mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-10 23:17:27 +00:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c92e78a9f8 | ||
|
|
d243b904cc | ||
|
|
374f8fb5fb | ||
|
|
dadbff5714 | ||
|
|
76ddae006f | ||
|
|
cfe157ec56 | ||
|
|
413115858c | ||
|
|
88046190ee | ||
|
|
72aa85a759 | ||
|
|
bfceebb7fb | ||
|
|
bc44fad352 | ||
|
|
4fca4dc60c | ||
|
|
036032373b | ||
|
|
89dfb43f3b | ||
|
|
c49aff4b6f | ||
|
|
56e60223c3 | ||
|
|
89b1f5aa1b | ||
|
|
b901598233 | ||
|
|
8cdc6a2885 | ||
|
|
a67e35aff9 | ||
|
|
f124e41ae6 | ||
|
|
4c954181cd | ||
|
|
7f7547737e | ||
|
|
a79d61ea85 | ||
|
|
d465b39c3e | ||
|
|
c5a609dc20 | ||
|
|
5634dc3d0d | ||
|
|
37e37b8cad | ||
|
|
8fd4534fbe | ||
|
|
d5427da52f |
6
.github/labeler.yml
vendored
6
.github/labeler.yml
vendored
@@ -15,9 +15,7 @@ c#:
|
|||||||
swift:
|
swift:
|
||||||
- '**/*.swift'
|
- '**/*.swift'
|
||||||
- swift/**/*
|
- swift/**/*
|
||||||
- tests/FlatBuffers.GRPC.Swift/**/*
|
- tests/swift/**
|
||||||
- tests/FlatBuffers.Benchmarks.swift/**/*
|
|
||||||
- tests/FlatBuffers.Test.Swift/**/*
|
|
||||||
- src/idl_gen_swift.cpp
|
- src/idl_gen_swift.cpp
|
||||||
|
|
||||||
javascript:
|
javascript:
|
||||||
@@ -86,9 +84,7 @@ documentation:
|
|||||||
|
|
||||||
CI:
|
CI:
|
||||||
- '.github/**/*'
|
- '.github/**/*'
|
||||||
- '.travis/**/*'
|
|
||||||
- '.bazelci/**/*'
|
- '.bazelci/**/*'
|
||||||
- .travis.yml
|
|
||||||
|
|
||||||
grpc:
|
grpc:
|
||||||
- grpc/**/*
|
- grpc/**/*
|
||||||
|
|||||||
18
.github/workflows/build.yml
vendored
18
.github/workflows/build.yml
vendored
@@ -82,10 +82,14 @@ jobs:
|
|||||||
CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles"
|
CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles"
|
||||||
-DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON
|
-DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON
|
||||||
-DFLATBUFFERS_CPP_STD=${{ matrix.std }}
|
-DFLATBUFFERS_CPP_STD=${{ matrix.std }}
|
||||||
|
-DFLATBUFFERS_BUILD_CPP17=${{ matrix.std >= 17 && 'On' || 'Off'}}
|
||||||
- name: build
|
- name: build
|
||||||
run: make -j
|
run: make -j
|
||||||
- name: test
|
- name: test
|
||||||
run: ./flattests
|
run: ./flattests
|
||||||
|
- name: test C++17
|
||||||
|
if: matrix.std >= 17
|
||||||
|
run: ./flattests_cpp17
|
||||||
|
|
||||||
build-windows-cpp-std:
|
build-windows-cpp-std:
|
||||||
name: Build Windows C++
|
name: Build Windows C++
|
||||||
@@ -103,10 +107,14 @@ jobs:
|
|||||||
cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release
|
cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release
|
||||||
-DFLATBUFFERS_STRICT_MODE=ON
|
-DFLATBUFFERS_STRICT_MODE=ON
|
||||||
-DFLATBUFFERS_CPP_STD=${{ matrix.std }}
|
-DFLATBUFFERS_CPP_STD=${{ matrix.std }}
|
||||||
|
-DFLATBUFFERS_BUILD_CPP17=${{ matrix.std >= 17 && 'On' || 'Off'}}
|
||||||
- name: build
|
- name: build
|
||||||
run: msbuild.exe FlatBuffers.sln /p:Configuration=Release /p:Platform=x64
|
run: msbuild.exe FlatBuffers.sln /p:Configuration=Release /p:Platform=x64
|
||||||
- name: test
|
- name: test
|
||||||
run: Release\flattests.exe
|
run: Release\flattests.exe
|
||||||
|
- name: test C++17
|
||||||
|
if: matrix.std >= 17
|
||||||
|
run: Release\flattests_cpp17.exe
|
||||||
|
|
||||||
build-windows:
|
build-windows:
|
||||||
permissions:
|
permissions:
|
||||||
@@ -350,8 +358,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: test
|
- name: test
|
||||||
working-directory: tests
|
working-directory: java
|
||||||
run: bash JavaTest.sh
|
run: mvn test
|
||||||
|
|
||||||
build-kotlin-macos:
|
build-kotlin-macos:
|
||||||
name: Build Kotlin MacOS
|
name: Build Kotlin MacOS
|
||||||
@@ -422,7 +430,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: test
|
- name: test
|
||||||
working-directory: tests/FlatBuffers.Test.Swift
|
working-directory: tests/swift/tests
|
||||||
run: sh SwiftTest.sh
|
run: sh SwiftTest.sh
|
||||||
|
|
||||||
build-swift-wasm:
|
build-swift-wasm:
|
||||||
@@ -435,7 +443,7 @@ jobs:
|
|||||||
- name: Setup Wasmer
|
- name: Setup Wasmer
|
||||||
uses: wasmerio/setup-wasmer@v1
|
uses: wasmerio/setup-wasmer@v1
|
||||||
- name: Test
|
- name: Test
|
||||||
working-directory: tests/FlatBuffers.Test.Swift.Wasm
|
working-directory: tests/swift/Wasm.tests
|
||||||
run: carton test
|
run: carton test
|
||||||
|
|
||||||
build-ts:
|
build-ts:
|
||||||
@@ -451,7 +459,7 @@ jobs:
|
|||||||
- name: compile
|
- name: compile
|
||||||
run: yarn compile
|
run: yarn compile
|
||||||
- name: test
|
- name: test
|
||||||
working-directory: tests
|
working-directory: tests/ts
|
||||||
run: python3 TypeScriptTest.py
|
run: python3 TypeScriptTest.py
|
||||||
|
|
||||||
build-dart:
|
build-dart:
|
||||||
|
|||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -78,7 +78,7 @@ tests/php/
|
|||||||
CMakeLists.txt.user
|
CMakeLists.txt.user
|
||||||
CMakeScripts/**
|
CMakeScripts/**
|
||||||
CTestTestfile.cmake
|
CTestTestfile.cmake
|
||||||
FlatBuffersConfigVersion.cmake
|
flatbuffers-config-version.cmake
|
||||||
FlatBuffers.cbp
|
FlatBuffers.cbp
|
||||||
build/Xcode/FlatBuffers.xcodeproj/project.xcworkspace/**
|
build/Xcode/FlatBuffers.xcodeproj/project.xcworkspace/**
|
||||||
build/Xcode/FlatBuffers.xcodeproj/xcuserdata/**
|
build/Xcode/FlatBuffers.xcodeproj/xcuserdata/**
|
||||||
@@ -88,6 +88,7 @@ java/*.iml
|
|||||||
.idea
|
.idea
|
||||||
*.iml
|
*.iml
|
||||||
target
|
target
|
||||||
|
java/target
|
||||||
**/*.pyc
|
**/*.pyc
|
||||||
build/VS2010/FlatBuffers.sdf
|
build/VS2010/FlatBuffers.sdf
|
||||||
build/VS2010/FlatBuffers.opensdf
|
build/VS2010/FlatBuffers.opensdf
|
||||||
@@ -148,4 +149,4 @@ flatbuffers.pc
|
|||||||
**/html/**
|
**/html/**
|
||||||
**/latex/**
|
**/latex/**
|
||||||
# https://cmake.org/cmake/help/latest/module/FetchContent.html#variable:FETCHCONTENT_BASE_DIR
|
# https://cmake.org/cmake/help/latest/module/FetchContent.html#variable:FETCHCONTENT_BASE_DIR
|
||||||
_deps/
|
_deps/
|
||||||
|
|||||||
215
.travis.yml
215
.travis.yml
@@ -1,215 +0,0 @@
|
|||||||
env:
|
|
||||||
global:
|
|
||||||
# Set at the root level as this is ignored when set under matrix.env.
|
|
||||||
- GCC_VERSION="4.9"
|
|
||||||
# Fail on first error if UBSAN or ASAN enabled for a target
|
|
||||||
- UBSAN_OPTIONS=halt_on_error=1
|
|
||||||
- ASAN_OPTIONS=halt_on_error=1
|
|
||||||
# Travis machines have 2 cores
|
|
||||||
- JOBS=2
|
|
||||||
- MAKEFLAGS="-j 2"
|
|
||||||
|
|
||||||
conan-linux: &conan-linux
|
|
||||||
os: linux
|
|
||||||
dist: xenial
|
|
||||||
language: python
|
|
||||||
python: "3.7"
|
|
||||||
services:
|
|
||||||
- docker
|
|
||||||
install:
|
|
||||||
- ./conan/travis/install.sh
|
|
||||||
script:
|
|
||||||
- ./conan/travis/build.sh
|
|
||||||
if: tag IS present
|
|
||||||
|
|
||||||
conan-linux-master: &conan-linux-master
|
|
||||||
os: linux
|
|
||||||
dist: xenial
|
|
||||||
language: python
|
|
||||||
python: "3.7"
|
|
||||||
services:
|
|
||||||
- docker
|
|
||||||
install:
|
|
||||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./conan/travis/install.sh; fi'
|
|
||||||
script:
|
|
||||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./conan/travis/build.sh; fi'
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
|
|
||||||
conan-osx: &conan-osx
|
|
||||||
os: osx
|
|
||||||
language: generic
|
|
||||||
install:
|
|
||||||
- ./conan/travis/install.sh
|
|
||||||
script:
|
|
||||||
- ./conan/travis/build.sh
|
|
||||||
if: tag IS present
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
#- language: python
|
|
||||||
# python: "2.7"
|
|
||||||
# install:
|
|
||||||
# - "pip install wheel twine"
|
|
||||||
# script:
|
|
||||||
# - "cd python/"
|
|
||||||
# - 'VERSION="$TRAVIS_TAG" python setup.py sdist bdist_wheel'
|
|
||||||
# - "cd ../"
|
|
||||||
# deploy:
|
|
||||||
# # Checkpointed release builds.
|
|
||||||
# - provider: script
|
|
||||||
# script: .travis/deploy-python.sh
|
|
||||||
# skip_cleanup: true
|
|
||||||
# on:
|
|
||||||
# tags: true
|
|
||||||
# # all_branches must be set with tags: true. See below post:
|
|
||||||
# # https://stackoverflow.com/a/27775257/1076585
|
|
||||||
# all_branches: true
|
|
||||||
# # Produce a new build for the cutting edge when master changes.
|
|
||||||
# - provider: script
|
|
||||||
# script: .travis/deploy-python.sh
|
|
||||||
# skip_cleanup: true
|
|
||||||
# on:
|
|
||||||
# branch: master
|
|
||||||
- language: cpp
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- docker-ce
|
|
||||||
script:
|
|
||||||
- bash .travis/build-and-run-docker-test-containers.sh
|
|
||||||
|
|
||||||
- language: cpp
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
|
|
||||||
compiler:
|
|
||||||
- gcc
|
|
||||||
|
|
||||||
env:
|
|
||||||
matrix:
|
|
||||||
- BUILD_TYPE=Debug
|
|
||||||
- BUILD_TYPE=Release
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq g++-$GCC_VERSION; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq gcc-$GCC_VERSION; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which g++-$GCC_VERSION) /usr/bin/g++; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi
|
|
||||||
|
|
||||||
script:
|
|
||||||
- pip install cmake
|
|
||||||
- bash .travis/check-sources.sh
|
|
||||||
- bash grpc/build_grpc.sh
|
|
||||||
- cmake .
|
|
||||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
|
||||||
-DFLATBUFFERS_BUILD_GRPCTEST=ON
|
|
||||||
-DGRPC_INSTALL_PATH=$TRAVIS_BUILD_DIR/google/grpc/install
|
|
||||||
-DPROTOBUF_DOWNLOAD_PATH=$TRAVIS_BUILD_DIR/google/grpc/third_party/protobuf
|
|
||||||
-DFLATBUFFERS_CODE_SANITIZE=ON
|
|
||||||
- cmake --build . --target all --clean-first -- -j${JOBS}
|
|
||||||
- LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ctest --extra-verbose --output-on-failure
|
|
||||||
|
|
||||||
- language: cpp
|
|
||||||
os: osx
|
|
||||||
osx_image: xcode9.3
|
|
||||||
env:
|
|
||||||
matrix:
|
|
||||||
- BUILD_TYPE=Debug
|
|
||||||
- BUILD_TYPE=Release
|
|
||||||
|
|
||||||
script:
|
|
||||||
- pip install --user cmake
|
|
||||||
- mkdir ~/cmake_path
|
|
||||||
- ln -s $(find ~/Library/Python -name cmake -type f | head -n 1) ~/cmake_path/cmake
|
|
||||||
- ln -s $(find ~/Library/Python -name ctest -type f | head -n 1) ~/cmake_path/ctest
|
|
||||||
- export PATH=~/cmake_path:${PATH}
|
|
||||||
- bash grpc/build_grpc.sh
|
|
||||||
- cmake .
|
|
||||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
|
||||||
-DFLATBUFFERS_BUILD_GRPCTEST=ON
|
|
||||||
-DGRPC_INSTALL_PATH=$TRAVIS_BUILD_DIR/google/grpc/install
|
|
||||||
-DPROTOBUF_DOWNLOAD_PATH=$TRAVIS_BUILD_DIR/google/grpc/third_party/protobuf
|
|
||||||
-DFLATBUFFERS_CODE_SANITIZE=ON
|
|
||||||
- cmake --build . -- -j${JOBS}
|
|
||||||
- DYLD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ctest --extra-verbose --output-on-failure
|
|
||||||
|
|
||||||
- <<: *conan-linux-master
|
|
||||||
env: CONAN_GCC_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/gcc8
|
|
||||||
- <<: *conan-linux
|
|
||||||
env: CONAN_GCC_VERSIONS=4.9 CONAN_DOCKER_IMAGE=conanio/gcc49
|
|
||||||
- <<: *conan-linux
|
|
||||||
env: CONAN_GCC_VERSIONS=5 CONAN_DOCKER_IMAGE=conanio/gcc5
|
|
||||||
- <<: *conan-linux
|
|
||||||
env: CONAN_GCC_VERSIONS=6 CONAN_DOCKER_IMAGE=conanio/gcc6
|
|
||||||
- <<: *conan-linux
|
|
||||||
env: CONAN_GCC_VERSIONS=7 CONAN_DOCKER_IMAGE=conanio/gcc7
|
|
||||||
- <<: *conan-linux
|
|
||||||
env: CONAN_GCC_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/gcc8
|
|
||||||
- <<: *conan-linux
|
|
||||||
env: CONAN_GCC_VERSIONS=9 CONAN_DOCKER_IMAGE=conanio/gcc9
|
|
||||||
- <<: *conan-linux
|
|
||||||
env: CONAN_CLANG_VERSIONS=3.9 CONAN_DOCKER_IMAGE=conanio/clang39
|
|
||||||
- <<: *conan-linux
|
|
||||||
env: CONAN_CLANG_VERSIONS=4.0 CONAN_DOCKER_IMAGE=conanio/clang40
|
|
||||||
- <<: *conan-linux
|
|
||||||
env: CONAN_CLANG_VERSIONS=5.0 CONAN_DOCKER_IMAGE=conanio/clang50
|
|
||||||
- <<: *conan-linux
|
|
||||||
env: CONAN_CLANG_VERSIONS=6.0 CONAN_DOCKER_IMAGE=conanio/clang60
|
|
||||||
- <<: *conan-linux
|
|
||||||
env: CONAN_CLANG_VERSIONS=7.0 CONAN_DOCKER_IMAGE=conanio/clang7
|
|
||||||
- <<: *conan-linux
|
|
||||||
env: CONAN_CLANG_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/clang8
|
|
||||||
- <<: *conan-osx
|
|
||||||
osx_image: xcode7.3
|
|
||||||
env: CONAN_APPLE_CLANG_VERSIONS=7.3
|
|
||||||
- <<: *conan-osx
|
|
||||||
osx_image: xcode8.3
|
|
||||||
env: CONAN_APPLE_CLANG_VERSIONS=8.1
|
|
||||||
- <<: *conan-osx
|
|
||||||
osx_image: xcode9
|
|
||||||
env: CONAN_APPLE_CLANG_VERSIONS=9.0
|
|
||||||
- <<: *conan-osx
|
|
||||||
osx_image: xcode9.4
|
|
||||||
env: CONAN_APPLE_CLANG_VERSIONS=9.1
|
|
||||||
- <<: *conan-osx
|
|
||||||
osx_image: xcode10.2
|
|
||||||
env: CONAN_APPLE_CLANG_VERSIONS=10.0
|
|
||||||
|
|
||||||
- language: android
|
|
||||||
sudo: true
|
|
||||||
dist: trusty
|
|
||||||
android:
|
|
||||||
components:
|
|
||||||
- tools
|
|
||||||
- platform-tools
|
|
||||||
- extra-android-m2repository
|
|
||||||
licenses:
|
|
||||||
- 'android-sdk-preview-license-52d11cd2'
|
|
||||||
- 'android-sdk-license-.+'
|
|
||||||
- 'google-gdk-license-.+'
|
|
||||||
compiler:
|
|
||||||
- gcc
|
|
||||||
before_install:
|
|
||||||
- echo y | sdkmanager "platforms;android-30"
|
|
||||||
- echo y | sdkmanager "build-tools;30.0.2"
|
|
||||||
- echo y | sdkmanager "ndk-bundle"
|
|
||||||
- echo y | sdkmanager "cmake;3.6.4111459"
|
|
||||||
script:
|
|
||||||
- cmake -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF .; make; export PATH="$PATH:${PWD}"
|
|
||||||
- cd android; ./gradlew clean build
|
|
||||||
|
|
||||||
- language: generic
|
|
||||||
if: type IN (pull_request)
|
|
||||||
os: linux
|
|
||||||
install:
|
|
||||||
- bash .travis/format_install.sh
|
|
||||||
|
|
||||||
script:
|
|
||||||
- bash .travis/format_check.sh
|
|
||||||
54
CHANGELOG.md
54
CHANGELOG.md
@@ -4,33 +4,59 @@ 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
|
new features that should be highlighted. Minor fixes or improvements are not
|
||||||
necessarily listed.
|
necessarily listed.
|
||||||
|
|
||||||
|
## 22.9.29 (Sept 29 2022)
|
||||||
|
|
||||||
|
* Rust soundness fixes to avoid the crate from bing labelled unsafe (#7518).
|
||||||
|
|
||||||
|
## 22.9.24 (Sept 24 2022)
|
||||||
|
|
||||||
|
* 20 Major releases in a row? Nope, we switched to a new
|
||||||
|
[versioning scheme](https://github.com/google/flatbuffers/wiki/Versioning)
|
||||||
|
that is based on date.
|
||||||
|
|
||||||
|
* Python supports fixed size arrays now (#7529).
|
||||||
|
|
||||||
|
* Behavior change in how C++ object API uses `UnPackTo`. The original intent of
|
||||||
|
this was to reduce allocations by reusing an existing object to pack data
|
||||||
|
into. At some point, this logic started to merge the states of the two objects
|
||||||
|
instead of clearing the state of the packee. This change goes back to the
|
||||||
|
original intention, the packed object is cleared when getting data packed into
|
||||||
|
it (#7527).
|
||||||
|
|
||||||
|
* Fixed a bug in C++ alignment that was using `sizeof()` instead of the intended
|
||||||
|
`AlignOf()` for structs (#7520).
|
||||||
|
|
||||||
|
* C# has an
|
||||||
|
[offical Nuget package](https://www.nuget.org/packages/Google.FlatBuffers) now
|
||||||
|
(#7496).
|
||||||
|
|
||||||
## 2.0.8 (Aug 29 2022)
|
## 2.0.8 (Aug 29 2022)
|
||||||
|
|
||||||
* Fix for `--keep-prefix` the was generating the wrong include statements for
|
* Fix for `--keep-prefix` the was generating the wrong include statements for
|
||||||
C++ (#7469). The bug was introduced in 2.0.7.
|
C++ (#7469). The bug was introduced in 2.0.7.
|
||||||
|
|
||||||
* Added the `Verifier::Options` option struct to allow specifying runtime
|
* Added the `Verifier::Options` option struct to allow specifying runtime
|
||||||
configuration settings for the verifier (#7489). This allows to skip verifying
|
configuration settings for the verifier (#7489). This allows to skip verifying
|
||||||
nested flatbuffers, a on-by-default change that was introduced in 2.0.7. This
|
nested flatbuffers, a on-by-default change that was introduced in 2.0.7. This
|
||||||
deprecates the existing `Verifier` constructor, which may be removed in a future
|
deprecates the existing `Verifier` constructor, which may be removed in a
|
||||||
version.
|
future version.
|
||||||
|
|
||||||
* Refactor of `tests/test.cpp` that lead to ~10% speedup in compilation of the
|
* Refactor of `tests/test.cpp` that lead to ~10% speedup in compilation of the
|
||||||
entire project (#7487).
|
entire project (#7487).
|
||||||
|
|
||||||
## 2.0.7 (Aug 22 2022)
|
## 2.0.7 (Aug 22 2022)
|
||||||
|
|
||||||
* This is the first version with an explicit change log, so all the previous
|
* This is the first version with an explicit change log, so all the previous
|
||||||
features will not be listed.
|
features will not be listed.
|
||||||
|
|
||||||
* Verifier now checks that buffers are at least the minimum size required to be
|
* Verifier now checks that buffers are at least the minimum size required to be
|
||||||
a flatbuffers (12 bytes). This includes nested flatbuffers, which previously
|
a flatbuffers (12 bytes). This includes nested flatbuffers, which previously
|
||||||
could be declared valid at size 0.
|
could be declared valid at size 0.
|
||||||
|
|
||||||
* Annotated binaries. Given a flatbuffer binary and a schema (or binary schema)
|
* Annotated binaries. Given a flatbuffer binary and a schema (or binary schema)
|
||||||
one can generate an annotated flatbuffer (.afb) to describe each byte in the
|
one can generate an annotated flatbuffer (.afb) to describe each byte in the
|
||||||
binary with schema metadata and value.
|
binary with schema metadata and value.
|
||||||
|
|
||||||
* First binary schema generator (Lua) to generate Lua code via a .bfbs file.
|
* First binary schema generator (Lua) to generate Lua code via a .bfbs file.
|
||||||
This is mostly an implementation detail of flatc internals, but will be slowly
|
This is mostly an implementation detail of flatc internals, but will be slowly
|
||||||
applied to the other language generators.
|
applied to the other language generators.
|
||||||
@@ -654,9 +654,9 @@ if(FLATBUFFERS_INSTALL)
|
|||||||
|
|
||||||
set(FB_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/flatbuffers")
|
set(FB_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/flatbuffers")
|
||||||
|
|
||||||
configure_file(CMake/FlatBuffersConfigVersion.cmake.in FlatBuffersConfigVersion.cmake @ONLY)
|
configure_file(CMake/flatbuffers-config-version.cmake.in flatbuffers-config-version.cmake @ONLY)
|
||||||
install(
|
install(
|
||||||
FILES "CMake/FlatBuffersConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/FlatBuffersConfigVersion.cmake"
|
FILES "CMake/flatbuffers-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-config-version.cmake"
|
||||||
DESTINATION ${FB_CMAKE_DIR}
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
set(VERSION_MAJOR 2)
|
set(VERSION_MAJOR 22)
|
||||||
set(VERSION_MINOR 0)
|
set(VERSION_MINOR 9)
|
||||||
set(VERSION_PATCH 8)
|
set(VERSION_PATCH 29)
|
||||||
set(VERSION_COMMIT 0)
|
set(VERSION_COMMIT 0)
|
||||||
|
|
||||||
find_program(GIT git)
|
find_program(GIT git)
|
||||||
|
|||||||
@@ -230,6 +230,8 @@ set(FlatBuffers_Tests_SRCS
|
|||||||
tests/util_test.cpp
|
tests/util_test.cpp
|
||||||
tests/native_type_test_impl.h
|
tests/native_type_test_impl.h
|
||||||
tests/native_type_test_impl.cpp
|
tests/native_type_test_impl.cpp
|
||||||
|
tests/alignment_test.h
|
||||||
|
tests/alignment_test.cpp
|
||||||
include/flatbuffers/code_generators.h
|
include/flatbuffers/code_generators.h
|
||||||
src/code_generators.cpp
|
src/code_generators.cpp
|
||||||
# file generate by running compiler on tests/monster_test.fbs
|
# file generate by running compiler on tests/monster_test.fbs
|
||||||
@@ -251,6 +253,8 @@ set(FlatBuffers_Tests_SRCS
|
|||||||
${CMAKE_CURRENT_BINARY_DIR}/tests/optional_scalars_generated.h
|
${CMAKE_CURRENT_BINARY_DIR}/tests/optional_scalars_generated.h
|
||||||
# file generate by running compiler on tests/native_inline_table_test.fbs
|
# file generate by running compiler on tests/native_inline_table_test.fbs
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/tests/native_inline_table_test_generated.h
|
${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
|
||||||
)
|
)
|
||||||
|
|
||||||
set(FlatBuffers_Tests_CPP17_SRCS
|
set(FlatBuffers_Tests_CPP17_SRCS
|
||||||
@@ -623,6 +627,7 @@ if(FLATBUFFERS_BUILD_TESTS)
|
|||||||
compile_flatbuffers_schema_to_binary(tests/arrays_test.fbs)
|
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_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/native_inline_table_test.fbs "--gen-compare")
|
||||||
|
compile_flatbuffers_schema_to_cpp(tests/alignment_test.fbs "--gen-compare")
|
||||||
if(NOT (MSVC AND (MSVC_VERSION LESS 1900)))
|
if(NOT (MSVC AND (MSVC_VERSION LESS 1900)))
|
||||||
compile_flatbuffers_schema_to_cpp(tests/monster_extra.fbs) # Test floating-point NAN/INF.
|
compile_flatbuffers_schema_to_cpp(tests/monster_extra.fbs) # Test floating-point NAN/INF.
|
||||||
endif()
|
endif()
|
||||||
@@ -699,9 +704,12 @@ if(FLATBUFFERS_INSTALL)
|
|||||||
|
|
||||||
set(FB_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/flatbuffers")
|
set(FB_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/flatbuffers")
|
||||||
|
|
||||||
configure_file(CMake/FlatBuffersConfigVersion.cmake.in FlatBuffersConfigVersion.cmake @ONLY)
|
configure_file(CMake/flatbuffers-config-version.cmake.in flatbuffers-config-version.cmake @ONLY)
|
||||||
install(
|
install(
|
||||||
FILES "CMake/FlatBuffersConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/FlatBuffersConfigVersion.cmake"
|
FILES
|
||||||
|
"CMake/flatbuffers-config.cmake"
|
||||||
|
"CMake/BuildFlatBuffers.cmake"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-config-version.cmake"
|
||||||
DESTINATION ${FB_CMAKE_DIR}
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = 'FlatBuffers'
|
s.name = 'FlatBuffers'
|
||||||
s.version = '2.0.0'
|
s.version = '22.9.29'
|
||||||
s.summary = 'FlatBuffers: Memory Efficient Serialization Library'
|
s.summary = 'FlatBuffers: Memory Efficient Serialization Library'
|
||||||
|
|
||||||
s.description = "FlatBuffers is a cross platform serialization library architected for
|
s.description = "FlatBuffers is a cross platform serialization library architected for
|
||||||
@@ -11,11 +11,11 @@ Pod::Spec.new do |s|
|
|||||||
s.homepage = 'https://github.com/google/flatbuffers'
|
s.homepage = 'https://github.com/google/flatbuffers'
|
||||||
s.license = { :type => 'Apache2.0', :file => 'LICENSE' }
|
s.license = { :type => 'Apache2.0', :file => 'LICENSE' }
|
||||||
s.author = { 'mustii' => 'mustii@mmk.one' }
|
s.author = { 'mustii' => 'mustii@mmk.one' }
|
||||||
s.source = { :git => 'https://github.com/mustiikhalil/flatbuffers.git', :tag => s.version.to_s, :submodules => true }
|
s.source = { :git => 'https://github.com/google/flatbuffers.git', :tag => s.version.to_s, :submodules => true }
|
||||||
|
|
||||||
s.ios.deployment_target = '11.0'
|
s.ios.deployment_target = '11.0'
|
||||||
s.osx.deployment_target = '10.14'
|
s.osx.deployment_target = '10.14'
|
||||||
|
|
||||||
s.swift_version = '5.0'
|
s.swift_version = '5.0'
|
||||||
s.source_files = 'Sources/**/*'
|
s.source_files = 'swift/Sources/Flatbuffers/*.swift'
|
||||||
end
|
end
|
||||||
@@ -32,5 +32,6 @@ let package = Package(
|
|||||||
.target(
|
.target(
|
||||||
name: "FlatBuffers",
|
name: "FlatBuffers",
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
|
path: "swift/Sources",
|
||||||
exclude: ["Documentation.docc/Resources/code/swift"]),
|
exclude: ["Documentation.docc/Resources/code/swift"]),
|
||||||
])
|
])
|
||||||
@@ -31,6 +31,7 @@ let package = Package(
|
|||||||
targets: [
|
targets: [
|
||||||
.target(
|
.target(
|
||||||
name: "FlatBuffers",
|
name: "FlatBuffers",
|
||||||
dependencies: []),
|
dependencies: [],
|
||||||
|
path: "swift/Sources")
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -56,10 +56,13 @@ http_archive(
|
|||||||
)
|
)
|
||||||
|
|
||||||
##### GRPC
|
##### GRPC
|
||||||
_GRPC_VERSION = "1.48.0" # https://github.com/grpc/grpc/releases/tag/v1.48.0
|
_GRPC_VERSION = "1.49.0" # https://github.com/grpc/grpc/releases/tag/v1.48.0
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "com_github_grpc_grpc",
|
name = "com_github_grpc_grpc",
|
||||||
|
patch_args = ["-p1"],
|
||||||
|
patches = ["//grpc:build_grpc_with_cxx14.patch"],
|
||||||
|
sha256 = "15715e1847cc9e42014f02c727dbcb48e39dbdb90f79ad3d66fe4361709ff935",
|
||||||
strip_prefix = "grpc-" + _GRPC_VERSION,
|
strip_prefix = "grpc-" + _GRPC_VERSION,
|
||||||
urls = ["https://github.com/grpc/grpc/archive/refs/tags/v" + _GRPC_VERSION + ".tar.gz"],
|
urls = ["https://github.com/grpc/grpc/archive/refs/tags/v" + _GRPC_VERSION + ".tar.gz"],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
<uses-feature android:glEsVersion="0x00020000"></uses-feature>
|
<uses-feature android:glEsVersion="0x00020000"></uses-feature>
|
||||||
|
|
||||||
<!-- This .apk has no Java code itself, so set hasCode to false. -->
|
<!-- This .apk has no Java code itself, so set hasCode to false. -->
|
||||||
<application android:label="@string/app_name"
|
<application android:name="android.support.multidex.MultiDexApplication"
|
||||||
|
android:label="@string/app_name"
|
||||||
android:hasCode="false"
|
android:hasCode="false"
|
||||||
android:allowBackup="false">
|
android:allowBackup="false">
|
||||||
<!-- Our activity is the built-in NativeActivity framework class.
|
<!-- Our activity is the built-in NativeActivity framework class.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.flatbuffers.app"
|
applicationId "com.flatbuffers.app"
|
||||||
minSdkVersion 16
|
minSdkVersion 26
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
@@ -18,6 +18,14 @@ android {
|
|||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
java {
|
||||||
|
srcDir '../../java/src/main/java/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters 'arm64-v8a', 'armeabi-v7a'
|
abiFilters 'arm64-v8a', 'armeabi-v7a'
|
||||||
}
|
}
|
||||||
@@ -105,30 +113,6 @@ android {
|
|||||||
dependsOn(generateFbsCpp)
|
dependsOn(generateFbsCpp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// flavorDimensions "stl-variant"
|
|
||||||
// productFlavors {
|
|
||||||
// gnustl {
|
|
||||||
// dimension "stl-variant"
|
|
||||||
// applicationIdSuffix ".gnustl"
|
|
||||||
// versionNameSuffix "-gnustl"
|
|
||||||
// externalNativeBuild {
|
|
||||||
// ndkBuild {
|
|
||||||
// arguments "APP_STL=gnustl_static"
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// libcpp {
|
|
||||||
// dimension "stl-variant"
|
|
||||||
// applicationIdSuffix ".libcpp"
|
|
||||||
// versionNameSuffix "-libcpp"
|
|
||||||
// externalNativeBuild {
|
|
||||||
// ndkBuild {
|
|
||||||
// arguments "APP_STL=c++_static"
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -136,6 +120,8 @@ dependencies {
|
|||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||||
implementation 'androidx.core:core-ktx:1.3.2'
|
implementation 'androidx.core:core-ktx:1.3.2'
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
implementation 'com.google.flatbuffers:flatbuffers-java:2.0.0'
|
|
||||||
|
// If you using java runtime you can add its dependency as the example below
|
||||||
|
// implementation 'com.google.flatbuffers:flatbuffers-java:$latest_version'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,13 @@
|
|||||||
|
|
||||||
#include "flatbuffers/flatbuffers.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 == 2 &&
|
||||||
|
FLATBUFFERS_VERSION_MINOR == 0 &&
|
||||||
|
FLATBUFFERS_VERSION_REVISION == 8,
|
||||||
|
"Non-compatible flatbuffers version included");
|
||||||
|
|
||||||
namespace com {
|
namespace com {
|
||||||
namespace fbs {
|
namespace fbs {
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class Animal : Table() {
|
|||||||
return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
|
return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
|
||||||
}
|
}
|
||||||
companion object {
|
companion object {
|
||||||
fun validateVersion() = Constants.FLATBUFFERS_2_0_0()
|
fun validateVersion() = Constants.FLATBUFFERS_22_9_29()
|
||||||
fun getRootAsAnimal(_bb: ByteBuffer): Animal = getRootAsAnimal(_bb, Animal())
|
fun getRootAsAnimal(_bb: ByteBuffer): Animal = getRootAsAnimal(_bb, Animal())
|
||||||
fun getRootAsAnimal(_bb: ByteBuffer, obj: Animal): Animal {
|
fun getRootAsAnimal(_bb: ByteBuffer, obj: Animal): Animal {
|
||||||
_bb.order(ByteOrder.LITTLE_ENDIAN)
|
_bb.order(ByteOrder.LITTLE_ENDIAN)
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import os
|
|
||||||
|
|
||||||
if os.getenv("APPVEYOR_REPO_TAG") != "true":
|
|
||||||
print("Skip build step. It's not TAG")
|
|
||||||
else:
|
|
||||||
os.system("python conan/build.py")
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
import os
|
|
||||||
|
|
||||||
if os.getenv("APPVEYOR_REPO_TAG") != "true":
|
|
||||||
print("Skip step. It's not TAG")
|
|
||||||
else:
|
|
||||||
os.system("pip install conan conan-package-tools")
|
|
||||||
@@ -21,14 +21,6 @@ def get_branch():
|
|||||||
|
|
||||||
def get_version():
|
def get_version():
|
||||||
version = get_branch()
|
version = get_branch()
|
||||||
if os.getenv("TRAVIS", False):
|
|
||||||
version = os.getenv("TRAVIS_BRANCH")
|
|
||||||
|
|
||||||
if os.getenv("APPVEYOR", False):
|
|
||||||
version = os.getenv("APPVEYOR_REPO_BRANCH")
|
|
||||||
if os.getenv("APPVEYOR_REPO_TAG") == "true":
|
|
||||||
version = os.getenv("APPVEYOR_REPO_TAG_NAME")
|
|
||||||
|
|
||||||
match = re.search(r"v(\d+\.\d+\.\d+.*)", version)
|
match = re.search(r"v(\d+\.\d+\.\d+.*)", version)
|
||||||
if match:
|
if match:
|
||||||
return match.group(1)
|
return match.group(1)
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
if [[ "$(uname -s)" == 'Darwin' ]]; then
|
|
||||||
if which pyenv > /dev/null; then
|
|
||||||
eval "$(pyenv init -)"
|
|
||||||
fi
|
|
||||||
pyenv activate conan
|
|
||||||
fi
|
|
||||||
|
|
||||||
conan user
|
|
||||||
python conan/build.py
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
if [[ "$(uname -s)" == 'Darwin' ]]; then
|
|
||||||
brew update || brew update
|
|
||||||
brew outdated pyenv || brew upgrade pyenv
|
|
||||||
brew install pyenv-virtualenv
|
|
||||||
brew install cmake || true
|
|
||||||
|
|
||||||
if which pyenv > /dev/null; then
|
|
||||||
eval "$(pyenv init -)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
pyenv install 2.7.10
|
|
||||||
pyenv virtualenv 2.7.10 conan
|
|
||||||
pyenv rehash
|
|
||||||
pyenv activate conan
|
|
||||||
fi
|
|
||||||
|
|
||||||
pip install -U conan_package_tools conan
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
name: flat_buffers
|
name: flat_buffers
|
||||||
version: 2.0.8
|
version: 22.9.29
|
||||||
description: FlatBuffers reading and writing library for Dart. Based on original work by Konstantin Scheglov and Paul Berry of the Dart SDK team.
|
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
|
homepage: https://github.com/google/flatbuffers
|
||||||
documentation: https://google.github.io/flatbuffers/index.html
|
documentation: https://google.github.io/flatbuffers/index.html
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ GitHub page](https://github.com/google/flatbuffers/tree/master/swift).
|
|||||||
|
|
||||||
## Testing the FlatBuffers Swift library
|
## Testing the FlatBuffers Swift library
|
||||||
|
|
||||||
The code to test the Swift library can be found at `flatbuffers/Flatbuffers.Test.Swift`.
|
The code to test the Swift library can be found at `flatbuffers/tests/swift/tests`.
|
||||||
The test code itself is located in [Flatbuffers.Test.Swift](https://github.com/google/flatbuffers/blob/master/tests/FlatBuffers.Test.Swift).
|
The test code itself is located in [flatbuffers/tests/swift/tests](https://github.com/google/flatbuffers/blob/master/tests/swift/tests).
|
||||||
|
|
||||||
To run the tests, use the [SwiftTest.sh](https://github.com/google/flatbuffers/blob/master/tests/FlatBuffers.Test.Swift/SwiftTest.sh) shell script.
|
To run the tests, use the [SwiftTest.sh](https://github.com/google/flatbuffers/blob/master/tests/swift/tests/SwiftTest.sh) shell script.
|
||||||
|
|
||||||
*Note: The shell script requires [Swift](https://swift.org) to
|
*Note: The shell script requires [Swift](https://swift.org) to
|
||||||
be installed.*
|
be installed.*
|
||||||
|
|||||||
10
grpc/build_grpc_with_cxx14.patch
Normal file
10
grpc/build_grpc_with_cxx14.patch
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
diff --git a/bazel/copts.bzl b/bazel/copts.bzl
|
||||||
|
index 10be944f25..879518b92f 100644
|
||||||
|
--- a/bazel/copts.bzl
|
||||||
|
+++ b/bazel/copts.bzl
|
||||||
|
@@ -59,4 +59,4 @@ GRPC_LLVM_WARNING_FLAGS = [
|
||||||
|
GRPC_DEFAULT_COPTS = select({
|
||||||
|
"//:use_strict_warning": GRPC_LLVM_WARNING_FLAGS + ["-DUSE_STRICT_WARNING=1"],
|
||||||
|
"//conditions:default": [],
|
||||||
|
-})
|
||||||
|
+}) + ["-std=c++14"]
|
||||||
@@ -6,7 +6,7 @@ import FlatBuffers
|
|||||||
|
|
||||||
public struct models_HelloReply: FlatBufferObject, Verifiable {
|
public struct models_HelloReply: FlatBufferObject, Verifiable {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_2_0_8() }
|
static func validateVersion() { FlatBuffersVersion_22_9_29() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
private var _accessor: Table
|
private var _accessor: Table
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ extension models_HelloReply: Encodable {
|
|||||||
|
|
||||||
public struct models_HelloRequest: FlatBufferObject, Verifiable {
|
public struct models_HelloRequest: FlatBufferObject, Verifiable {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_2_0_8() }
|
static func validateVersion() { FlatBuffersVersion_22_9_29() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
private var _accessor: Table
|
private var _accessor: Table
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// automatically generated by the FlatBuffers compiler, do not modify
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
export { HelloReply } from './models/hello-reply';
|
export { HelloReply } from './models/hello-reply.js';
|
||||||
export { HelloRequest } from './models/hello-request';
|
export { HelloRequest } from './models/hello-request.js';
|
||||||
|
|||||||
@@ -138,9 +138,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
|
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
|
||||||
|
|
||||||
#define FLATBUFFERS_VERSION_MAJOR 2
|
#define FLATBUFFERS_VERSION_MAJOR 22
|
||||||
#define FLATBUFFERS_VERSION_MINOR 0
|
#define FLATBUFFERS_VERSION_MINOR 9
|
||||||
#define FLATBUFFERS_VERSION_REVISION 8
|
#define FLATBUFFERS_VERSION_REVISION 29
|
||||||
#define FLATBUFFERS_STRING_EXPAND(X) #X
|
#define FLATBUFFERS_STRING_EXPAND(X) #X
|
||||||
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
|
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|||||||
@@ -449,7 +449,7 @@ class FlatBufferBuilder {
|
|||||||
}
|
}
|
||||||
template<typename T> void PreAlign(size_t len) {
|
template<typename T> void PreAlign(size_t len) {
|
||||||
AssertScalarT<T>();
|
AssertScalarT<T>();
|
||||||
PreAlign(len, sizeof(T));
|
PreAlign(len, AlignOf<T>());
|
||||||
}
|
}
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
@@ -589,11 +589,15 @@ class FlatBufferBuilder {
|
|||||||
return PushElement(static_cast<uoffset_t>(len));
|
return PushElement(static_cast<uoffset_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartVector(size_t len, size_t elemsize) {
|
void StartVector(size_t len, size_t elemsize, size_t alignment) {
|
||||||
NotNested();
|
NotNested();
|
||||||
nested = true;
|
nested = true;
|
||||||
PreAlign<uoffset_t>(len * elemsize);
|
PreAlign<uoffset_t>(len * elemsize);
|
||||||
PreAlign(len * elemsize, elemsize); // Just in case elemsize > uoffset_t.
|
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>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call this right before StartVector/CreateVector if you want to force the
|
// Call this right before StartVector/CreateVector if you want to force the
|
||||||
@@ -627,7 +631,7 @@ class FlatBufferBuilder {
|
|||||||
// If this assert hits, you're specifying a template argument that is
|
// If this assert hits, you're specifying a template argument that is
|
||||||
// causing the wrong overload to be selected, remove it.
|
// causing the wrong overload to be selected, remove it.
|
||||||
AssertScalarT<T>();
|
AssertScalarT<T>();
|
||||||
StartVector(len, sizeof(T));
|
StartVector<T>(len);
|
||||||
if (len == 0) { return Offset<Vector<T>>(EndVector(len)); }
|
if (len == 0) { return Offset<Vector<T>>(EndVector(len)); }
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#if FLATBUFFERS_LITTLEENDIAN
|
#if FLATBUFFERS_LITTLEENDIAN
|
||||||
@@ -668,7 +672,7 @@ class FlatBufferBuilder {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) {
|
Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) {
|
||||||
StartVector(len, sizeof(Offset<T>));
|
StartVector<Offset<T>>(len);
|
||||||
for (auto i = len; i > 0;) { PushElement(v[--i]); }
|
for (auto i = len; i > 0;) { PushElement(v[--i]); }
|
||||||
return Offset<Vector<Offset<T>>>(EndVector(len));
|
return Offset<Vector<Offset<T>>>(EndVector(len));
|
||||||
}
|
}
|
||||||
@@ -688,7 +692,7 @@ class FlatBufferBuilder {
|
|||||||
// an array. Instead, read elements manually.
|
// an array. Instead, read elements manually.
|
||||||
// Background: https://isocpp.org/blog/2012/11/on-vectorbool
|
// Background: https://isocpp.org/blog/2012/11/on-vectorbool
|
||||||
Offset<Vector<uint8_t>> CreateVector(const std::vector<bool> &v) {
|
Offset<Vector<uint8_t>> CreateVector(const std::vector<bool> &v) {
|
||||||
StartVector(v.size(), sizeof(uint8_t));
|
StartVector<uint8_t>(v.size());
|
||||||
for (auto i = v.size(); i > 0;) {
|
for (auto i = v.size(); i > 0;) {
|
||||||
PushElement(static_cast<uint8_t>(v[--i]));
|
PushElement(static_cast<uint8_t>(v[--i]));
|
||||||
}
|
}
|
||||||
@@ -762,7 +766,7 @@ class FlatBufferBuilder {
|
|||||||
for (auto it = begin; it != end; ++it) {
|
for (auto it = begin; it != end; ++it) {
|
||||||
buf_.scratch_push_small(CreateString(*it));
|
buf_.scratch_push_small(CreateString(*it));
|
||||||
}
|
}
|
||||||
StartVector(size, sizeof(Offset<String>));
|
StartVector<Offset<String>>(size);
|
||||||
for (auto i = 1; i <= size; i++) {
|
for (auto i = 1; i <= size; i++) {
|
||||||
// Note we re-evaluate the buf location each iteration to account for any
|
// Note we re-evaluate the buf location each iteration to account for any
|
||||||
// underlying buffer resizing that may occur.
|
// underlying buffer resizing that may occur.
|
||||||
@@ -782,7 +786,7 @@ class FlatBufferBuilder {
|
|||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Offset<Vector<const T *>> CreateVectorOfStructs(const T *v, size_t len) {
|
Offset<Vector<const T *>> CreateVectorOfStructs(const T *v, size_t len) {
|
||||||
StartVector(len * sizeof(T) / AlignOf<T>(), AlignOf<T>());
|
StartVector(len * sizeof(T) / AlignOf<T>(), sizeof(T), AlignOf<T>());
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
|
PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
|
||||||
}
|
}
|
||||||
@@ -1025,9 +1029,9 @@ class FlatBufferBuilder {
|
|||||||
/// written to at a later time to serialize the data into a `vector`
|
/// written to at a later time to serialize the data into a `vector`
|
||||||
/// in the buffer.
|
/// in the buffer.
|
||||||
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
|
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
|
||||||
uint8_t **buf) {
|
size_t alignment, uint8_t **buf) {
|
||||||
NotNested();
|
NotNested();
|
||||||
StartVector(len, elemsize);
|
StartVector(len, elemsize, alignment);
|
||||||
buf_.make_space(len * elemsize);
|
buf_.make_space(len * elemsize);
|
||||||
auto vec_start = GetSize();
|
auto vec_start = GetSize();
|
||||||
auto vec_end = EndVector(len);
|
auto vec_end = EndVector(len);
|
||||||
@@ -1035,6 +1039,12 @@ class FlatBufferBuilder {
|
|||||||
return vec_end;
|
return vec_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]])
|
||||||
|
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
|
||||||
|
uint8_t **buf) {
|
||||||
|
return CreateUninitializedVector(len, elemsize, elemsize, buf);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Specialized version of `CreateVector` for non-copying use cases.
|
/// @brief Specialized version of `CreateVector` for non-copying use cases.
|
||||||
/// Write the data any time later to the returned buffer pointer `buf`.
|
/// Write the data any time later to the returned buffer pointer `buf`.
|
||||||
/// @tparam T The data type of the data that will be stored in the buffer
|
/// @tparam T The data type of the data that will be stored in the buffer
|
||||||
@@ -1046,14 +1056,14 @@ class FlatBufferBuilder {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) {
|
Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) {
|
||||||
AssertScalarT<T>();
|
AssertScalarT<T>();
|
||||||
return CreateUninitializedVector(len, sizeof(T),
|
return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
|
||||||
reinterpret_cast<uint8_t **>(buf));
|
reinterpret_cast<uint8_t **>(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
|
Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
|
||||||
T **buf) {
|
T **buf) {
|
||||||
return CreateUninitializedVector(len, sizeof(T),
|
return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
|
||||||
reinterpret_cast<uint8_t **>(buf));
|
reinterpret_cast<uint8_t **>(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1064,7 +1074,7 @@ class FlatBufferBuilder {
|
|||||||
Offset<Vector<T>> CreateVectorScalarCast(const U *v, size_t len) {
|
Offset<Vector<T>> CreateVectorScalarCast(const U *v, size_t len) {
|
||||||
AssertScalarT<T>();
|
AssertScalarT<T>();
|
||||||
AssertScalarT<U>();
|
AssertScalarT<U>();
|
||||||
StartVector(len, sizeof(T));
|
StartVector<T>(len);
|
||||||
for (auto i = len; i > 0;) { PushElement(static_cast<T>(v[--i])); }
|
for (auto i = len; i > 0;) { PushElement(static_cast<T>(v[--i])); }
|
||||||
return Offset<Vector<T>>(EndVector(len));
|
return Offset<Vector<T>>(EndVector(len));
|
||||||
}
|
}
|
||||||
@@ -1173,7 +1183,7 @@ class FlatBufferBuilder {
|
|||||||
// Allocates space for a vector of structures.
|
// Allocates space for a vector of structures.
|
||||||
// Must be completed with EndVectorOfStructs().
|
// Must be completed with EndVectorOfStructs().
|
||||||
template<typename T> T *StartVectorOfStructs(size_t vector_size) {
|
template<typename T> T *StartVectorOfStructs(size_t vector_size) {
|
||||||
StartVector(vector_size * sizeof(T) / AlignOf<T>(), AlignOf<T>());
|
StartVector(vector_size * sizeof(T) / AlignOf<T>(), sizeof(T), AlignOf<T>());
|
||||||
return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
|
return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
// Ensure the included flatbuffers.h is the same version as when this file was
|
// Ensure the included flatbuffers.h is the same version as when this file was
|
||||||
// generated, otherwise it may not be compatible.
|
// generated, otherwise it may not be compatible.
|
||||||
static_assert(FLATBUFFERS_VERSION_MAJOR == 2 &&
|
static_assert(FLATBUFFERS_VERSION_MAJOR == 22 &&
|
||||||
FLATBUFFERS_VERSION_MINOR == 0 &&
|
FLATBUFFERS_VERSION_MINOR == 9 &&
|
||||||
FLATBUFFERS_VERSION_REVISION == 8,
|
FLATBUFFERS_VERSION_REVISION == 29,
|
||||||
"Non-compatible flatbuffers version included");
|
"Non-compatible flatbuffers version included");
|
||||||
|
|
||||||
namespace reflection {
|
namespace reflection {
|
||||||
|
|||||||
@@ -685,9 +685,6 @@ bool SetGlobalTestLocale(const char *locale_name,
|
|||||||
bool ReadEnvironmentVariable(const char *var_name,
|
bool ReadEnvironmentVariable(const char *var_name,
|
||||||
std::string *_value = nullptr);
|
std::string *_value = nullptr);
|
||||||
|
|
||||||
// MSVC specific: Send all assert reports to STDOUT to prevent CI hangs.
|
|
||||||
void SetupDefaultCRTReportMode();
|
|
||||||
|
|
||||||
enum class Case {
|
enum class Case {
|
||||||
kUnknown = 0,
|
kUnknown = 0,
|
||||||
// TheQuickBrownFox
|
// TheQuickBrownFox
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.google.flatbuffers</groupId>
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
<artifactId>flatbuffers-java</artifactId>
|
<artifactId>flatbuffers-java</artifactId>
|
||||||
<version>2.0.8</version>
|
<version>22.9.29</version>
|
||||||
<packaging>bundle</packaging>
|
<packaging>bundle</packaging>
|
||||||
<name>FlatBuffers Java API</name>
|
<name>FlatBuffers Java API</name>
|
||||||
<description>
|
<description>
|
||||||
@@ -37,6 +37,18 @@
|
|||||||
<tag>HEAD</tag>
|
<tag>HEAD</tag>
|
||||||
</scm>
|
</scm>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.13.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.truth</groupId>
|
||||||
|
<artifactId>truth</artifactId>
|
||||||
|
<version>1.1.3</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
<snapshotRepository>
|
<snapshotRepository>
|
||||||
@@ -45,7 +57,21 @@
|
|||||||
</snapshotRepository>
|
</snapshotRepository>
|
||||||
</distributionManagement>
|
</distributionManagement>
|
||||||
<build>
|
<build>
|
||||||
<sourceDirectory>java</sourceDirectory>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<release>8</release>
|
||||||
|
<testExcludes>
|
||||||
|
<testExclude>**/LongEnum.java</testExclude>
|
||||||
|
<testExclude>MyGame/Example/MonsterStorageGrpc.java</testExclude>
|
||||||
|
<testExclude>MyGame/Example/StructOfStructs**</testExclude>
|
||||||
|
<testExclude>MyGame/OtherNameSpace/TableBT.java</testExclude>
|
||||||
|
</testExcludes>
|
||||||
|
</configuration>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
@@ -55,13 +81,6 @@
|
|||||||
</activation>
|
</activation>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<release>8</release>
|
|
||||||
</configuration>
|
|
||||||
<version>3.8.1</version>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
@@ -46,7 +46,7 @@ public class Constants {
|
|||||||
Changes to the Java implementation need to be sure to change
|
Changes to the Java implementation need to be sure to change
|
||||||
the version here and in the code generator on every possible
|
the version here and in the code generator on every possible
|
||||||
incompatible change */
|
incompatible change */
|
||||||
public static void FLATBUFFERS_2_0_8() {}
|
public static void FLATBUFFERS_22_9_29() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @endcond
|
/// @endcond
|
||||||
@@ -173,6 +173,21 @@ public class FlexBuffersBuilder {
|
|||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a null value into the buffer
|
||||||
|
*/
|
||||||
|
public void putNull() {
|
||||||
|
putNull(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a null value into the buffer
|
||||||
|
* @param key key used to store element in map
|
||||||
|
*/
|
||||||
|
public void putNull(String key) {
|
||||||
|
stack.add(Value.nullValue(putKey(key)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a single boolean into the buffer
|
* Insert a single boolean into the buffer
|
||||||
* @param val true or false
|
* @param val true or false
|
||||||
@@ -502,7 +517,9 @@ public class FlexBuffersBuilder {
|
|||||||
* @return Value representing the created vector
|
* @return Value representing the created vector
|
||||||
*/
|
*/
|
||||||
private Value createVector(int key, int start, int length, boolean typed, boolean fixed, Value keys) {
|
private Value createVector(int key, int start, int length, boolean typed, boolean fixed, Value keys) {
|
||||||
assert (!fixed || typed); // typed=false, fixed=true combination is not supported.
|
if (fixed & !typed)
|
||||||
|
throw new UnsupportedOperationException("Untyped fixed vector is not supported");
|
||||||
|
|
||||||
// Figure out smallest bit width we can store this vector with.
|
// Figure out smallest bit width we can store this vector with.
|
||||||
int bitWidth = Math.max(WIDTH_8, widthUInBits(length));
|
int bitWidth = Math.max(WIDTH_8, widthUInBits(length));
|
||||||
int prefixElems = 1;
|
int prefixElems = 1;
|
||||||
@@ -673,6 +690,10 @@ public class FlexBuffersBuilder {
|
|||||||
this.iValue = Long.MIN_VALUE;
|
this.iValue = Long.MIN_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Value nullValue(int key) {
|
||||||
|
return new Value(key, FBT_NULL, WIDTH_8, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static Value bool(int key, boolean b) {
|
static Value bool(int key, boolean b) {
|
||||||
return new Value(key, FBT_BOOL, WIDTH_8, b ? 1 : 0);
|
return new Value(key, FBT_BOOL, WIDTH_8, b ? 1 : 0);
|
||||||
}
|
}
|
||||||
1
java/src/test/java/DictionaryLookup
Symbolic link
1
java/src/test/java/DictionaryLookup
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../../../tests/DictionaryLookup
|
||||||
File diff suppressed because it is too large
Load Diff
1
java/src/test/java/MyGame
Symbolic link
1
java/src/test/java/MyGame
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../../../tests/MyGame
|
||||||
1
java/src/test/java/NamespaceA
Symbolic link
1
java/src/test/java/NamespaceA
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../../../tests/namespace_test/NamespaceA
|
||||||
1
java/src/test/java/NamespaceC
Symbolic link
1
java/src/test/java/NamespaceC
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../../../tests/namespace_test/NamespaceC
|
||||||
1
java/src/test/java/optional_scalars
Symbolic link
1
java/src/test/java/optional_scalars
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../../../tests/optional_scalars
|
||||||
1
java/src/test/java/union_vector
Symbolic link
1
java/src/test/java/union_vector
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../../../tests/union_vector
|
||||||
BIN
java/src/test/resources/monsterdata_test.mon
Normal file
BIN
java/src/test/resources/monsterdata_test.mon
Normal file
Binary file not shown.
@@ -1 +1 @@
|
|||||||
../../../../java/
|
../../../../java/src/main/java
|
||||||
@@ -51,7 +51,7 @@ using System.Buffers.Binary;
|
|||||||
#warning ENABLE_SPAN_T requires UNSAFE_BYTEBUFFER to also be defined
|
#warning ENABLE_SPAN_T requires UNSAFE_BYTEBUFFER to also be defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace FlatBuffers
|
namespace Google.FlatBuffers
|
||||||
{
|
{
|
||||||
public abstract class ByteBufferAllocator
|
public abstract class ByteBufferAllocator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace FlatBuffers
|
namespace Google.FlatBuffers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class that collects utility functions around `ByteBuffer`.
|
/// Class that collects utility functions around `ByteBuffer`.
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ using System.Text;
|
|||||||
/// @addtogroup flatbuffers_csharp_api
|
/// @addtogroup flatbuffers_csharp_api
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
namespace FlatBuffers
|
namespace Google.FlatBuffers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Responsible for building up and accessing a FlatBuffer formatted byte
|
/// Responsible for building up and accessing a FlatBuffer formatted byte
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace FlatBuffers
|
namespace Google.FlatBuffers
|
||||||
{
|
{
|
||||||
public static class FlatBufferConstants
|
public static class FlatBufferConstants
|
||||||
{
|
{
|
||||||
@@ -32,6 +32,6 @@ namespace FlatBuffers
|
|||||||
Changes to the C# implementation need to be sure to change
|
Changes to the C# implementation need to be sure to change
|
||||||
the version here and in the code generator on every possible
|
the version here and in the code generator on every possible
|
||||||
incompatible change */
|
incompatible change */
|
||||||
public static void FLATBUFFERS_2_0_8() {}
|
public static void FLATBUFFERS_22_9_29() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFrameworks>netstandard2.1;netstandard2.0;net46</TargetFrameworks>
|
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(UNSAFE_BYTEBUFFER)' == 'true'">
|
|
||||||
<DefineConstants>$(DefineConstants);UNSAFE_BYTEBUFFER</DefineConstants>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(BYTEBUFFER_NO_BOUNDS_CHECK)' == 'true'">
|
|
||||||
<DefineConstants>$(DefineConstants);BYTEBUFFER_NO_BOUNDS_CHECK</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(ENABLE_SPAN_T)' == 'true'">
|
|
||||||
<DefineConstants>$(DefineConstants);ENABLE_SPAN_T</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition="('$(ENABLE_SPAN_T)' == 'true') And (('$(TargetFramework)' == 'netstandard2.0') Or ('$(TargetFramework)' == 'net46'))">
|
|
||||||
<PackageReference Include="System.Memory" Version="4.5.4" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
46
net/FlatBuffers/Google.FlatBuffers.csproj
Normal file
46
net/FlatBuffers/Google.FlatBuffers.csproj
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>netstandard2.1;netstandard2.0;net46</TargetFrameworks>
|
||||||
|
<Description>A cross-platform memory efficient serialization library</Description>
|
||||||
|
<PackageVersion>22.9.29</PackageVersion>
|
||||||
|
<Authors>Google LLC</Authors>
|
||||||
|
<PackageProjectUrl>https://github.com/google/flatbuffers</PackageProjectUrl>
|
||||||
|
<RepositoryUrl>https://github.com/google/flatbuffers</RepositoryUrl>
|
||||||
|
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||||
|
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
|
||||||
|
<PackageIcon>flatbuffers.png</PackageIcon>
|
||||||
|
<PackageTags>Google;FlatBuffers;Serialization;Buffer;Binary;zero copy</PackageTags>
|
||||||
|
<Copyright>Copyright 2022 Google LLC</Copyright>
|
||||||
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
|
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||||
|
<SignAssembly>true</SignAssembly>
|
||||||
|
<AssemblyOriginatorKeyFile>flatbuffers.snk</AssemblyOriginatorKeyFile>
|
||||||
|
<DelaySign>false</DelaySign>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(UNSAFE_BYTEBUFFER)' == 'true'">
|
||||||
|
<DefineConstants>$(DefineConstants);UNSAFE_BYTEBUFFER</DefineConstants>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(BYTEBUFFER_NO_BOUNDS_CHECK)' == 'true'">
|
||||||
|
<DefineConstants>$(DefineConstants);BYTEBUFFER_NO_BOUNDS_CHECK</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(ENABLE_SPAN_T)' == 'true'">
|
||||||
|
<DefineConstants>$(DefineConstants);ENABLE_SPAN_T</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="('$(ENABLE_SPAN_T)' == 'true') And (('$(TargetFramework)' == 'netstandard2.0') Or ('$(TargetFramework)' == 'net46'))">
|
||||||
|
<PackageReference Include="System.Memory" Version="4.5.4" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\..\LICENSE.txt" Pack="true" PackagePath="" />
|
||||||
|
<None Include="flatbuffers.png" Pack="true" PackagePath="" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace FlatBuffers
|
namespace Google.FlatBuffers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the base for both structs and tables.
|
/// This is the base for both structs and tables.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace FlatBuffers
|
namespace Google.FlatBuffers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Offset class for typesafe assignments.
|
/// Offset class for typesafe assignments.
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2014 Google Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("FlatBuffers")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("")]
|
|
||||||
[assembly: AssemblyProduct("FlatBuffers")]
|
|
||||||
[assembly: AssemblyCopyright("Copyright (c) 2015 Google Inc")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
|
||||||
// to COM components. If you need to access a type in this assembly from
|
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|
||||||
[assembly: Guid("91c32e64-ef20-47df-9c9f-cec9207bc6df")]
|
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
|
||||||
//
|
|
||||||
// Major Version
|
|
||||||
// Minor Version
|
|
||||||
// Build Number
|
|
||||||
// Revision
|
|
||||||
//
|
|
||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
|
||||||
// by using the '*' as shown below:
|
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
|
||||||
[assembly: AssemblyVersion("1.0.0.0")]
|
|
||||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace FlatBuffers
|
namespace Google.FlatBuffers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All structs in the generated code derive from this class, and add their own accessors.
|
/// All structs in the generated code derive from this class, and add their own accessors.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ using System;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace FlatBuffers
|
namespace Google.FlatBuffers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All tables in the generated code derive from this struct, and add their own accessors.
|
/// All tables in the generated code derive from this struct, and add their own accessors.
|
||||||
|
|||||||
BIN
net/FlatBuffers/flatbuffers.png
Normal file
BIN
net/FlatBuffers/flatbuffers.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.0 KiB |
BIN
net/FlatBuffers/flatbuffers.snk
Normal file
BIN
net/FlatBuffers/flatbuffers.snk
Normal file
Binary file not shown.
19
package.json
19
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "flatbuffers",
|
"name": "flatbuffers",
|
||||||
"version": "2.0.8",
|
"version": "22.9.29",
|
||||||
"description": "Memory Efficient Serialization Library",
|
"description": "Memory Efficient Serialization Library",
|
||||||
"files": [
|
"files": [
|
||||||
"js/**/*.js",
|
"js/**/*.js",
|
||||||
@@ -16,7 +16,8 @@
|
|||||||
"test": "tests"
|
"test": "tests"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "npm run compile && cd tests && python3 ./TypeScriptTest.py",
|
"test": "npm run compile && cd tests/ts && python3 ./TypeScriptTest.py",
|
||||||
|
"lint": "eslint ts",
|
||||||
"compile": "tsc && tsc -p tsconfig.mjs.json && rollup -c",
|
"compile": "tsc && tsc -p tsconfig.mjs.json && rollup -c",
|
||||||
"prepublishOnly": "npm install --only=dev && npm run compile"
|
"prepublishOnly": "npm install --only=dev && npm run compile"
|
||||||
},
|
},
|
||||||
@@ -35,12 +36,12 @@
|
|||||||
"homepage": "https://google.github.io/flatbuffers/",
|
"homepage": "https://google.github.io/flatbuffers/",
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@bazel/typescript": "^5.2.0",
|
"@bazel/typescript": "5.2.0",
|
||||||
"@types/node": "17.0.21",
|
"@types/node": "18.7.16",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.12.0",
|
"@typescript-eslint/eslint-plugin": "^5.36.2",
|
||||||
"@typescript-eslint/parser": "^4.12.0",
|
"@typescript-eslint/parser": "^5.36.2",
|
||||||
"eslint": "^7.17.0",
|
"eslint": "^8.23.1",
|
||||||
"rollup": "^2.78.0",
|
"rollup": "^2.79.0",
|
||||||
"typescript": "^4.5.5"
|
"typescript": "^4.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,4 +14,4 @@
|
|||||||
|
|
||||||
# Placeholder, to be updated during the release process
|
# Placeholder, to be updated during the release process
|
||||||
# by the setup.py
|
# by the setup.py
|
||||||
__version__ = u"2.0.8"
|
__version__ = u"22.9.29"
|
||||||
|
|||||||
@@ -113,6 +113,15 @@ class Table(object):
|
|||||||
numpy_dtype = N.to_numpy_type(flags)
|
numpy_dtype = N.to_numpy_type(flags)
|
||||||
return encode.GetVectorAsNumpy(numpy_dtype, self.Bytes, length, offset)
|
return encode.GetVectorAsNumpy(numpy_dtype, self.Bytes, length, offset)
|
||||||
|
|
||||||
|
def GetArrayAsNumpy(self, flags, off, length):
|
||||||
|
"""
|
||||||
|
GetArrayAsNumpy returns the array with fixed width that starts at `Vector(offset)`
|
||||||
|
with length `length` as a numpy array with the type specified by `flags`. The
|
||||||
|
array is a `view` into Bytes so modifying the returned will modify Bytes in place.
|
||||||
|
"""
|
||||||
|
numpy_dtype = N.to_numpy_type(flags)
|
||||||
|
return encode.GetVectorAsNumpy(numpy_dtype, self.Bytes, length, off)
|
||||||
|
|
||||||
def GetVOffsetTSlot(self, slot, d):
|
def GetVOffsetTSlot(self, slot, d):
|
||||||
"""
|
"""
|
||||||
GetVOffsetTSlot retrieves the VOffsetT that the given vtable location
|
GetVOffsetTSlot retrieves the VOffsetT that the given vtable location
|
||||||
@@ -125,5 +134,5 @@ class Table(object):
|
|||||||
|
|
||||||
off = self.Offset(slot)
|
off = self.Offset(slot)
|
||||||
if off == 0:
|
if off == 0:
|
||||||
return d
|
return d
|
||||||
return off
|
return off
|
||||||
|
|||||||
45
readme.md
45
readme.md
@@ -20,33 +20,46 @@ maximum memory efficiency. It allows you to directly access serialized data with
|
|||||||
* MacOS X
|
* MacOS X
|
||||||
* Linux
|
* Linux
|
||||||
* Android
|
* Android
|
||||||
* And any others with a recent C++ compiler.
|
* And any others with a recent C++ compiler (C++ 11 and newer)
|
||||||
|
|
||||||
## Supported programming languages
|
## Supported programming languages
|
||||||
* C++
|
|
||||||
* C#
|
Code generation and runtime libraries for many popular languages.
|
||||||
* C
|
|
||||||
* Dart
|
1. C
|
||||||
* Go
|
1. C++ - [snapcraft.io](https://snapcraft.io/flatbuffers)
|
||||||
* Java
|
1. C# - [nuget.org](https://www.nuget.org/packages/Google.FlatBuffers)
|
||||||
* JavaScript
|
1. Dart - [pub.dev](https://pub.dev/packages/flat_buffers)
|
||||||
* Lobster
|
1. Go - [go.dev](https://pkg.go.dev/github.com/google/flatbuffers/go)
|
||||||
* Lua
|
1. Java - [Maven](https://search.maven.org/artifact/com.google.flatbuffers/flatbuffers-java)
|
||||||
* PHP
|
1. JavaScript - [NPM](https://www.npmjs.com/package/flatbuffers)
|
||||||
* Python
|
1. Kotlin
|
||||||
* Rust
|
1. Lobster
|
||||||
* Swift
|
1. Lua
|
||||||
* TypeScript
|
1. PHP
|
||||||
|
1. Python - [PyPi](https://pypi.org/project/flatbuffers/)
|
||||||
|
1. Rust - [crates.io](https://crates.io/crates/flatbuffers)
|
||||||
|
1. Swift
|
||||||
|
1. TypeScript - [NPM](https://www.npmjs.com/package/flatbuffers)
|
||||||
|
|
||||||
*and more in progress...*
|
*and more in progress...*
|
||||||
|
|
||||||
|
1. [Nim](https://github.com/google/flatbuffers/pull/7362)
|
||||||
|
|
||||||
## Contribution
|
## Contribution
|
||||||
* [FlatBuffers Google Group][] to discuss FlatBuffers with other developers and users.
|
|
||||||
* [FlatBuffers Issues Tracker][] to submit an issue.
|
* [FlatBuffers Issues Tracker][] to submit an issue.
|
||||||
* [stackoverflow.com][] with [`flatbuffers` tag][] for any questions regarding FlatBuffers.
|
* [stackoverflow.com][] with [`flatbuffers` tag][] for any questions regarding FlatBuffers.
|
||||||
|
|
||||||
*To contribute to this project,* see [CONTRIBUTING][].
|
*To contribute to this project,* see [CONTRIBUTING][].
|
||||||
|
|
||||||
|
## Community
|
||||||
|
|
||||||
|
* [FlatBuffers Google Group][] to discuss FlatBuffers with other developers and users.
|
||||||
|
* [Discord Server](https:///discord.gg/6qgKs3R)
|
||||||
|
* [Gitter](https://gitter.im/google/flatbuffers)
|
||||||
|
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
Please see our [Security Policy](SECURITY.md) for reporting vulnerabilities.
|
Please see our [Security Policy](SECURITY.md) for reporting vulnerabilities.
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ no_std = ["core2", "thiserror_core2"]
|
|||||||
serialize = ["serde"]
|
serialize = ["serde"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
smallvec = "1.6.1"
|
|
||||||
bitflags = "1.2.1"
|
bitflags = "1.2.1"
|
||||||
serde = { version = "1.0", optional = true }
|
serde = { version = "1.0", optional = true }
|
||||||
thiserror = { version = "1.0.30", optional = true }
|
thiserror = { version = "1.0.30", optional = true }
|
||||||
|
|||||||
@@ -37,14 +37,18 @@ where
|
|||||||
#[allow(clippy::len_without_is_empty)]
|
#[allow(clippy::len_without_is_empty)]
|
||||||
#[allow(clippy::from_over_into)] // TODO(caspern): Go from From to Into.
|
#[allow(clippy::from_over_into)] // TODO(caspern): Go from From to Into.
|
||||||
impl<'a, T: 'a, const N: usize> Array<'a, T, N> {
|
impl<'a, T: 'a, const N: usize> Array<'a, T, N> {
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// buf must be a contiguous array of `T`
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if `buf.len()` is not `size_of::<T>() * N`
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(buf: &'a [u8]) -> Self {
|
pub unsafe fn new(buf: &'a [u8]) -> Self {
|
||||||
assert!(size_of::<T>() * N == buf.len());
|
assert_eq!(size_of::<T>() * N, buf.len());
|
||||||
|
|
||||||
Array {
|
Array(buf, PhantomData)
|
||||||
0: buf,
|
|
||||||
1: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -61,34 +65,39 @@ impl<'a, T: Follow<'a> + 'a, const N: usize> Array<'a, T, N> {
|
|||||||
pub fn get(&self, idx: usize) -> T::Inner {
|
pub fn get(&self, idx: usize) -> T::Inner {
|
||||||
assert!(idx < N);
|
assert!(idx < N);
|
||||||
let sz = size_of::<T>();
|
let sz = size_of::<T>();
|
||||||
T::follow(self.0, sz * idx)
|
// Safety:
|
||||||
|
// self.0 was valid for length `N` on construction and have verified `idx < N`
|
||||||
|
unsafe { T::follow(self.0, sz * idx) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn iter(&self) -> VectorIter<'a, T> {
|
pub fn iter(&self) -> VectorIter<'a, T> {
|
||||||
VectorIter::from_slice(self.0, self.len())
|
// Safety:
|
||||||
|
// self.0 was valid for length N on construction
|
||||||
|
unsafe { VectorIter::from_slice(self.0, self.len()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Follow<'a> + Debug, const N: usize> Into<[T::Inner; N]> for Array<'a, T, N> {
|
impl<'a, T: Follow<'a> + Debug, const N: usize> From<Array<'a, T, N>> for [T::Inner; N] {
|
||||||
#[inline(always)]
|
fn from(array: Array<'a, T, N>) -> Self {
|
||||||
fn into(self) -> [T::Inner; N] {
|
array_init(|i| array.get(i))
|
||||||
array_init(|i| self.get(i))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(caspern): Implement some future safe version of SafeSliceAccess.
|
|
||||||
|
|
||||||
/// Implement Follow for all possible Arrays that have Follow-able elements.
|
/// Implement Follow for all possible Arrays that have Follow-able elements.
|
||||||
impl<'a, T: Follow<'a> + 'a, const N: usize> Follow<'a> for Array<'a, T, N> {
|
impl<'a, T: Follow<'a> + 'a, const N: usize> Follow<'a> for Array<'a, T, N> {
|
||||||
type Inner = Array<'a, T, N>;
|
type Inner = Array<'a, T, N>;
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
Array::new(&buf[loc..loc + N * size_of::<T>()])
|
Array::new(&buf[loc..loc + N * size_of::<T>()])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn emplace_scalar_array<T: EndianScalar, const N: usize>(
|
/// Place an array of EndianScalar into the provided mutable byte slice. Performs
|
||||||
|
/// endian conversion, if necessary.
|
||||||
|
/// # Safety
|
||||||
|
/// Caller must ensure `s.len() >= size_of::<[T; N]>()`
|
||||||
|
pub unsafe fn emplace_scalar_array<T: EndianScalar, const N: usize>(
|
||||||
buf: &mut [u8],
|
buf: &mut [u8],
|
||||||
loc: usize,
|
loc: usize,
|
||||||
src: &[T; N],
|
src: &[T; N],
|
||||||
@@ -96,14 +105,12 @@ pub fn emplace_scalar_array<T: EndianScalar, const N: usize>(
|
|||||||
let mut buf_ptr = buf[loc..].as_mut_ptr();
|
let mut buf_ptr = buf[loc..].as_mut_ptr();
|
||||||
for item in src.iter() {
|
for item in src.iter() {
|
||||||
let item_le = item.to_little_endian();
|
let item_le = item.to_little_endian();
|
||||||
unsafe {
|
core::ptr::copy_nonoverlapping(
|
||||||
core::ptr::copy_nonoverlapping(
|
&item_le as *const T::Scalar as *const u8,
|
||||||
&item_le as *const T as *const u8,
|
buf_ptr,
|
||||||
buf_ptr,
|
size_of::<T::Scalar>(),
|
||||||
size_of::<T>(),
|
);
|
||||||
);
|
buf_ptr = buf_ptr.add(size_of::<T::Scalar>());
|
||||||
buf_ptr = buf_ptr.add(size_of::<T>());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +131,8 @@ where
|
|||||||
let mut array: core::mem::MaybeUninit<[T; N]> = core::mem::MaybeUninit::uninit();
|
let mut array: core::mem::MaybeUninit<[T; N]> = core::mem::MaybeUninit::uninit();
|
||||||
let mut ptr_i = array.as_mut_ptr() as *mut T;
|
let mut ptr_i = array.as_mut_ptr() as *mut T;
|
||||||
|
|
||||||
|
// Safety:
|
||||||
|
// array is aligned by T, and has length N
|
||||||
unsafe {
|
unsafe {
|
||||||
for i in 0..N {
|
for i in 0..N {
|
||||||
let value_i = initializer(i);
|
let value_i = initializer(i);
|
||||||
@@ -134,7 +143,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="serialize")]
|
#[cfg(feature = "serialize")]
|
||||||
impl<'a, T: 'a, const N: usize> serde::ser::Serialize for Array<'a, T, N>
|
impl<'a, T: 'a, const N: usize> serde::ser::Serialize for Array<'a, T, N>
|
||||||
where
|
where
|
||||||
T: 'a + Follow<'a>,
|
T: 'a + Follow<'a>,
|
||||||
|
|||||||
@@ -14,26 +14,22 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern crate smallvec;
|
#[cfg(feature = "no_std")]
|
||||||
|
use alloc::{vec, vec::Vec};
|
||||||
use core::cmp::max;
|
use core::cmp::max;
|
||||||
use core::iter::{DoubleEndedIterator, ExactSizeIterator};
|
use core::iter::{DoubleEndedIterator, ExactSizeIterator};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::ptr::write_bytes;
|
use core::ptr::write_bytes;
|
||||||
use core::slice::from_raw_parts;
|
|
||||||
#[cfg(feature = "no_std")]
|
|
||||||
use alloc::{vec, vec::Vec};
|
|
||||||
|
|
||||||
use crate::endian_scalar::{emplace_scalar, read_scalar_at};
|
use crate::endian_scalar::emplace_scalar;
|
||||||
use crate::primitives::*;
|
use crate::primitives::*;
|
||||||
use crate::push::{Push, PushAlignment};
|
use crate::push::{Push, PushAlignment};
|
||||||
|
use crate::read_scalar;
|
||||||
use crate::table::Table;
|
use crate::table::Table;
|
||||||
use crate::vector::{SafeSliceAccess, Vector};
|
use crate::vector::Vector;
|
||||||
use crate::vtable::{field_index_to_field_offset, VTable};
|
use crate::vtable::{field_index_to_field_offset, VTable};
|
||||||
use crate::vtable_writer::VTableWriter;
|
use crate::vtable_writer::VTableWriter;
|
||||||
|
|
||||||
pub const N_SMALLVEC_STRING_VECTOR_CAPACITY: usize = 16;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
struct FieldLoc {
|
struct FieldLoc {
|
||||||
off: UOffsetT,
|
off: UOffsetT,
|
||||||
@@ -121,6 +117,8 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
|
|||||||
{
|
{
|
||||||
let to_clear = self.owned_buf.len() - self.head;
|
let to_clear = self.owned_buf.len() - self.head;
|
||||||
let ptr = (&mut self.owned_buf[self.head..]).as_mut_ptr();
|
let ptr = (&mut self.owned_buf[self.head..]).as_mut_ptr();
|
||||||
|
// Safety:
|
||||||
|
// Verified ptr is valid for `to_clear` above
|
||||||
unsafe {
|
unsafe {
|
||||||
write_bytes(ptr, 0, to_clear);
|
write_bytes(ptr, 0, to_clear);
|
||||||
}
|
}
|
||||||
@@ -153,7 +151,9 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
|
|||||||
self.make_space(sz);
|
self.make_space(sz);
|
||||||
{
|
{
|
||||||
let (dst, rest) = (&mut self.owned_buf[self.head..]).split_at_mut(sz);
|
let (dst, rest) = (&mut self.owned_buf[self.head..]).split_at_mut(sz);
|
||||||
x.push(dst, rest);
|
// Safety:
|
||||||
|
// Called make_space above
|
||||||
|
unsafe { x.push(dst, rest.len()) };
|
||||||
}
|
}
|
||||||
WIPOffset::new(self.used_space() as UOffsetT)
|
WIPOffset::new(self.used_space() as UOffsetT)
|
||||||
}
|
}
|
||||||
@@ -309,73 +309,32 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
|
|||||||
WIPOffset::new(self.used_space() as UOffsetT)
|
WIPOffset::new(self.used_space() as UOffsetT)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a vector by memcpy'ing. This is much faster than calling
|
|
||||||
/// `create_vector`, but the underlying type must be represented as
|
|
||||||
/// little-endian on the host machine. This property is encoded in the
|
|
||||||
/// type system through the SafeSliceAccess trait. The following types are
|
|
||||||
/// always safe, on any platform: bool, u8, i8, and any
|
|
||||||
/// FlatBuffers-generated struct.
|
|
||||||
#[inline]
|
|
||||||
pub fn create_vector_direct<'a: 'b, 'b, T: SafeSliceAccess + Push + Sized + 'b>(
|
|
||||||
&'a mut self,
|
|
||||||
items: &'b [T],
|
|
||||||
) -> WIPOffset<Vector<'fbb, T>> {
|
|
||||||
self.assert_not_nested(
|
|
||||||
"create_vector_direct can not be called when a table or vector is under construction",
|
|
||||||
);
|
|
||||||
let elem_size = T::size();
|
|
||||||
self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET));
|
|
||||||
|
|
||||||
let bytes = {
|
|
||||||
let ptr = items.as_ptr() as *const T as *const u8;
|
|
||||||
unsafe { from_raw_parts(ptr, items.len() * elem_size) }
|
|
||||||
};
|
|
||||||
self.push_bytes_unprefixed(bytes);
|
|
||||||
self.push(items.len() as UOffsetT);
|
|
||||||
|
|
||||||
WIPOffset::new(self.used_space() as UOffsetT)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a vector of strings.
|
|
||||||
///
|
|
||||||
/// Speed-sensitive users may wish to reduce memory usage by creating the
|
|
||||||
/// vector manually: use `start_vector`, `push`, and `end_vector`.
|
|
||||||
#[inline]
|
|
||||||
pub fn create_vector_of_strings<'a, 'b>(
|
|
||||||
&'a mut self,
|
|
||||||
xs: &'b [&'b str],
|
|
||||||
) -> WIPOffset<Vector<'fbb, ForwardsUOffset<&'fbb str>>> {
|
|
||||||
self.assert_not_nested("create_vector_of_strings can not be called when a table or vector is under construction");
|
|
||||||
// internally, smallvec can be a stack-allocated or heap-allocated vector:
|
|
||||||
// if xs.len() > N_SMALLVEC_STRING_VECTOR_CAPACITY then it will overflow to the heap.
|
|
||||||
let mut offsets: smallvec::SmallVec<[WIPOffset<&str>; N_SMALLVEC_STRING_VECTOR_CAPACITY]> =
|
|
||||||
smallvec::SmallVec::with_capacity(xs.len());
|
|
||||||
unsafe {
|
|
||||||
offsets.set_len(xs.len());
|
|
||||||
}
|
|
||||||
|
|
||||||
// note that this happens in reverse, because the buffer is built back-to-front:
|
|
||||||
for (i, &s) in xs.iter().enumerate().rev() {
|
|
||||||
let o = self.create_string(s);
|
|
||||||
offsets[i] = o;
|
|
||||||
}
|
|
||||||
self.create_vector(&offsets[..])
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a vector of Push-able objects.
|
/// Create a vector of Push-able objects.
|
||||||
///
|
///
|
||||||
/// Speed-sensitive users may wish to reduce memory usage by creating the
|
/// Speed-sensitive users may wish to reduce memory usage by creating the
|
||||||
/// vector manually: use `start_vector`, `push`, and `end_vector`.
|
/// vector manually: use `start_vector`, `push`, and `end_vector`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn create_vector<'a: 'b, 'b, T: Push + Copy + 'b>(
|
pub fn create_vector<'a: 'b, 'b, T: Push + 'b>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
items: &'b [T],
|
items: &'b [T],
|
||||||
) -> WIPOffset<Vector<'fbb, T::Output>> {
|
) -> WIPOffset<Vector<'fbb, T::Output>> {
|
||||||
let elem_size = T::size();
|
let elem_size = T::size();
|
||||||
self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET));
|
let slice_size = items.len() * elem_size;
|
||||||
for i in (0..items.len()).rev() {
|
self.align(slice_size, T::alignment().max_of(SIZE_UOFFSET));
|
||||||
self.push(items[i]);
|
self.ensure_capacity(slice_size + UOffsetT::size());
|
||||||
|
|
||||||
|
self.head -= slice_size;
|
||||||
|
let mut written_len = self.owned_buf.len() - self.head;
|
||||||
|
|
||||||
|
let buf = &mut self.owned_buf[self.head..self.head + slice_size];
|
||||||
|
for (item, out) in items.iter().zip(buf.chunks_exact_mut(elem_size)) {
|
||||||
|
written_len -= elem_size;
|
||||||
|
|
||||||
|
// Safety:
|
||||||
|
// Called ensure_capacity and aligned to T above
|
||||||
|
unsafe { item.push(out, written_len) };
|
||||||
}
|
}
|
||||||
|
|
||||||
WIPOffset::new(self.push::<UOffsetT>(items.len() as UOffsetT).value())
|
WIPOffset::new(self.push::<UOffsetT>(items.len() as UOffsetT).value())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,17 +343,18 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
|
|||||||
/// Speed-sensitive users may wish to reduce memory usage by creating the
|
/// Speed-sensitive users may wish to reduce memory usage by creating the
|
||||||
/// vector manually: use `start_vector`, `push`, and `end_vector`.
|
/// vector manually: use `start_vector`, `push`, and `end_vector`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn create_vector_from_iter<T: Push + Copy>(
|
pub fn create_vector_from_iter<T: Push>(
|
||||||
&mut self,
|
&mut self,
|
||||||
items: impl ExactSizeIterator<Item = T> + DoubleEndedIterator,
|
items: impl ExactSizeIterator<Item = T> + DoubleEndedIterator,
|
||||||
) -> WIPOffset<Vector<'fbb, T::Output>> {
|
) -> WIPOffset<Vector<'fbb, T::Output>> {
|
||||||
let elem_size = T::size();
|
let elem_size = T::size();
|
||||||
let len = items.len();
|
self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET));
|
||||||
self.align(len * elem_size, T::alignment().max_of(SIZE_UOFFSET));
|
let mut actual = 0;
|
||||||
for item in items.rev() {
|
for item in items.rev() {
|
||||||
self.push(item);
|
self.push(item);
|
||||||
|
actual += 1;
|
||||||
}
|
}
|
||||||
WIPOffset::new(self.push::<UOffsetT>(len as UOffsetT).value())
|
WIPOffset::new(self.push::<UOffsetT>(actual).value())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set whether default values are stored.
|
/// Set whether default values are stored.
|
||||||
@@ -443,7 +403,15 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
|
|||||||
assert_msg_name: &'static str,
|
assert_msg_name: &'static str,
|
||||||
) {
|
) {
|
||||||
let idx = self.used_space() - tab_revloc.value() as usize;
|
let idx = self.used_space() - tab_revloc.value() as usize;
|
||||||
let tab = Table::new(&self.owned_buf[self.head..], idx);
|
|
||||||
|
// Safety:
|
||||||
|
// The value of TableFinishedWIPOffset is the offset from the end of owned_buf
|
||||||
|
// to an SOffsetT pointing to a valid VTable
|
||||||
|
//
|
||||||
|
// `self.owned_buf.len() = self.used_space() + self.head`
|
||||||
|
// `self.owned_buf.len() - tab_revloc = self.used_space() - tab_revloc + self.head`
|
||||||
|
// `self.owned_buf.len() - tab_revloc = idx + self.head`
|
||||||
|
let tab = unsafe { Table::new(&self.owned_buf[self.head..], idx) };
|
||||||
let o = tab.vtable().get(slot_byte_loc) as usize;
|
let o = tab.vtable().get(slot_byte_loc) as usize;
|
||||||
assert!(o != 0, "missing required field {}", assert_msg_name);
|
assert!(o != 0, "missing required field {}", assert_msg_name);
|
||||||
}
|
}
|
||||||
@@ -560,11 +528,15 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let new_vt_bytes = &self.owned_buf[vt_start_pos..vt_end_pos];
|
let new_vt_bytes = &self.owned_buf[vt_start_pos..vt_end_pos];
|
||||||
let found = self.written_vtable_revpos.binary_search_by(|old_vtable_revpos: &UOffsetT| {
|
let found = self
|
||||||
let old_vtable_pos = self.owned_buf.len() - *old_vtable_revpos as usize;
|
.written_vtable_revpos
|
||||||
let old_vtable = VTable::init(&self.owned_buf, old_vtable_pos);
|
.binary_search_by(|old_vtable_revpos: &UOffsetT| {
|
||||||
new_vt_bytes.cmp(old_vtable.as_bytes())
|
let old_vtable_pos = self.owned_buf.len() - *old_vtable_revpos as usize;
|
||||||
});
|
// Safety:
|
||||||
|
// Already written vtables are valid by construction
|
||||||
|
let old_vtable = unsafe { VTable::init(&self.owned_buf, old_vtable_pos) };
|
||||||
|
new_vt_bytes.cmp(old_vtable.as_bytes())
|
||||||
|
});
|
||||||
let final_vtable_revpos = match found {
|
let final_vtable_revpos = match found {
|
||||||
Ok(i) => {
|
Ok(i) => {
|
||||||
// The new vtable is a duplicate so clear it.
|
// The new vtable is a duplicate so clear it.
|
||||||
@@ -581,12 +553,22 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
|
|||||||
};
|
};
|
||||||
// Write signed offset from table to its vtable.
|
// Write signed offset from table to its vtable.
|
||||||
let table_pos = self.owned_buf.len() - object_revloc_to_vtable.value() as usize;
|
let table_pos = self.owned_buf.len() - object_revloc_to_vtable.value() as usize;
|
||||||
let tmp_soffset_to_vt = unsafe { read_scalar_at::<UOffsetT>(&self.owned_buf, table_pos) };
|
if cfg!(debug_assertions) {
|
||||||
debug_assert_eq!(tmp_soffset_to_vt, 0xF0F0_F0F0);
|
// Safety:
|
||||||
|
// Verified slice length
|
||||||
|
let tmp_soffset_to_vt = unsafe {
|
||||||
|
read_scalar::<UOffsetT>(&self.owned_buf[table_pos..table_pos + SIZE_UOFFSET])
|
||||||
|
};
|
||||||
|
assert_eq!(tmp_soffset_to_vt, 0xF0F0_F0F0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let buf = &mut self.owned_buf[table_pos..table_pos + SIZE_SOFFSET];
|
||||||
|
// Safety:
|
||||||
|
// Verified length of buf above
|
||||||
unsafe {
|
unsafe {
|
||||||
emplace_scalar::<SOffsetT>(
|
emplace_scalar::<SOffsetT>(
|
||||||
&mut self.owned_buf[table_pos..table_pos + SIZE_SOFFSET],
|
buf,
|
||||||
final_vtable_revpos as SOffsetT - object_revloc_to_vtable.value() as SOffsetT
|
final_vtable_revpos as SOffsetT - object_revloc_to_vtable.value() as SOffsetT,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,6 +606,8 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
|
|||||||
// finally, zero out the old end data.
|
// finally, zero out the old end data.
|
||||||
{
|
{
|
||||||
let ptr = (&mut self.owned_buf[..middle]).as_mut_ptr();
|
let ptr = (&mut self.owned_buf[..middle]).as_mut_ptr();
|
||||||
|
// Safety:
|
||||||
|
// ptr is byte aligned and of length middle
|
||||||
unsafe {
|
unsafe {
|
||||||
write_bytes(ptr, 0, middle);
|
write_bytes(ptr, 0, middle);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,24 @@
|
|||||||
|
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
|
|
||||||
|
mod private {
|
||||||
|
/// Types that are trivially transmutable are those where any combination of bits
|
||||||
|
/// represents a valid value of that type
|
||||||
|
///
|
||||||
|
/// For example integral types are TriviallyTransmutable as all bit patterns are valid,
|
||||||
|
/// however, `bool` is not trivially transmutable as only `0` and `1` are valid
|
||||||
|
pub trait TriviallyTransmutable {}
|
||||||
|
|
||||||
|
impl TriviallyTransmutable for i8 {}
|
||||||
|
impl TriviallyTransmutable for i16 {}
|
||||||
|
impl TriviallyTransmutable for i32 {}
|
||||||
|
impl TriviallyTransmutable for i64 {}
|
||||||
|
impl TriviallyTransmutable for u8 {}
|
||||||
|
impl TriviallyTransmutable for u16 {}
|
||||||
|
impl TriviallyTransmutable for u32 {}
|
||||||
|
impl TriviallyTransmutable for u64 {}
|
||||||
|
}
|
||||||
|
|
||||||
/// Trait for values that must be stored in little-endian byte order, but
|
/// Trait for values that must be stored in little-endian byte order, but
|
||||||
/// might be represented in memory as big-endian. Every type that implements
|
/// might be represented in memory as big-endian. Every type that implements
|
||||||
/// EndianScalar is a valid FlatBuffers scalar value.
|
/// EndianScalar is a valid FlatBuffers scalar value.
|
||||||
@@ -28,144 +46,118 @@ use core::mem::size_of;
|
|||||||
/// "too much". For example, num-traits provides i128 support, but that is an
|
/// "too much". For example, num-traits provides i128 support, but that is an
|
||||||
/// invalid FlatBuffers type.
|
/// invalid FlatBuffers type.
|
||||||
pub trait EndianScalar: Sized + PartialEq + Copy + Clone {
|
pub trait EndianScalar: Sized + PartialEq + Copy + Clone {
|
||||||
fn to_little_endian(self) -> Self;
|
type Scalar: private::TriviallyTransmutable;
|
||||||
fn from_little_endian(self) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Macro for implementing a no-op endian conversion. This is used for types
|
fn to_little_endian(self) -> Self::Scalar;
|
||||||
/// that are one byte wide.
|
|
||||||
macro_rules! impl_endian_scalar_noop {
|
fn from_little_endian(v: Self::Scalar) -> Self;
|
||||||
($ty:ident) => {
|
|
||||||
impl EndianScalar for $ty {
|
|
||||||
#[inline]
|
|
||||||
fn to_little_endian(self) -> Self {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn from_little_endian(self) -> Self {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Macro for implementing an endian conversion using the stdlib `to_le` and
|
/// Macro for implementing an endian conversion using the stdlib `to_le` and
|
||||||
/// `from_le` functions. This is used for integer types. It is not used for
|
/// `from_le` functions. This is used for integer types. It is not used for
|
||||||
/// floats, because the `to_le` and `from_le` are not implemented for them in
|
/// floats, because the `to_le` and `from_le` are not implemented for them in
|
||||||
/// the stdlib.
|
/// the stdlib.
|
||||||
macro_rules! impl_endian_scalar_stdlib_le_conversion {
|
macro_rules! impl_endian_scalar {
|
||||||
($ty:ident) => {
|
($ty:ident) => {
|
||||||
impl EndianScalar for $ty {
|
impl EndianScalar for $ty {
|
||||||
|
type Scalar = Self;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_little_endian(self) -> Self {
|
fn to_little_endian(self) -> Self::Scalar {
|
||||||
Self::to_le(self)
|
Self::to_le(self)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_little_endian(self) -> Self {
|
fn from_little_endian(v: Self::Scalar) -> Self {
|
||||||
Self::from_le(self)
|
Self::from_le(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_endian_scalar_noop!(bool);
|
impl_endian_scalar!(u8);
|
||||||
impl_endian_scalar_noop!(u8);
|
impl_endian_scalar!(i8);
|
||||||
impl_endian_scalar_noop!(i8);
|
impl_endian_scalar!(u16);
|
||||||
|
impl_endian_scalar!(u32);
|
||||||
|
impl_endian_scalar!(u64);
|
||||||
|
impl_endian_scalar!(i16);
|
||||||
|
impl_endian_scalar!(i32);
|
||||||
|
impl_endian_scalar!(i64);
|
||||||
|
|
||||||
impl_endian_scalar_stdlib_le_conversion!(u16);
|
impl EndianScalar for bool {
|
||||||
impl_endian_scalar_stdlib_le_conversion!(u32);
|
type Scalar = u8;
|
||||||
impl_endian_scalar_stdlib_le_conversion!(u64);
|
|
||||||
impl_endian_scalar_stdlib_le_conversion!(i16);
|
fn to_little_endian(self) -> Self::Scalar {
|
||||||
impl_endian_scalar_stdlib_le_conversion!(i32);
|
self as u8
|
||||||
impl_endian_scalar_stdlib_le_conversion!(i64);
|
}
|
||||||
|
|
||||||
|
fn from_little_endian(v: Self::Scalar) -> Self {
|
||||||
|
v != 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl EndianScalar for f32 {
|
impl EndianScalar for f32 {
|
||||||
|
type Scalar = u32;
|
||||||
/// Convert f32 from host endian-ness to little-endian.
|
/// Convert f32 from host endian-ness to little-endian.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_little_endian(self) -> Self {
|
fn to_little_endian(self) -> u32 {
|
||||||
#[cfg(target_endian = "little")]
|
// Floats and Ints have the same endianness on all supported platforms.
|
||||||
{
|
// <https://doc.rust-lang.org/std/primitive.f32.html#method.from_bits>
|
||||||
self
|
self.to_bits().to_le()
|
||||||
}
|
|
||||||
#[cfg(not(target_endian = "little"))]
|
|
||||||
{
|
|
||||||
byte_swap_f32(self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/// Convert f32 from little-endian to host endian-ness.
|
/// Convert f32 from little-endian to host endian-ness.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_little_endian(self) -> Self {
|
fn from_little_endian(v: u32) -> Self {
|
||||||
#[cfg(target_endian = "little")]
|
// Floats and Ints have the same endianness on all supported platforms.
|
||||||
{
|
// <https://doc.rust-lang.org/std/primitive.f32.html#method.from_bits>
|
||||||
self
|
f32::from_bits(u32::from_le(v))
|
||||||
}
|
|
||||||
#[cfg(not(target_endian = "little"))]
|
|
||||||
{
|
|
||||||
byte_swap_f32(self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EndianScalar for f64 {
|
impl EndianScalar for f64 {
|
||||||
|
type Scalar = u64;
|
||||||
|
|
||||||
/// Convert f64 from host endian-ness to little-endian.
|
/// Convert f64 from host endian-ness to little-endian.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_little_endian(self) -> Self {
|
fn to_little_endian(self) -> u64 {
|
||||||
#[cfg(target_endian = "little")]
|
// Floats and Ints have the same endianness on all supported platforms.
|
||||||
{
|
// <https://doc.rust-lang.org/std/primitive.f64.html#method.from_bits>
|
||||||
self
|
self.to_bits().to_le()
|
||||||
}
|
|
||||||
#[cfg(not(target_endian = "little"))]
|
|
||||||
{
|
|
||||||
byte_swap_f64(self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/// Convert f64 from little-endian to host endian-ness.
|
/// Convert f64 from little-endian to host endian-ness.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_little_endian(self) -> Self {
|
fn from_little_endian(v: u64) -> Self {
|
||||||
#[cfg(target_endian = "little")]
|
// Floats and Ints have the same endianness on all supported platforms.
|
||||||
{
|
// <https://doc.rust-lang.org/std/primitive.f64.html#method.from_bits>
|
||||||
self
|
f64::from_bits(u64::from_le(v))
|
||||||
}
|
|
||||||
#[cfg(not(target_endian = "little"))]
|
|
||||||
{
|
|
||||||
byte_swap_f64(self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Swaps the bytes of an f32.
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[inline]
|
|
||||||
pub fn byte_swap_f32(x: f32) -> f32 {
|
|
||||||
f32::from_bits(x.to_bits().swap_bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Swaps the bytes of an f64.
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[inline]
|
|
||||||
pub fn byte_swap_f64(x: f64) -> f64 {
|
|
||||||
f64::from_bits(x.to_bits().swap_bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Place an EndianScalar into the provided mutable byte slice. Performs
|
/// Place an EndianScalar into the provided mutable byte slice. Performs
|
||||||
/// endian conversion, if necessary.
|
/// endian conversion, if necessary.
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// Caller must ensure `s.len() > size_of::<T>()`
|
/// Caller must ensure `s.len() >= size_of::<T>()`
|
||||||
/// and `x` does not overlap with `s`.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn emplace_scalar<T: EndianScalar>(s: &mut [u8], x: T) {
|
pub unsafe fn emplace_scalar<T: EndianScalar>(s: &mut [u8], x: T) {
|
||||||
|
let size = size_of::<T::Scalar>();
|
||||||
|
debug_assert!(
|
||||||
|
s.len() >= size,
|
||||||
|
"insufficient capacity for emplace_scalar, needed {} got {}",
|
||||||
|
size,
|
||||||
|
s.len()
|
||||||
|
);
|
||||||
|
|
||||||
let x_le = x.to_little_endian();
|
let x_le = x.to_little_endian();
|
||||||
core::ptr::copy_nonoverlapping(
|
core::ptr::copy_nonoverlapping(
|
||||||
&x_le as *const T as *const u8,
|
&x_le as *const T::Scalar as *const u8,
|
||||||
s.as_mut_ptr() as *mut u8,
|
s.as_mut_ptr() as *mut u8,
|
||||||
size_of::<T>(),
|
size,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read an EndianScalar from the provided byte slice at the specified location.
|
/// Read an EndianScalar from the provided byte slice at the specified location.
|
||||||
/// Performs endian conversion, if necessary.
|
/// Performs endian conversion, if necessary.
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// Caller must ensure `s.len() > loc + size_of::<T>()`.
|
/// Caller must ensure `s.len() >= loc + size_of::<T>()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn read_scalar_at<T: EndianScalar>(s: &[u8], loc: usize) -> T {
|
pub unsafe fn read_scalar_at<T: EndianScalar>(s: &[u8], loc: usize) -> T {
|
||||||
read_scalar(&s[loc..])
|
read_scalar(&s[loc..])
|
||||||
@@ -177,8 +169,20 @@ pub unsafe fn read_scalar_at<T: EndianScalar>(s: &[u8], loc: usize) -> T {
|
|||||||
/// Caller must ensure `s.len() > size_of::<T>()`.
|
/// Caller must ensure `s.len() > size_of::<T>()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn read_scalar<T: EndianScalar>(s: &[u8]) -> T {
|
pub unsafe fn read_scalar<T: EndianScalar>(s: &[u8]) -> T {
|
||||||
let mut mem = core::mem::MaybeUninit::<T>::uninit();
|
let size = size_of::<T::Scalar>();
|
||||||
|
debug_assert!(
|
||||||
|
s.len() >= size,
|
||||||
|
"insufficient capacity for emplace_scalar, needed {} got {}",
|
||||||
|
size,
|
||||||
|
s.len()
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut mem = core::mem::MaybeUninit::<T::Scalar>::uninit();
|
||||||
// Since [u8] has alignment 1, we copy it into T which may have higher alignment.
|
// Since [u8] has alignment 1, we copy it into T which may have higher alignment.
|
||||||
core::ptr::copy_nonoverlapping(s.as_ptr(), mem.as_mut_ptr() as *mut u8, size_of::<T>());
|
core::ptr::copy_nonoverlapping(
|
||||||
mem.assume_init().from_little_endian()
|
s.as_ptr(),
|
||||||
|
mem.as_mut_ptr() as *mut u8,
|
||||||
|
size,
|
||||||
|
);
|
||||||
|
T::from_little_endian(mem.assume_init())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,11 @@ use core::marker::PhantomData;
|
|||||||
/// continue traversing the FlatBuffer.
|
/// continue traversing the FlatBuffer.
|
||||||
pub trait Follow<'buf> {
|
pub trait Follow<'buf> {
|
||||||
type Inner;
|
type Inner;
|
||||||
fn follow(buf: &'buf [u8], loc: usize) -> Self::Inner;
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `buf[loc..]` must contain a valid value of `Self` and anything it
|
||||||
|
/// transitively refers to by offset must also be valid
|
||||||
|
unsafe fn follow(buf: &'buf [u8], loc: usize) -> Self::Inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FollowStart wraps a Follow impl in a struct type. This can make certain
|
/// FollowStart wraps a Follow impl in a struct type. This can make certain
|
||||||
@@ -39,17 +43,21 @@ pub struct FollowStart<T>(PhantomData<T>);
|
|||||||
impl<'a, T: Follow<'a> + 'a> FollowStart<T> {
|
impl<'a, T: Follow<'a> + 'a> FollowStart<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self { 0: PhantomData }
|
Self(PhantomData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `buf[loc..]` must contain a valid value of `T`
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn self_follow(&'a self, buf: &'a [u8], loc: usize) -> T::Inner {
|
pub unsafe fn self_follow(&'a self, buf: &'a [u8], loc: usize) -> T::Inner {
|
||||||
T::follow(buf, loc)
|
T::follow(buf, loc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a, T: Follow<'a>> Follow<'a> for FollowStart<T> {
|
impl<'a, T: Follow<'a>> Follow<'a> for FollowStart<T> {
|
||||||
type Inner = T::Inner;
|
type Inner = T::Inner;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
T::follow(buf, loc)
|
T::follow(buf, loc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ where
|
|||||||
{
|
{
|
||||||
let mut v = Verifier::new(opts, data);
|
let mut v = Verifier::new(opts, data);
|
||||||
<ForwardsUOffset<T>>::run_verifier(&mut v, 0)?;
|
<ForwardsUOffset<T>>::run_verifier(&mut v, 0)?;
|
||||||
|
// Safety:
|
||||||
|
// Run verifier above
|
||||||
Ok(unsafe { root_unchecked::<T>(data) })
|
Ok(unsafe { root_unchecked::<T>(data) })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +77,8 @@ where
|
|||||||
{
|
{
|
||||||
let mut v = Verifier::new(opts, data);
|
let mut v = Verifier::new(opts, data);
|
||||||
<SkipSizePrefix<ForwardsUOffset<T>>>::run_verifier(&mut v, 0)?;
|
<SkipSizePrefix<ForwardsUOffset<T>>>::run_verifier(&mut v, 0)?;
|
||||||
|
// Safety:
|
||||||
|
// Run verifier above
|
||||||
Ok(unsafe { size_prefixed_root_unchecked::<T>(data) })
|
Ok(unsafe { size_prefixed_root_unchecked::<T>(data) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,14 +48,12 @@ mod vtable_writer;
|
|||||||
|
|
||||||
pub use crate::array::{array_init, emplace_scalar_array, Array};
|
pub use crate::array::{array_init, emplace_scalar_array, Array};
|
||||||
pub use crate::builder::FlatBufferBuilder;
|
pub use crate::builder::FlatBufferBuilder;
|
||||||
pub use crate::endian_scalar::{
|
pub use crate::endian_scalar::{emplace_scalar, read_scalar, read_scalar_at, EndianScalar};
|
||||||
byte_swap_f32, byte_swap_f64, emplace_scalar, read_scalar, read_scalar_at, EndianScalar,
|
|
||||||
};
|
|
||||||
pub use crate::follow::{Follow, FollowStart};
|
pub use crate::follow::{Follow, FollowStart};
|
||||||
pub use crate::primitives::*;
|
pub use crate::primitives::*;
|
||||||
pub use crate::push::Push;
|
pub use crate::push::Push;
|
||||||
pub use crate::table::{buffer_has_identifier, Table};
|
pub use crate::table::{buffer_has_identifier, Table};
|
||||||
pub use crate::vector::{follow_cast_ref, SafeSliceAccess, Vector, VectorIter};
|
pub use crate::vector::{follow_cast_ref, Vector, VectorIter};
|
||||||
pub use crate::verifier::{
|
pub use crate::verifier::{
|
||||||
ErrorTraceDetail, InvalidFlatbuffer, SimpleToVerifyInSlice, Verifiable, Verifier,
|
ErrorTraceDetail, InvalidFlatbuffer, SimpleToVerifyInSlice, Verifiable, Verifier,
|
||||||
VerifierOptions,
|
VerifierOptions,
|
||||||
@@ -64,6 +62,4 @@ pub use crate::vtable::field_index_to_field_offset;
|
|||||||
pub use bitflags;
|
pub use bitflags;
|
||||||
pub use get_root::*;
|
pub use get_root::*;
|
||||||
|
|
||||||
// TODO(rw): Unify `create_vector` and `create_vector_direct` by using
|
|
||||||
// `Into<Vector<...>>`.
|
|
||||||
// TODO(rw): Split fill ops in builder into fill_small, fill_big like in C++.
|
// TODO(rw): Split fill ops in builder into fill_small, fill_big like in C++.
|
||||||
|
|||||||
@@ -112,10 +112,7 @@ impl<'a, T: 'a> WIPOffset<T> {
|
|||||||
/// Create a new WIPOffset.
|
/// Create a new WIPOffset.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(o: UOffsetT) -> WIPOffset<T> {
|
pub fn new(o: UOffsetT) -> WIPOffset<T> {
|
||||||
WIPOffset {
|
WIPOffset(o, PhantomData)
|
||||||
0: o,
|
|
||||||
1: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a wrapped value that brings its meaning as a union WIPOffset
|
/// Return a wrapped value that brings its meaning as a union WIPOffset
|
||||||
@@ -135,11 +132,9 @@ impl<T> Push for WIPOffset<T> {
|
|||||||
type Output = ForwardsUOffset<T>;
|
type Output = ForwardsUOffset<T>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn push(&self, dst: &mut [u8], rest: &[u8]) {
|
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
|
||||||
let n = (SIZE_UOFFSET + rest.len() - self.value() as usize) as UOffsetT;
|
let n = (SIZE_UOFFSET + written_len - self.value() as usize) as UOffsetT;
|
||||||
unsafe {
|
emplace_scalar::<UOffsetT>(dst, n);
|
||||||
emplace_scalar::<UOffsetT>(dst, n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,8 +142,8 @@ impl<T> Push for ForwardsUOffset<T> {
|
|||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn push(&self, dst: &mut [u8], rest: &[u8]) {
|
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
|
||||||
self.value().push(dst, rest);
|
self.value().push(dst, written_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,9 +174,9 @@ impl<T> ForwardsUOffset<T> {
|
|||||||
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsUOffset<T> {
|
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsUOffset<T> {
|
||||||
type Inner = T::Inner;
|
type Inner = T::Inner;
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
let slice = &buf[loc..loc + SIZE_UOFFSET];
|
let slice = &buf[loc..loc + SIZE_UOFFSET];
|
||||||
let off = unsafe { read_scalar::<u32>(slice) as usize };
|
let off = read_scalar::<u32>(slice) as usize;
|
||||||
T::follow(buf, loc + off)
|
T::follow(buf, loc + off)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,9 +195,9 @@ impl<T> ForwardsVOffset<T> {
|
|||||||
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsVOffset<T> {
|
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsVOffset<T> {
|
||||||
type Inner = T::Inner;
|
type Inner = T::Inner;
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
let slice = &buf[loc..loc + SIZE_VOFFSET];
|
let slice = &buf[loc..loc + SIZE_VOFFSET];
|
||||||
let off = unsafe { read_scalar::<VOffsetT>(slice) as usize };
|
let off = read_scalar::<VOffsetT>(slice) as usize;
|
||||||
T::follow(buf, loc + off)
|
T::follow(buf, loc + off)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,8 +206,8 @@ impl<T> Push for ForwardsVOffset<T> {
|
|||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn push(&self, dst: &mut [u8], rest: &[u8]) {
|
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
|
||||||
self.value().push(dst, rest);
|
self.value().push(dst, written_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,9 +225,9 @@ impl<T> BackwardsSOffset<T> {
|
|||||||
impl<'a, T: Follow<'a>> Follow<'a> for BackwardsSOffset<T> {
|
impl<'a, T: Follow<'a>> Follow<'a> for BackwardsSOffset<T> {
|
||||||
type Inner = T::Inner;
|
type Inner = T::Inner;
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
let slice = &buf[loc..loc + SIZE_SOFFSET];
|
let slice = &buf[loc..loc + SIZE_SOFFSET];
|
||||||
let off = unsafe { read_scalar::<SOffsetT>(slice) };
|
let off = read_scalar::<SOffsetT>(slice);
|
||||||
T::follow(buf, (loc as SOffsetT - off) as usize)
|
T::follow(buf, (loc as SOffsetT - off) as usize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,8 +236,8 @@ impl<T> Push for BackwardsSOffset<T> {
|
|||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn push(&self, dst: &mut [u8], rest: &[u8]) {
|
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
|
||||||
self.value().push(dst, rest);
|
self.value().push(dst, written_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,7 +247,7 @@ pub struct SkipSizePrefix<T>(PhantomData<T>);
|
|||||||
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipSizePrefix<T> {
|
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipSizePrefix<T> {
|
||||||
type Inner = T::Inner;
|
type Inner = T::Inner;
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
T::follow(buf, loc + SIZE_SIZEPREFIX)
|
T::follow(buf, loc + SIZE_SIZEPREFIX)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,7 +258,7 @@ pub struct SkipRootOffset<T>(PhantomData<T>);
|
|||||||
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipRootOffset<T> {
|
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipRootOffset<T> {
|
||||||
type Inner = T::Inner;
|
type Inner = T::Inner;
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
T::follow(buf, loc + SIZE_UOFFSET)
|
T::follow(buf, loc + SIZE_UOFFSET)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,7 +269,7 @@ pub struct FileIdentifier;
|
|||||||
impl<'a> Follow<'a> for FileIdentifier {
|
impl<'a> Follow<'a> for FileIdentifier {
|
||||||
type Inner = &'a [u8];
|
type Inner = &'a [u8];
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
&buf[loc..loc + FILE_IDENTIFIER_LENGTH]
|
&buf[loc..loc + FILE_IDENTIFIER_LENGTH]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -286,7 +281,7 @@ pub struct SkipFileIdentifier<T>(PhantomData<T>);
|
|||||||
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> {
|
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> {
|
||||||
type Inner = T::Inner;
|
type Inner = T::Inner;
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
T::follow(buf, loc + FILE_IDENTIFIER_LENGTH)
|
T::follow(buf, loc + FILE_IDENTIFIER_LENGTH)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,8 +289,8 @@ impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> {
|
|||||||
impl<'a> Follow<'a> for bool {
|
impl<'a> Follow<'a> for bool {
|
||||||
type Inner = bool;
|
type Inner = bool;
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
unsafe { read_scalar_at::<u8>(buf, loc) != 0 }
|
read_scalar_at::<u8>(buf, loc) != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,8 +304,8 @@ macro_rules! impl_follow_for_endian_scalar {
|
|||||||
impl<'a> Follow<'a> for $ty {
|
impl<'a> Follow<'a> for $ty {
|
||||||
type Inner = $ty;
|
type Inner = $ty;
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
unsafe { read_scalar_at::<$ty>(buf, loc) }
|
read_scalar_at::<$ty>(buf, loc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,11 @@ use crate::endian_scalar::emplace_scalar;
|
|||||||
/// types.
|
/// types.
|
||||||
pub trait Push: Sized {
|
pub trait Push: Sized {
|
||||||
type Output;
|
type Output;
|
||||||
fn push(&self, dst: &mut [u8], _rest: &[u8]);
|
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// dst is aligned to [`Self::alignment`] and has length greater than or equal to [`Self::size`]
|
||||||
|
unsafe fn push(&self, dst: &mut [u8], written_len: usize);
|
||||||
#[inline]
|
#[inline]
|
||||||
fn size() -> usize {
|
fn size() -> usize {
|
||||||
size_of::<Self::Output>()
|
size_of::<Self::Output>()
|
||||||
@@ -35,13 +39,29 @@ pub trait Push: Sized {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Push> Push for &'a T {
|
||||||
|
type Output = T::Output;
|
||||||
|
|
||||||
|
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
|
||||||
|
T::push(self, dst, written_len)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size() -> usize {
|
||||||
|
T::size()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alignment() -> PushAlignment {
|
||||||
|
T::alignment()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Ensure Push alignment calculations are typesafe (because this helps reduce
|
/// Ensure Push alignment calculations are typesafe (because this helps reduce
|
||||||
/// implementation issues when using FlatBufferBuilder::align).
|
/// implementation issues when using FlatBufferBuilder::align).
|
||||||
pub struct PushAlignment(usize);
|
pub struct PushAlignment(usize);
|
||||||
impl PushAlignment {
|
impl PushAlignment {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(x: usize) -> Self {
|
pub fn new(x: usize) -> Self {
|
||||||
PushAlignment { 0: x }
|
PushAlignment(x)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn value(&self) -> usize {
|
pub fn value(&self) -> usize {
|
||||||
@@ -60,10 +80,8 @@ macro_rules! impl_push_for_endian_scalar {
|
|||||||
type Output = $ty;
|
type Output = $ty;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
|
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||||
unsafe {
|
emplace_scalar::<$ty>(dst, *self);
|
||||||
emplace_scalar::<$ty>(dst, *self);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,23 +18,36 @@ use crate::follow::Follow;
|
|||||||
use crate::primitives::*;
|
use crate::primitives::*;
|
||||||
use crate::vtable::VTable;
|
use crate::vtable::VTable;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub struct Table<'a> {
|
pub struct Table<'a> {
|
||||||
pub buf: &'a [u8],
|
buf: &'a [u8],
|
||||||
pub loc: usize,
|
loc: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Table<'a> {
|
impl<'a> Table<'a> {
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `buf` must contain a `soffset_t` at `loc`, which points to a valid vtable
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(buf: &'a [u8], loc: usize) -> Self {
|
pub unsafe fn new(buf: &'a [u8], loc: usize) -> Self {
|
||||||
Table { buf, loc }
|
Table { buf, loc }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn vtable(&self) -> VTable<'a> {
|
pub fn vtable(&self) -> VTable<'a> {
|
||||||
<BackwardsSOffset<VTable<'a>>>::follow(self.buf, self.loc)
|
// Safety:
|
||||||
|
// Table::new is created with a valid buf and location
|
||||||
|
unsafe { <BackwardsSOffset<VTable<'a>>>::follow(self.buf, self.loc) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieves the value at the provided `slot_byte_loc` returning `default`
|
||||||
|
/// if no value present
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The value of the corresponding slot must have type T
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get<T: Follow<'a> + 'a>(
|
pub unsafe fn get<T: Follow<'a> + 'a>(
|
||||||
&self,
|
&self,
|
||||||
slot_byte_loc: VOffsetT,
|
slot_byte_loc: VOffsetT,
|
||||||
default: Option<T::Inner>,
|
default: Option<T::Inner>,
|
||||||
@@ -50,19 +63,26 @@ impl<'a> Table<'a> {
|
|||||||
impl<'a> Follow<'a> for Table<'a> {
|
impl<'a> Follow<'a> for Table<'a> {
|
||||||
type Inner = Table<'a>;
|
type Inner = Table<'a>;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
Table { buf, loc }
|
Table { buf, loc }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if data contains a prefix of `ident`
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn buffer_has_identifier(data: &[u8], ident: &str, size_prefixed: bool) -> bool {
|
pub fn buffer_has_identifier(data: &[u8], ident: &str, size_prefixed: bool) -> bool {
|
||||||
assert_eq!(ident.len(), FILE_IDENTIFIER_LENGTH);
|
assert_eq!(ident.len(), FILE_IDENTIFIER_LENGTH);
|
||||||
|
|
||||||
let got = if size_prefixed {
|
let got = if size_prefixed {
|
||||||
<SkipSizePrefix<SkipRootOffset<FileIdentifier>>>::follow(data, 0)
|
assert!(data.len() >= SIZE_SIZEPREFIX + SIZE_UOFFSET + FILE_IDENTIFIER_LENGTH);
|
||||||
|
// Safety:
|
||||||
|
// Verified data has sufficient bytes
|
||||||
|
unsafe { <SkipSizePrefix<SkipRootOffset<FileIdentifier>>>::follow(data, 0) }
|
||||||
} else {
|
} else {
|
||||||
<SkipRootOffset<FileIdentifier>>::follow(data, 0)
|
assert!(data.len() >= SIZE_UOFFSET + FILE_IDENTIFIER_LENGTH);
|
||||||
|
// Safety:
|
||||||
|
// Verified data has sufficient bytes
|
||||||
|
unsafe { <SkipRootOffset<FileIdentifier>>::follow(data, 0) }
|
||||||
};
|
};
|
||||||
|
|
||||||
ident.as_bytes() == got
|
ident.as_bytes() == got
|
||||||
|
|||||||
@@ -17,13 +17,10 @@
|
|||||||
use core::fmt::{Debug, Formatter, Result};
|
use core::fmt::{Debug, Formatter, Result};
|
||||||
use core::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
|
use core::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::mem::size_of;
|
use core::mem::{align_of, size_of};
|
||||||
use core::slice::from_raw_parts;
|
|
||||||
use core::str::from_utf8_unchecked;
|
use core::str::from_utf8_unchecked;
|
||||||
|
|
||||||
use crate::endian_scalar::read_scalar_at;
|
use crate::endian_scalar::read_scalar_at;
|
||||||
#[cfg(target_endian = "little")]
|
|
||||||
use crate::endian_scalar::EndianScalar;
|
|
||||||
use crate::follow::Follow;
|
use crate::follow::Follow;
|
||||||
use crate::primitives::*;
|
use crate::primitives::*;
|
||||||
|
|
||||||
@@ -55,6 +52,7 @@ where
|
|||||||
// and Clone for `T: Copy` and `T: Clone` respectively. However `Vector<'a, T>`
|
// and Clone for `T: Copy` and `T: Clone` respectively. However `Vector<'a, T>`
|
||||||
// can always be copied, no matter that `T` you have.
|
// can always be copied, no matter that `T` you have.
|
||||||
impl<'a, T> Copy for Vector<'a, T> {}
|
impl<'a, T> Copy for Vector<'a, T> {}
|
||||||
|
|
||||||
impl<'a, T> Clone for Vector<'a, T> {
|
impl<'a, T> Clone for Vector<'a, T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
*self
|
*self
|
||||||
@@ -62,32 +60,46 @@ impl<'a, T> Clone for Vector<'a, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: 'a> Vector<'a, T> {
|
impl<'a, T: 'a> Vector<'a, T> {
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// `buf` contains a valid vector at `loc` consisting of
|
||||||
|
///
|
||||||
|
/// - UOffsetT element count
|
||||||
|
/// - Consecutive list of `T` elements
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(buf: &'a [u8], loc: usize) -> Self {
|
pub unsafe fn new(buf: &'a [u8], loc: usize) -> Self {
|
||||||
Vector {
|
Vector(buf, loc, PhantomData)
|
||||||
0: buf,
|
|
||||||
1: loc,
|
|
||||||
2: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
|
// Safety:
|
||||||
|
// Valid vector at time of construction starting with UOffsetT element count
|
||||||
unsafe { read_scalar_at::<UOffsetT>(self.0, self.1) as usize }
|
unsafe { read_scalar_at::<UOffsetT>(self.0, self.1) as usize }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.len() == 0
|
self.len() == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn bytes(&self) -> &'a [u8] {
|
||||||
|
let sz = size_of::<T>();
|
||||||
|
let len = self.len();
|
||||||
|
&self.0[self.1 + SIZE_UOFFSET..self.1 + SIZE_UOFFSET + sz * len]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
|
impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get(&self, idx: usize) -> T::Inner {
|
pub fn get(&self, idx: usize) -> T::Inner {
|
||||||
assert!(idx < self.len() as usize);
|
assert!(idx < self.len());
|
||||||
let sz = size_of::<T>();
|
let sz = size_of::<T>();
|
||||||
debug_assert!(sz > 0);
|
debug_assert!(sz > 0);
|
||||||
T::follow(self.0, self.1 as usize + SIZE_UOFFSET + sz * idx)
|
// Safety:
|
||||||
|
// Valid vector at time of construction, verified that idx < element count
|
||||||
|
unsafe { T::follow(self.0, self.1 as usize + SIZE_UOFFSET + sz * idx) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -96,84 +108,40 @@ impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SafeSliceAccess {}
|
/// # Safety
|
||||||
impl<'a, T: SafeSliceAccess + 'a> Vector<'a, T> {
|
///
|
||||||
pub fn safe_slice(self) -> &'a [T] {
|
/// `buf` must contain a value of T at `loc` and have alignment of 1
|
||||||
let buf = self.0;
|
pub unsafe fn follow_cast_ref<'a, T: Sized + 'a>(buf: &'a [u8], loc: usize) -> &'a T {
|
||||||
let loc = self.1;
|
assert_eq!(align_of::<T>(), 1);
|
||||||
let sz = size_of::<T>();
|
|
||||||
debug_assert!(sz > 0);
|
|
||||||
let len = unsafe { read_scalar_at::<UOffsetT>(buf, loc) } as usize;
|
|
||||||
let data_buf = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len * sz];
|
|
||||||
let ptr = data_buf.as_ptr() as *const T;
|
|
||||||
let s: &'a [T] = unsafe { from_raw_parts(ptr, len) };
|
|
||||||
s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SafeSliceAccess for u8 {}
|
|
||||||
impl SafeSliceAccess for i8 {}
|
|
||||||
impl SafeSliceAccess for bool {}
|
|
||||||
|
|
||||||
// TODO(caspern): Get rid of this. Conditional compliation is unnecessary complexity.
|
|
||||||
// Vectors of primitives just don't work on big endian machines!!!
|
|
||||||
#[cfg(target_endian = "little")]
|
|
||||||
mod le_safe_slice_impls {
|
|
||||||
impl super::SafeSliceAccess for u16 {}
|
|
||||||
impl super::SafeSliceAccess for u32 {}
|
|
||||||
impl super::SafeSliceAccess for u64 {}
|
|
||||||
|
|
||||||
impl super::SafeSliceAccess for i16 {}
|
|
||||||
impl super::SafeSliceAccess for i32 {}
|
|
||||||
impl super::SafeSliceAccess for i64 {}
|
|
||||||
|
|
||||||
impl super::SafeSliceAccess for f32 {}
|
|
||||||
impl super::SafeSliceAccess for f64 {}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_endian = "little")]
|
|
||||||
pub use self::le_safe_slice_impls::*;
|
|
||||||
|
|
||||||
pub fn follow_cast_ref<'a, T: Sized + 'a>(buf: &'a [u8], loc: usize) -> &'a T {
|
|
||||||
let sz = size_of::<T>();
|
let sz = size_of::<T>();
|
||||||
let buf = &buf[loc..loc + sz];
|
let buf = &buf[loc..loc + sz];
|
||||||
let ptr = buf.as_ptr() as *const T;
|
let ptr = buf.as_ptr() as *const T;
|
||||||
unsafe { &*ptr }
|
// SAFETY
|
||||||
|
// buf contains a value at loc of type T and T has no alignment requirements
|
||||||
|
&*ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Follow<'a> for &'a str {
|
impl<'a> Follow<'a> for &'a str {
|
||||||
type Inner = &'a str;
|
type Inner = &'a str;
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
let len = unsafe { read_scalar_at::<UOffsetT>(buf, loc) } as usize;
|
let len = read_scalar_at::<UOffsetT>(buf, loc) as usize;
|
||||||
let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len];
|
let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len];
|
||||||
unsafe { from_utf8_unchecked(slice) }
|
from_utf8_unchecked(slice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_endian = "little")]
|
impl<'a> Follow<'a> for &'a [u8] {
|
||||||
fn follow_slice_helper<T>(buf: &[u8], loc: usize) -> &[T] {
|
type Inner = &'a [u8];
|
||||||
let sz = size_of::<T>();
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
debug_assert!(sz > 0);
|
let len = read_scalar_at::<UOffsetT>(buf, loc) as usize;
|
||||||
let len = unsafe { read_scalar_at::<UOffsetT>(buf, loc) as usize };
|
&buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len]
|
||||||
let data_buf = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len * sz];
|
|
||||||
let ptr = data_buf.as_ptr() as *const T;
|
|
||||||
let s: &[T] = unsafe { from_raw_parts(ptr, len) };
|
|
||||||
s
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implement direct slice access if the host is little-endian.
|
|
||||||
#[cfg(target_endian = "little")]
|
|
||||||
impl<'a, T: EndianScalar> Follow<'a> for &'a [T] {
|
|
||||||
type Inner = &'a [T];
|
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
|
||||||
follow_slice_helper::<T>(buf, loc)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implement Follow for all possible Vectors that have Follow-able elements.
|
/// Implement Follow for all possible Vectors that have Follow-able elements.
|
||||||
impl<'a, T: Follow<'a> + 'a> Follow<'a> for Vector<'a, T> {
|
impl<'a, T: Follow<'a> + 'a> Follow<'a> for Vector<'a, T> {
|
||||||
type Inner = Vector<'a, T>;
|
type Inner = Vector<'a, T>;
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
Vector::new(buf, loc)
|
Vector::new(buf, loc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,8 +169,14 @@ impl<'a, T: 'a> VectorIter<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new `VectorIter` from the provided slice
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// buf must contain a contiguous sequence of `items_num` values of `T`
|
||||||
|
///
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice(buf: &'a [u8], items_num: usize) -> Self {
|
pub unsafe fn from_slice(buf: &'a [u8], items_num: usize) -> Self {
|
||||||
VectorIter {
|
VectorIter {
|
||||||
buf,
|
buf,
|
||||||
loc: 0,
|
loc: 0,
|
||||||
@@ -235,7 +209,10 @@ impl<'a, T: Follow<'a> + 'a> Iterator for VectorIter<'a, T> {
|
|||||||
if self.remaining == 0 {
|
if self.remaining == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let result = T::follow(self.buf, self.loc);
|
// Safety:
|
||||||
|
// VectorIter can only be created from a contiguous sequence of `items_num`
|
||||||
|
// And remaining is initialized to `items_num`
|
||||||
|
let result = unsafe { T::follow(self.buf, self.loc) };
|
||||||
self.loc += sz;
|
self.loc += sz;
|
||||||
self.remaining -= 1;
|
self.remaining -= 1;
|
||||||
Some(result)
|
Some(result)
|
||||||
@@ -272,7 +249,10 @@ impl<'a, T: Follow<'a> + 'a> DoubleEndedIterator for VectorIter<'a, T> {
|
|||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
self.remaining -= 1;
|
self.remaining -= 1;
|
||||||
Some(T::follow(self.buf, self.loc + sz * self.remaining))
|
// Safety:
|
||||||
|
// VectorIter can only be created from a contiguous sequence of `items_num`
|
||||||
|
// And remaining is initialized to `items_num`
|
||||||
|
Some(unsafe { T::follow(self.buf, self.loc + sz * self.remaining) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +289,7 @@ impl<'a, 'b, T: Follow<'a> + 'a> IntoIterator for &'b Vector<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="serialize")]
|
#[cfg(feature = "serialize")]
|
||||||
impl<'a, T> serde::ser::Serialize for Vector<'a, T>
|
impl<'a, T> serde::ser::Serialize for Vector<'a, T>
|
||||||
where
|
where
|
||||||
T: 'a + Follow<'a>,
|
T: 'a + Follow<'a>,
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
|
use crate::follow::Follow;
|
||||||
|
use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::ops::Range;
|
use core::ops::Range;
|
||||||
use core::option::Option;
|
use core::option::Option;
|
||||||
use crate::follow::Follow;
|
|
||||||
use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
|
|
||||||
|
|
||||||
#[cfg(feature="no_std")]
|
#[cfg(not(feature = "no_std"))]
|
||||||
use thiserror_core2::Error;
|
|
||||||
#[cfg(not(feature="no_std"))]
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use thiserror_core2::Error;
|
||||||
|
|
||||||
/// Traces the location of data errors. Not populated for Dos detecting errors.
|
/// Traces the location of data errors. Not populated for Dos detecting errors.
|
||||||
/// Useful for MissingRequiredField and Utf8Error in particular, though
|
/// Useful for MissingRequiredField and Utf8Error in particular, though
|
||||||
@@ -28,8 +28,10 @@ pub enum ErrorTraceDetail {
|
|||||||
position: usize,
|
position: usize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Default, Debug, Clone)]
|
#[derive(PartialEq, Eq, Default, Debug, Clone)]
|
||||||
pub struct ErrorTrace(Vec<ErrorTraceDetail>);
|
pub struct ErrorTrace(Vec<ErrorTraceDetail>);
|
||||||
|
|
||||||
impl core::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {
|
impl core::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_ref(&self) -> &[ErrorTraceDetail] {
|
fn as_ref(&self) -> &[ErrorTraceDetail] {
|
||||||
@@ -63,7 +65,7 @@ pub enum InvalidFlatbuffer {
|
|||||||
error_trace: ErrorTrace,
|
error_trace: ErrorTrace,
|
||||||
},
|
},
|
||||||
#[error("String in range [{}, {}) is missing its null terminator.\n{error_trace}",
|
#[error("String in range [{}, {}) is missing its null terminator.\n{error_trace}",
|
||||||
range.start, range.end)]
|
range.start, range.end)]
|
||||||
MissingNullTerminator {
|
MissingNullTerminator {
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
error_trace: ErrorTrace,
|
error_trace: ErrorTrace,
|
||||||
@@ -184,6 +186,7 @@ fn trace_field<T>(res: Result<T>, field_name: &'static str, position: usize) ->
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a TableField trace detail if `res` is a data error.
|
/// Adds a TableField trace detail if `res` is a data error.
|
||||||
fn trace_elem<T>(res: Result<T>, index: usize, position: usize) -> Result<T> {
|
fn trace_elem<T>(res: Result<T>, index: usize, position: usize) -> Result<T> {
|
||||||
append_trace(res, ErrorTraceDetail::VectorElement { index, position })
|
append_trace(res, ErrorTraceDetail::VectorElement { index, position })
|
||||||
@@ -205,6 +208,7 @@ pub struct VerifierOptions {
|
|||||||
// options to error un-recognized enums and unions? possible footgun.
|
// options to error un-recognized enums and unions? possible footgun.
|
||||||
// Ignore nested flatbuffers, etc?
|
// Ignore nested flatbuffers, etc?
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for VerifierOptions {
|
impl Default for VerifierOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -226,6 +230,7 @@ pub struct Verifier<'opts, 'buf> {
|
|||||||
num_tables: usize,
|
num_tables: usize,
|
||||||
apparent_size: usize,
|
apparent_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'opts, 'buf> Verifier<'opts, 'buf> {
|
impl<'opts, 'buf> Verifier<'opts, 'buf> {
|
||||||
pub fn new(opts: &'opts VerifierOptions, buffer: &'buf [u8]) -> Self {
|
pub fn new(opts: &'opts VerifierOptions, buffer: &'buf [u8]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -247,9 +252,12 @@ impl<'opts, 'buf> Verifier<'opts, 'buf> {
|
|||||||
/// memory since `buffer: &[u8]` has alignment 1.
|
/// memory since `buffer: &[u8]` has alignment 1.
|
||||||
///
|
///
|
||||||
/// ### WARNING
|
/// ### WARNING
|
||||||
|
///
|
||||||
/// This does not work for flatbuffers-structs as they have alignment 1 according to
|
/// This does not work for flatbuffers-structs as they have alignment 1 according to
|
||||||
/// `core::mem::align_of` but are meant to have higher alignment within a Flatbuffer w.r.t.
|
/// `core::mem::align_of` but are meant to have higher alignment within a Flatbuffer w.r.t.
|
||||||
/// `buffer[0]`. TODO(caspern).
|
/// `buffer[0]`. TODO(caspern).
|
||||||
|
///
|
||||||
|
/// Note this does not impact soundness as this crate does not assume alignment of structs
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_aligned<T>(&self, pos: usize) -> Result<()> {
|
fn is_aligned<T>(&self, pos: usize) -> Result<()> {
|
||||||
if pos % core::mem::align_of::<T>() == 0 {
|
if pos % core::mem::align_of::<T>() == 0 {
|
||||||
@@ -307,9 +315,9 @@ impl<'opts, 'buf> Verifier<'opts, 'buf> {
|
|||||||
|
|
||||||
// signed offsets are subtracted.
|
// signed offsets are subtracted.
|
||||||
let derefed = if offset > 0 {
|
let derefed = if offset > 0 {
|
||||||
pos.checked_sub(offset.abs() as usize)
|
pos.checked_sub(offset.unsigned_abs() as usize)
|
||||||
} else {
|
} else {
|
||||||
pos.checked_add(offset.abs() as usize)
|
pos.checked_add(offset.unsigned_abs() as usize)
|
||||||
};
|
};
|
||||||
if let Some(x) = derefed {
|
if let Some(x) = derefed {
|
||||||
if x < self.buffer.len() {
|
if x < self.buffer.len() {
|
||||||
@@ -372,6 +380,7 @@ pub struct TableVerifier<'ver, 'opts, 'buf> {
|
|||||||
// Verifier struct which holds the surrounding state and options.
|
// Verifier struct which holds the surrounding state and options.
|
||||||
verifier: &'ver mut Verifier<'opts, 'buf>,
|
verifier: &'ver mut Verifier<'opts, 'buf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> {
|
impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> {
|
||||||
fn deref(&mut self, field: VOffsetT) -> Result<Option<usize>> {
|
fn deref(&mut self, field: VOffsetT) -> Result<Option<usize>> {
|
||||||
let field = field as usize;
|
let field = field as usize;
|
||||||
@@ -439,7 +448,9 @@ impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> {
|
|||||||
}
|
}
|
||||||
(Some(k), Some(v)) => {
|
(Some(k), Some(v)) => {
|
||||||
trace_field(Key::run_verifier(self.verifier, k), key_field_name, k)?;
|
trace_field(Key::run_verifier(self.verifier, k), key_field_name, k)?;
|
||||||
let discriminant = Key::follow(self.verifier.buffer, k);
|
// Safety:
|
||||||
|
// Run verifier on `k` above
|
||||||
|
let discriminant = unsafe { Key::follow(self.verifier.buffer, k) };
|
||||||
trace_field(
|
trace_field(
|
||||||
verify_union(discriminant, self.verifier, v),
|
verify_union(discriminant, self.verifier, v),
|
||||||
val_field_name,
|
val_field_name,
|
||||||
@@ -486,16 +497,27 @@ fn verify_vector_range<T>(v: &mut Verifier, pos: usize) -> Result<core::ops::Ran
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait SimpleToVerifyInSlice {}
|
pub trait SimpleToVerifyInSlice {}
|
||||||
|
|
||||||
impl SimpleToVerifyInSlice for bool {}
|
impl SimpleToVerifyInSlice for bool {}
|
||||||
|
|
||||||
impl SimpleToVerifyInSlice for i8 {}
|
impl SimpleToVerifyInSlice for i8 {}
|
||||||
|
|
||||||
impl SimpleToVerifyInSlice for u8 {}
|
impl SimpleToVerifyInSlice for u8 {}
|
||||||
|
|
||||||
impl SimpleToVerifyInSlice for i16 {}
|
impl SimpleToVerifyInSlice for i16 {}
|
||||||
|
|
||||||
impl SimpleToVerifyInSlice for u16 {}
|
impl SimpleToVerifyInSlice for u16 {}
|
||||||
|
|
||||||
impl SimpleToVerifyInSlice for i32 {}
|
impl SimpleToVerifyInSlice for i32 {}
|
||||||
|
|
||||||
impl SimpleToVerifyInSlice for u32 {}
|
impl SimpleToVerifyInSlice for u32 {}
|
||||||
|
|
||||||
impl SimpleToVerifyInSlice for f32 {}
|
impl SimpleToVerifyInSlice for f32 {}
|
||||||
|
|
||||||
impl SimpleToVerifyInSlice for i64 {}
|
impl SimpleToVerifyInSlice for i64 {}
|
||||||
|
|
||||||
impl SimpleToVerifyInSlice for u64 {}
|
impl SimpleToVerifyInSlice for u64 {}
|
||||||
|
|
||||||
impl SimpleToVerifyInSlice for f64 {}
|
impl SimpleToVerifyInSlice for f64 {}
|
||||||
|
|
||||||
impl<T: SimpleToVerifyInSlice> Verifiable for Vector<'_, T> {
|
impl<T: SimpleToVerifyInSlice> Verifiable for Vector<'_, T> {
|
||||||
|
|||||||
@@ -33,24 +33,42 @@ impl<'a> PartialEq for VTable<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VTable<'a> {
|
impl<'a> VTable<'a> {
|
||||||
pub fn init(buf: &'a [u8], loc: usize) -> Self {
|
/// SAFETY
|
||||||
|
/// `buf` must contain a valid vtable at `loc`
|
||||||
|
///
|
||||||
|
/// This consists of a number of `VOffsetT`
|
||||||
|
/// - size of vtable in bytes including size element
|
||||||
|
/// - size of object in bytes including the vtable offset
|
||||||
|
/// - n fields where n is the number of fields in the table's schema when the code was compiled
|
||||||
|
pub unsafe fn init(buf: &'a [u8], loc: usize) -> Self {
|
||||||
VTable { buf, loc }
|
VTable { buf, loc }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_fields(&self) -> usize {
|
pub fn num_fields(&self) -> usize {
|
||||||
(self.num_bytes() / SIZE_VOFFSET) - 2
|
(self.num_bytes() / SIZE_VOFFSET) - 2
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_bytes(&self) -> usize {
|
pub fn num_bytes(&self) -> usize {
|
||||||
|
// Safety:
|
||||||
|
// Valid VTable at time of construction
|
||||||
unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc) as usize }
|
unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc) as usize }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn object_inline_num_bytes(&self) -> usize {
|
pub fn object_inline_num_bytes(&self) -> usize {
|
||||||
|
// Safety:
|
||||||
|
// Valid VTable at time of construction
|
||||||
let n = unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc + SIZE_VOFFSET) };
|
let n = unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc + SIZE_VOFFSET) };
|
||||||
n as usize
|
n as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_field(&self, idx: usize) -> VOffsetT {
|
pub fn get_field(&self, idx: usize) -> VOffsetT {
|
||||||
// TODO(rw): distinguish between None and 0?
|
// TODO(rw): distinguish between None and 0?
|
||||||
if idx > self.num_fields() {
|
if idx > self.num_fields() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Safety:
|
||||||
|
// Valid VTable at time of construction
|
||||||
unsafe {
|
unsafe {
|
||||||
read_scalar_at::<VOffsetT>(
|
read_scalar_at::<VOffsetT>(
|
||||||
self.buf,
|
self.buf,
|
||||||
@@ -58,13 +76,17 @@ impl<'a> VTable<'a> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, byte_loc: VOffsetT) -> VOffsetT {
|
pub fn get(&self, byte_loc: VOffsetT) -> VOffsetT {
|
||||||
// TODO(rw): distinguish between None and 0?
|
// TODO(rw): distinguish between None and 0?
|
||||||
if byte_loc as usize >= self.num_bytes() {
|
if byte_loc as usize + 2 > self.num_bytes() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
// Safety:
|
||||||
|
// byte_loc is within bounds of vtable, which was valid at time of construction
|
||||||
unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc + byte_loc as usize) }
|
unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc + byte_loc as usize) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_bytes(&self) -> &[u8] {
|
pub fn as_bytes(&self) -> &[u8] {
|
||||||
let len = self.num_bytes();
|
let len = self.num_bytes();
|
||||||
&self.buf[self.loc..self.loc + len]
|
&self.buf[self.loc..self.loc + len]
|
||||||
@@ -87,7 +109,7 @@ pub fn field_offset_to_field_index(field_o: VOffsetT) -> VOffsetT {
|
|||||||
|
|
||||||
impl<'a> Follow<'a> for VTable<'a> {
|
impl<'a> Follow<'a> for VTable<'a> {
|
||||||
type Inner = VTable<'a>;
|
type Inner = VTable<'a>;
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
VTable::init(buf, loc)
|
VTable::init(buf, loc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,11 @@ impl<'a> VTableWriter<'a> {
|
|||||||
/// to the provided value.
|
/// to the provided value.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn write_vtable_byte_length(&mut self, n: VOffsetT) {
|
pub fn write_vtable_byte_length(&mut self, n: VOffsetT) {
|
||||||
|
let buf = &mut self.buf[..SIZE_VOFFSET];
|
||||||
|
// Safety:
|
||||||
|
// Validated range above
|
||||||
unsafe {
|
unsafe {
|
||||||
emplace_scalar::<VOffsetT>(&mut self.buf[..SIZE_VOFFSET], n);
|
emplace_scalar::<VOffsetT>(buf, n);
|
||||||
}
|
}
|
||||||
debug_assert_eq!(n as usize, self.buf.len());
|
debug_assert_eq!(n as usize, self.buf.len());
|
||||||
}
|
}
|
||||||
@@ -49,8 +52,11 @@ impl<'a> VTableWriter<'a> {
|
|||||||
/// Writes an object length (in bytes) into the vtable.
|
/// Writes an object length (in bytes) into the vtable.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn write_object_inline_size(&mut self, n: VOffsetT) {
|
pub fn write_object_inline_size(&mut self, n: VOffsetT) {
|
||||||
|
let buf = &mut self.buf[SIZE_VOFFSET..2 * SIZE_VOFFSET];
|
||||||
|
// Safety:
|
||||||
|
// Validated range above
|
||||||
unsafe {
|
unsafe {
|
||||||
emplace_scalar::<VOffsetT>(&mut self.buf[SIZE_VOFFSET..2 * SIZE_VOFFSET], n);
|
emplace_scalar::<VOffsetT>(buf, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,8 +67,11 @@ impl<'a> VTableWriter<'a> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn write_field_offset(&mut self, vtable_offset: VOffsetT, object_data_offset: VOffsetT) {
|
pub fn write_field_offset(&mut self, vtable_offset: VOffsetT, object_data_offset: VOffsetT) {
|
||||||
let idx = vtable_offset as usize;
|
let idx = vtable_offset as usize;
|
||||||
|
let buf = &mut self.buf[idx..idx + SIZE_VOFFSET];
|
||||||
|
// Safety:
|
||||||
|
// Validated range above
|
||||||
unsafe {
|
unsafe {
|
||||||
emplace_scalar::<VOffsetT>(&mut self.buf[idx..idx + SIZE_VOFFSET], object_data_offset);
|
emplace_scalar::<VOffsetT>(buf, object_data_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,6 +82,9 @@ impl<'a> VTableWriter<'a> {
|
|||||||
// This is the closest thing to memset in Rust right now.
|
// This is the closest thing to memset in Rust right now.
|
||||||
let len = self.buf.len();
|
let len = self.buf.len();
|
||||||
let p = self.buf.as_mut_ptr() as *mut u8;
|
let p = self.buf.as_mut_ptr() as *mut u8;
|
||||||
|
|
||||||
|
// Safety:
|
||||||
|
// p is byte aligned and of length `len`
|
||||||
unsafe {
|
unsafe {
|
||||||
write_bytes(p, 0, len);
|
write_bytes(p, 0, len);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
// Ensure the included flatbuffers.h is the same version as when this file was
|
// Ensure the included flatbuffers.h is the same version as when this file was
|
||||||
// generated, otherwise it may not be compatible.
|
// generated, otherwise it may not be compatible.
|
||||||
static_assert(FLATBUFFERS_VERSION_MAJOR == 2 &&
|
static_assert(FLATBUFFERS_VERSION_MAJOR == 22 &&
|
||||||
FLATBUFFERS_VERSION_MINOR == 0 &&
|
FLATBUFFERS_VERSION_MINOR == 9 &&
|
||||||
FLATBUFFERS_VERSION_REVISION == 8,
|
FLATBUFFERS_VERSION_REVISION == 29,
|
||||||
"Non-compatible flatbuffers version included");
|
"Non-compatible flatbuffers version included");
|
||||||
|
|
||||||
namespace MyGame {
|
namespace MyGame {
|
||||||
@@ -607,10 +607,10 @@ inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function
|
|||||||
{ auto _e = name(); if (_e) _o->name = _e->str(); }
|
{ auto _e = name(); if (_e) _o->name = _e->str(); }
|
||||||
{ auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->inventory.begin()); } }
|
{ auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); std::copy(_e->begin(), _e->end(), _o->inventory.begin()); } }
|
||||||
{ auto _e = color(); _o->color = _e; }
|
{ auto _e = color(); _o->color = _e; }
|
||||||
{ auto _e = weapons(); if (_e) { _o->weapons.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons[_i] = flatbuffers::unique_ptr<MyGame::Sample::WeaponT>(_e->Get(_i)->UnPack(_resolver)); } } }
|
{ auto _e = weapons(); if (_e) { _o->weapons.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { if(_o->weapons[_i]) { _e->Get(_i)->UnPackTo(_o->weapons[_i].get(), _resolver); } else { _o->weapons[_i] = flatbuffers::unique_ptr<MyGame::Sample::WeaponT>(_e->Get(_i)->UnPack(_resolver)); }; } } else { _o->weapons.resize(0); } }
|
||||||
{ auto _e = equipped_type(); _o->equipped.type = _e; }
|
{ auto _e = equipped_type(); _o->equipped.type = _e; }
|
||||||
{ auto _e = equipped(); if (_e) _o->equipped.value = MyGame::Sample::EquipmentUnion::UnPack(_e, equipped_type(), _resolver); }
|
{ auto _e = equipped(); if (_e) _o->equipped.value = MyGame::Sample::EquipmentUnion::UnPack(_e, equipped_type(), _resolver); }
|
||||||
{ auto _e = path(); if (_e) { _o->path.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->path[_i] = *_e->Get(_i); } } }
|
{ auto _e = path(); if (_e) { _o->path.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->path[_i] = *_e->Get(_i); } } else { _o->path.resize(0); } }
|
||||||
}
|
}
|
||||||
|
|
||||||
inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
|
inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public enum MyGame_Sample_Equipment: UInt8, Enum {
|
|||||||
|
|
||||||
public struct MyGame_Sample_Vec3: NativeStruct {
|
public struct MyGame_Sample_Vec3: NativeStruct {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_2_0_8() }
|
static func validateVersion() { FlatBuffersVersion_22_9_29() }
|
||||||
|
|
||||||
private var _x: Float32
|
private var _x: Float32
|
||||||
private var _y: Float32
|
private var _y: Float32
|
||||||
@@ -56,7 +56,7 @@ public struct MyGame_Sample_Vec3: NativeStruct {
|
|||||||
|
|
||||||
public struct MyGame_Sample_Vec3_Mutable: FlatBufferObject {
|
public struct MyGame_Sample_Vec3_Mutable: FlatBufferObject {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_2_0_8() }
|
static func validateVersion() { FlatBuffersVersion_22_9_29() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
private var _accessor: Struct
|
private var _accessor: Struct
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ public struct MyGame_Sample_Vec3_Mutable: FlatBufferObject {
|
|||||||
|
|
||||||
public struct MyGame_Sample_Monster: FlatBufferObject {
|
public struct MyGame_Sample_Monster: FlatBufferObject {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_2_0_8() }
|
static func validateVersion() { FlatBuffersVersion_22_9_29() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
private var _accessor: Table
|
private var _accessor: Table
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ public struct MyGame_Sample_Monster: FlatBufferObject {
|
|||||||
|
|
||||||
public struct MyGame_Sample_Weapon: FlatBufferObject {
|
public struct MyGame_Sample_Weapon: FlatBufferObject {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_2_0_8() }
|
static func validateVersion() { FlatBuffersVersion_22_9_29() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
private var _accessor: Table
|
private var _accessor: Table
|
||||||
|
|
||||||
|
|||||||
@@ -59,10 +59,8 @@ impl core::fmt::Debug for Color {
|
|||||||
impl<'a> flatbuffers::Follow<'a> for Color {
|
impl<'a> flatbuffers::Follow<'a> for Color {
|
||||||
type Inner = Self;
|
type Inner = Self;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
let b = unsafe {
|
let b = flatbuffers::read_scalar_at::<i8>(buf, loc);
|
||||||
flatbuffers::read_scalar_at::<i8>(buf, loc)
|
|
||||||
};
|
|
||||||
Self(b)
|
Self(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,21 +68,21 @@ impl<'a> flatbuffers::Follow<'a> for Color {
|
|||||||
impl flatbuffers::Push for Color {
|
impl flatbuffers::Push for Color {
|
||||||
type Output = Color;
|
type Output = Color;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
|
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||||
unsafe { flatbuffers::emplace_scalar::<i8>(dst, self.0); }
|
flatbuffers::emplace_scalar::<i8>(dst, self.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl flatbuffers::EndianScalar for Color {
|
impl flatbuffers::EndianScalar for Color {
|
||||||
|
type Scalar = i8;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_little_endian(self) -> Self {
|
fn to_little_endian(self) -> i8 {
|
||||||
let b = i8::to_le(self.0);
|
self.0.to_le()
|
||||||
Self(b)
|
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(clippy::wrong_self_convention)]
|
#[allow(clippy::wrong_self_convention)]
|
||||||
fn from_little_endian(self) -> Self {
|
fn from_little_endian(v: i8) -> Self {
|
||||||
let b = i8::from_le(self.0);
|
let b = i8::from_le(v);
|
||||||
Self(b)
|
Self(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user