Compare commits

...

30 Commits

Author SHA1 Message Date
Derek Bailey
c92e78a9f8 FlatBuffers Version 22.9.29 (#7557) 2022-09-29 22:12:07 -07:00
Björn Harrtell
d243b904cc [TS] Make strict compliant and improve typings (#7549)
* [TS] Make strict compliant and improve typings

* clang-format

* Code gen harmonize

Co-authored-by: Derek Bailey <derekbailey@google.com>
2022-09-29 15:03:35 -07:00
Raphael Taylor-Davies
374f8fb5fb Rust soundness fixes (#7518)
* Rust soundness fixes

* Second pass

* Make init_from_table unsafe

* Remove SafeSliceAccess

* Clippy

* Remove create_vector_of_strings

* More clippy

* Remove deprecated root type accessors

* More soundness fixes

* Fix EndianScalar for bool

* Add TriviallyTransmutable

* Add debug assertions

* Review comments

* Review feedback
2022-09-29 09:58:49 -04:00
mustiikhalil
dadbff5714 Moves swift package to root of repository so it can be used directly … (#7548)
* Moves swift package to root of repository so it can be used directly from the main repo

Fixing paths for swift directory

* Update swift readme
2022-09-27 14:32:05 -07:00
Derek Bailey
76ddae006f FlatBuffers Version 22.9.24 (#7547) 2022-09-27 11:55:25 -07:00
Mark Pauley
cfe157ec56 Emit internal enums when swift_implementation_only (#7545)
- Copy the same pattern as structs and tables
- Fixes google#7542
2022-09-24 20:15:39 +02:00
Joshua Smith
413115858c [Python] Python fixed size array (#7529)
* feat: Added support for fixed sized arrays to python

Problem:
We encountered that using fixed arrays from C++ to python that python would
not read those arrays correctly due to no size information being encoded in the byte
array itself.

Fix:
Encode the sizes within the generated python file during code generation.
Specfically we add GetArrayAsNumpy to the python version of table, which takes as input
the length of the vector. When generating the python message files we include this length
from the VectorType().fixed_length.

* fix: added digit support for camel case to snake case conversion

Problem:
When including a number in the message name we would encounter cases where SnakeCase would
not add the appropirate breaks. e.g. Int32Stamped -> int_32stamped rather than int_32_stamped.

Fix:
To fix this we can add the condition that we check if the current character is not lower and
not a digit, that we check if the previous character was a lower or digit. If it was a lower
or digit then we add the break.

* fix: Array support for structures

Problem:
The python generated code for handling non-struct and struct vectors
and arrays was inconsistent. The calls to populate the obj api was
creating incorrect code.

Solution:
To fix this the VectorOfStruct and VectorOfNonStruct was rewritten
to handle array cases and bring the two methods in line which each
other.

Testing:
PythonTesting.sh now correctly runs and generates the code for
array_test.fbs.
Minor modifications were done on the test to use the new index
accessor for struct arrays and the script correctly sources the
location of the python code.

* chore: clang format changes

* Added code generated by scripts/generate_code. Modified GetArrayOfNonStruct slightly
to allow for function overloading allowing the user to get a single element of an array
or the whole array.

* Added new_line parameter to OffsetPrefix to allow optional new lines to be added.
This allows us to use the GenIndents method that automatically adds new lines instead.

* Reupload of generated code from the scripts/generate_code.py

* Removed new line in GetVectorAsNumpy.

* Updated Array lengths to use Length methods where possible. Added fallthrough for GenTypePointer. Added digit check to CamelToSnake method. Added and modified tests for ToSnakeCase and CamelToSnake.

* Added range check on the getter methods for vector and array types. Renamed == as is for python
2022-09-22 11:08:09 -07:00
Yun Peng
88046190ee Upgrade grpc to 1.49.0 and make sure it builds (#7538)
Co-authored-by: Derek Bailey <derekbailey@google.com>
2022-09-21 12:53:03 -07:00
Denis Blank
72aa85a759 [C++] Rare bad buffer content alignment if sizeof(T) != alignof(T) (#7520)
* [C++] Add a failing unit test for #7516 (Rare bad buffer content alignment if sizeof(T) != alignof(T))

* [C++] Fix final buffer alignment when using an array of structs
* A struct can have an arbitrary size and therefore sizeof(struct) == alignof(struct)
  does not hold anymore as for value primitives.
* This patch fixes this by introducing alignment parameters to various
  CreateVector*/StartVector calls.
* Closes #7516
2022-09-21 11:05:05 -07:00
Dorochi
bfceebb7fb Fix conform (#7532)
* Fix conform;
Make sure the command fails when tail fields are removed;

* Fix last commit according to dbaileychess' comment
2022-09-14 21:45:40 -07:00
Derek Bailey
bc44fad352 UnPackTo disable merge by default (#7527)
* UnPackTo disable merge by default

* avoid double free in test

* remove merge parameter

* remove shrink to fit
2022-09-13 22:00:01 -07:00
Björn Harrtell
4fca4dc60c [TS/JS] Move TS tests to dedicated folder and deps upgrade (#7508)
* Move TS tests to dedicated folder and deps upgrade

* Attempt to fix generate_code

* Fix dir on CI

* Add js extension

* Fix missing extension

* Harmonize with test gen

* Unexplained code gen change

* Restore yarn.lock

* Naive attempt to fix bazel stuff

* Pin @bazel/typescript to 5.2.0

* Attempt to fix bazel

* More tweak

* Upgrade deps

* Tweak?

* Fix path

* Fix test package

Co-authored-by: Derek Bailey <derekbailey@google.com>
2022-09-12 20:03:23 -07:00
dependabot[bot]
036032373b Bump junit from 4.13 to 4.13.1 in /java (#7526)
Bumps [junit](https://github.com/junit-team/junit4) from 4.13 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.13.1.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.13...r4.13.1)

---
updated-dependencies:
- dependency-name: junit:junit
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-11 19:56:51 -07:00
Nick
89dfb43f3b Replace bash JavaTest.sh with mvn test (#7500)
* Start of mvn-ification of the test

* move to right locations

* Update the IO done in the test to read from resources / write to temp folders

* Add github workflow attempt to mvn test it instead of JavaTest.sh

* Pin the Kotlin benchmark's symlink for /java to the right location

* Inline equality assertions and format JavaTest.java

* fix android gradle source directory

Co-authored-by: Derek Bailey <derekbailey@google.com>
2022-09-11 17:46:46 -07:00
Derek Bailey
c49aff4b6f enabled cpp17 tests in CI (#7524) 2022-09-11 16:08:07 -07:00
Derek Bailey
56e60223c3 prevent force_align attribute on enums (#7523) 2022-09-10 13:41:58 -07:00
Derek Bailey
89b1f5aa1b remove travis config (#7522)
* remove travis config

* remove more travis and appveyor stuff

* remove appveyor specific things
2022-09-10 12:36:51 -07:00
Paulo Pinheiro
b901598233 [Java][Flexbuffers] Add API to add nullables into the buffer. (#7521)
Fix #7517
2022-09-10 09:13:01 -07:00
Derek Bailey
8cdc6a2885 Install BuildFlatBuffers.cmake (#7519) 2022-09-10 00:30:47 -07:00
mustiikhalil
a67e35aff9 Moves all of the swift test code into tests/swift (#7509)
Fixes failing tests by regenerating test cases
2022-09-09 22:35:42 -07:00
Derek Bailey
f124e41ae6 Updated Readme
Added links to runtime packages for variety of languages.
2022-09-03 08:05:36 -07:00
Paulo Pinheiro
4c954181cd [Java][FlexBuffers] throwing exception for untyped fixed vectors (#7507)
Untyped fixed vectors are not supported in FlexBuffers. There
was an assert to check for it, but on java, asserts are optional. This
change converts the assertion into a runtime exception.

Fixes #7358

Co-authored-by: Derek Bailey <derekbailey@google.com>
2022-09-01 22:04:18 -07:00
Paulo Pinheiro
7f7547737e [Android] Remove maven dependency of flatbuffers and use source folder (#7503) 2022-09-01 14:58:25 -07:00
mustiikhalil
a79d61ea85 Fixes issue with cocoapods failing to be published because of docc (#7505)
Co-authored-by: Derek Bailey <derekbailey@google.com>
2022-09-01 11:44:13 -07:00
Chris Langhans
d465b39c3e [CMake]: fix breaking find_package change (#7499) (#7502)
Co-authored-by: Derek Bailey <derekbailey@google.com>
2022-09-01 10:28:59 -07:00
Derek Bailey
c5a609dc20 [C#] Prepares for official Nuget release (#7496)
* Define nuget package

* C# Switch to Google.FlatBuffers namespace

* Add Source Link for nuget package

* Add Strong Name signing of Google.FlatBuffers
2022-09-01 10:17:34 -07:00
Ivan Zakharchanka
5634dc3d0d [ISSUE-6268] returns NaN insteadof nan (#7498)
* returns NaN insteadof nan

* clang-format-git
2022-08-31 16:22:17 -07:00
mustiikhalil
37e37b8cad Updates cocoapods version (#7497) 2022-08-31 10:20:11 -07:00
Derek Bailey
8fd4534fbe update android multidex setting (#7495) 2022-08-30 14:32:16 -07:00
Derek Bailey
d5427da52f Disable Android Build (#7494) 2022-08-29 22:16:04 -07:00
523 changed files with 20381 additions and 4401 deletions

6
.github/labeler.yml vendored
View File

@@ -15,9 +15,7 @@ c#:
swift:
- '**/*.swift'
- swift/**/*
- tests/FlatBuffers.GRPC.Swift/**/*
- tests/FlatBuffers.Benchmarks.swift/**/*
- tests/FlatBuffers.Test.Swift/**/*
- tests/swift/**
- src/idl_gen_swift.cpp
javascript:
@@ -86,9 +84,7 @@ documentation:
CI:
- '.github/**/*'
- '.travis/**/*'
- '.bazelci/**/*'
- .travis.yml
grpc:
- grpc/**/*

View File

@@ -82,10 +82,14 @@ jobs:
CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles"
-DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON
-DFLATBUFFERS_CPP_STD=${{ matrix.std }}
-DFLATBUFFERS_BUILD_CPP17=${{ matrix.std >= 17 && 'On' || 'Off'}}
- name: build
run: make -j
- name: test
run: ./flattests
- name: test C++17
if: matrix.std >= 17
run: ./flattests_cpp17
build-windows-cpp-std:
name: Build Windows C++
@@ -103,10 +107,14 @@ jobs:
cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release
-DFLATBUFFERS_STRICT_MODE=ON
-DFLATBUFFERS_CPP_STD=${{ matrix.std }}
-DFLATBUFFERS_BUILD_CPP17=${{ matrix.std >= 17 && 'On' || 'Off'}}
- name: build
run: msbuild.exe FlatBuffers.sln /p:Configuration=Release /p:Platform=x64
- name: test
run: Release\flattests.exe
- name: test C++17
if: matrix.std >= 17
run: Release\flattests_cpp17.exe
build-windows:
permissions:
@@ -350,8 +358,8 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: test
working-directory: tests
run: bash JavaTest.sh
working-directory: java
run: mvn test
build-kotlin-macos:
name: Build Kotlin MacOS
@@ -422,7 +430,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: test
working-directory: tests/FlatBuffers.Test.Swift
working-directory: tests/swift/tests
run: sh SwiftTest.sh
build-swift-wasm:
@@ -435,7 +443,7 @@ jobs:
- name: Setup Wasmer
uses: wasmerio/setup-wasmer@v1
- name: Test
working-directory: tests/FlatBuffers.Test.Swift.Wasm
working-directory: tests/swift/Wasm.tests
run: carton test
build-ts:
@@ -451,7 +459,7 @@ jobs:
- name: compile
run: yarn compile
- name: test
working-directory: tests
working-directory: tests/ts
run: python3 TypeScriptTest.py
build-dart:

5
.gitignore vendored
View File

@@ -78,7 +78,7 @@ tests/php/
CMakeLists.txt.user
CMakeScripts/**
CTestTestfile.cmake
FlatBuffersConfigVersion.cmake
flatbuffers-config-version.cmake
FlatBuffers.cbp
build/Xcode/FlatBuffers.xcodeproj/project.xcworkspace/**
build/Xcode/FlatBuffers.xcodeproj/xcuserdata/**
@@ -88,6 +88,7 @@ java/*.iml
.idea
*.iml
target
java/target
**/*.pyc
build/VS2010/FlatBuffers.sdf
build/VS2010/FlatBuffers.opensdf
@@ -148,4 +149,4 @@ flatbuffers.pc
**/html/**
**/latex/**
# https://cmake.org/cmake/help/latest/module/FetchContent.html#variable:FETCHCONTENT_BASE_DIR
_deps/
_deps/

View File

@@ -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

View File

@@ -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
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)
* 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
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
deprecates the existing `Verifier` constructor, which may be removed in a future
version.
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
deprecates the existing `Verifier` constructor, which may be removed in a
future version.
* 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)
* 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
a flatbuffers (12 bytes). This includes nested flatbuffers, which previously
could be declared valid at size 0.
a flatbuffers (12 bytes). This includes nested flatbuffers, which previously
could be declared valid at size 0.
* 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
binary with schema metadata and value.
one can generate an annotated flatbuffer (.afb) to describe each byte in the
binary with schema metadata and value.
* 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
applied to the other language generators.
* 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
applied to the other language generators.

View File

@@ -654,9 +654,9 @@ if(FLATBUFFERS_INSTALL)
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(
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}
)

View File

@@ -1,6 +1,6 @@
set(VERSION_MAJOR 2)
set(VERSION_MINOR 0)
set(VERSION_PATCH 8)
set(VERSION_MAJOR 22)
set(VERSION_MINOR 9)
set(VERSION_PATCH 29)
set(VERSION_COMMIT 0)
find_program(GIT git)

View File

@@ -230,6 +230,8 @@ set(FlatBuffers_Tests_SRCS
tests/util_test.cpp
tests/native_type_test_impl.h
tests/native_type_test_impl.cpp
tests/alignment_test.h
tests/alignment_test.cpp
include/flatbuffers/code_generators.h
src/code_generators.cpp
# 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
# file generate by running compiler on tests/native_inline_table_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/native_inline_table_test_generated.h
# file generate by running compiler on tests/alignment_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/alignment_test_generated.h
)
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_embedded_binary(tests/monster_test.fbs "--no-includes;--gen-compare")
compile_flatbuffers_schema_to_cpp(tests/native_inline_table_test.fbs "--gen-compare")
compile_flatbuffers_schema_to_cpp(tests/alignment_test.fbs "--gen-compare")
if(NOT (MSVC AND (MSVC_VERSION LESS 1900)))
compile_flatbuffers_schema_to_cpp(tests/monster_extra.fbs) # Test floating-point NAN/INF.
endif()
@@ -699,9 +704,12 @@ if(FLATBUFFERS_INSTALL)
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(
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}
)

View File

@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'FlatBuffers'
s.version = '2.0.0'
s.version = '22.9.29'
s.summary = 'FlatBuffers: Memory Efficient Serialization Library'
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.license = { :type => 'Apache2.0', :file => 'LICENSE' }
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.osx.deployment_target = '10.14'
s.swift_version = '5.0'
s.source_files = 'Sources/**/*'
s.source_files = 'swift/Sources/Flatbuffers/*.swift'
end

View File

@@ -32,5 +32,6 @@ let package = Package(
.target(
name: "FlatBuffers",
dependencies: [],
path: "swift/Sources",
exclude: ["Documentation.docc/Resources/code/swift"]),
])

View File

@@ -31,6 +31,7 @@ let package = Package(
targets: [
.target(
name: "FlatBuffers",
dependencies: []),
dependencies: [],
path: "swift/Sources")
])

View File

@@ -56,10 +56,13 @@ http_archive(
)
##### 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(
name = "com_github_grpc_grpc",
patch_args = ["-p1"],
patches = ["//grpc:build_grpc_with_cxx14.patch"],
sha256 = "15715e1847cc9e42014f02c727dbcb48e39dbdb90f79ad3d66fe4361709ff935",
strip_prefix = "grpc-" + _GRPC_VERSION,
urls = ["https://github.com/grpc/grpc/archive/refs/tags/v" + _GRPC_VERSION + ".tar.gz"],
)

View File

@@ -6,7 +6,8 @@
<uses-feature android:glEsVersion="0x00020000"></uses-feature>
<!-- 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:allowBackup="false">
<!-- Our activity is the built-in NativeActivity framework class.

View File

@@ -8,7 +8,7 @@ android {
defaultConfig {
applicationId "com.flatbuffers.app"
minSdkVersion 16
minSdkVersion 26
targetSdkVersion 30
versionCode 1
versionName "1.0"
@@ -18,6 +18,14 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
main {
java {
srcDir '../../java/src/main/java/'
}
}
}
ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a'
}
@@ -105,30 +113,6 @@ android {
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 {
@@ -136,6 +120,8 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
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'
}

View File

@@ -6,6 +6,13 @@
#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 fbs {
namespace app {

View File

@@ -36,7 +36,7 @@ class Animal : Table() {
return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
}
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, obj: Animal): Animal {
_bb.order(ByteOrder.LITTLE_ENDIAN)

View File

@@ -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")

View File

@@ -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")

View File

@@ -21,14 +21,6 @@ def get_branch():
def get_version():
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)
if match:
return match.group(1)

View File

@@ -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

View File

@@ -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

View File

@@ -1,5 +1,5 @@
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.
homepage: https://github.com/google/flatbuffers
documentation: https://google.github.io/flatbuffers/index.html

View File

@@ -22,10 +22,10 @@ GitHub page](https://github.com/google/flatbuffers/tree/master/swift).
## Testing the FlatBuffers Swift library
The code to test the Swift library can be found at `flatbuffers/Flatbuffers.Test.Swift`.
The test code itself is located in [Flatbuffers.Test.Swift](https://github.com/google/flatbuffers/blob/master/tests/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/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
be installed.*

View 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"]

View File

@@ -6,7 +6,7 @@ import FlatBuffers
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 }
private var _accessor: Table
@@ -55,7 +55,7 @@ extension models_HelloReply: Encodable {
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 }
private var _accessor: Table

View File

@@ -1,4 +1,4 @@
// automatically generated by the FlatBuffers compiler, do not modify
export { HelloReply } from './models/hello-reply';
export { HelloRequest } from './models/hello-request';
export { HelloReply } from './models/hello-reply.js';
export { HelloRequest } from './models/hello-request.js';

View File

@@ -138,9 +138,9 @@
#endif
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
#define FLATBUFFERS_VERSION_MAJOR 2
#define FLATBUFFERS_VERSION_MINOR 0
#define FLATBUFFERS_VERSION_REVISION 8
#define FLATBUFFERS_VERSION_MAJOR 22
#define FLATBUFFERS_VERSION_MINOR 9
#define FLATBUFFERS_VERSION_REVISION 29
#define FLATBUFFERS_STRING_EXPAND(X) #X
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
namespace flatbuffers {

View File

@@ -449,7 +449,7 @@ class FlatBufferBuilder {
}
template<typename T> void PreAlign(size_t len) {
AssertScalarT<T>();
PreAlign(len, sizeof(T));
PreAlign(len, AlignOf<T>());
}
/// @endcond
@@ -589,11 +589,15 @@ class FlatBufferBuilder {
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();
nested = true;
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
@@ -627,7 +631,7 @@ class FlatBufferBuilder {
// If this assert hits, you're specifying a template argument that is
// causing the wrong overload to be selected, remove it.
AssertScalarT<T>();
StartVector(len, sizeof(T));
StartVector<T>(len);
if (len == 0) { return Offset<Vector<T>>(EndVector(len)); }
// clang-format off
#if FLATBUFFERS_LITTLEENDIAN
@@ -668,7 +672,7 @@ class FlatBufferBuilder {
template<typename T>
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]); }
return Offset<Vector<Offset<T>>>(EndVector(len));
}
@@ -688,7 +692,7 @@ class FlatBufferBuilder {
// an array. Instead, read elements manually.
// Background: https://isocpp.org/blog/2012/11/on-vectorbool
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;) {
PushElement(static_cast<uint8_t>(v[--i]));
}
@@ -762,7 +766,7 @@ class FlatBufferBuilder {
for (auto it = begin; it != end; ++it) {
buf_.scratch_push_small(CreateString(*it));
}
StartVector(size, sizeof(Offset<String>));
StartVector<Offset<String>>(size);
for (auto i = 1; i <= size; i++) {
// Note we re-evaluate the buf location each iteration to account for any
// underlying buffer resizing that may occur.
@@ -782,7 +786,7 @@ class FlatBufferBuilder {
/// where the vector is stored.
template<typename T>
Offset<Vector<const T *>> CreateVectorOfStructs(const T *v, size_t len) {
StartVector(len * sizeof(T) / AlignOf<T>(), AlignOf<T>());
StartVector(len * sizeof(T) / AlignOf<T>(), sizeof(T), AlignOf<T>());
if (len > 0) {
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`
/// in the buffer.
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
uint8_t **buf) {
size_t alignment, uint8_t **buf) {
NotNested();
StartVector(len, elemsize);
StartVector(len, elemsize, alignment);
buf_.make_space(len * elemsize);
auto vec_start = GetSize();
auto vec_end = EndVector(len);
@@ -1035,6 +1039,12 @@ class FlatBufferBuilder {
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.
/// 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
@@ -1046,14 +1056,14 @@ class FlatBufferBuilder {
template<typename T>
Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) {
AssertScalarT<T>();
return CreateUninitializedVector(len, sizeof(T),
return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
reinterpret_cast<uint8_t **>(buf));
}
template<typename T>
Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
T **buf) {
return CreateUninitializedVector(len, sizeof(T),
return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
reinterpret_cast<uint8_t **>(buf));
}
@@ -1064,7 +1074,7 @@ class FlatBufferBuilder {
Offset<Vector<T>> CreateVectorScalarCast(const U *v, size_t len) {
AssertScalarT<T>();
AssertScalarT<U>();
StartVector(len, sizeof(T));
StartVector<T>(len);
for (auto i = len; i > 0;) { PushElement(static_cast<T>(v[--i])); }
return Offset<Vector<T>>(EndVector(len));
}
@@ -1173,7 +1183,7 @@ class FlatBufferBuilder {
// Allocates space for a vector of structures.
// Must be completed with EndVectorOfStructs().
template<typename T> T *StartVectorOfStructs(size_t vector_size) {
StartVector(vector_size * sizeof(T) / AlignOf<T>(), AlignOf<T>());
StartVector(vector_size * sizeof(T) / AlignOf<T>(), sizeof(T), AlignOf<T>());
return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
}

View File

@@ -8,9 +8,9 @@
// 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,
static_assert(FLATBUFFERS_VERSION_MAJOR == 22 &&
FLATBUFFERS_VERSION_MINOR == 9 &&
FLATBUFFERS_VERSION_REVISION == 29,
"Non-compatible flatbuffers version included");
namespace reflection {

View File

@@ -685,9 +685,6 @@ bool SetGlobalTestLocale(const char *locale_name,
bool ReadEnvironmentVariable(const char *var_name,
std::string *_value = nullptr);
// MSVC specific: Send all assert reports to STDOUT to prevent CI hangs.
void SetupDefaultCRTReportMode();
enum class Case {
kUnknown = 0,
// TheQuickBrownFox

View File

@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.flatbuffers</groupId>
<artifactId>flatbuffers-java</artifactId>
<version>2.0.8</version>
<version>22.9.29</version>
<packaging>bundle</packaging>
<name>FlatBuffers Java API</name>
<description>
@@ -37,6 +37,18 @@
<tag>HEAD</tag>
</scm>
<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>
<distributionManagement>
<snapshotRepository>
@@ -45,7 +57,21 @@
</snapshotRepository>
</distributionManagement>
<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>
<profiles>
<profile>
@@ -55,13 +81,6 @@
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>8</release>
</configuration>
<version>3.8.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>

View File

@@ -46,7 +46,7 @@ public class Constants {
Changes to the Java implementation need to be sure to change
the version here and in the code generator on every possible
incompatible change */
public static void FLATBUFFERS_2_0_8() {}
public static void FLATBUFFERS_22_9_29() {}
}
/// @endcond

View File

@@ -173,6 +173,21 @@ public class FlexBuffersBuilder {
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
* @param val true or false
@@ -502,7 +517,9 @@ public class FlexBuffersBuilder {
* @return Value representing the created vector
*/
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.
int bitWidth = Math.max(WIDTH_8, widthUInBits(length));
int prefixElems = 1;
@@ -673,6 +690,10 @@ public class FlexBuffersBuilder {
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) {
return new Value(key, FBT_BOOL, WIDTH_8, b ? 1 : 0);
}

View File

@@ -0,0 +1 @@
../../../../tests/DictionaryLookup

File diff suppressed because it is too large Load Diff

1
java/src/test/java/MyGame Symbolic link
View File

@@ -0,0 +1 @@
../../../../tests/MyGame

View File

@@ -0,0 +1 @@
../../../../tests/namespace_test/NamespaceA

View File

@@ -0,0 +1 @@
../../../../tests/namespace_test/NamespaceC

View File

@@ -0,0 +1 @@
../../../../tests/optional_scalars

View File

@@ -0,0 +1 @@
../../../../tests/union_vector

Binary file not shown.

View File

@@ -1 +1 @@
../../../../java/
../../../../java/src/main/java

View File

@@ -51,7 +51,7 @@ using System.Buffers.Binary;
#warning ENABLE_SPAN_T requires UNSAFE_BYTEBUFFER to also be defined
#endif
namespace FlatBuffers
namespace Google.FlatBuffers
{
public abstract class ByteBufferAllocator
{

View File

@@ -16,7 +16,7 @@
using System;
namespace FlatBuffers
namespace Google.FlatBuffers
{
/// <summary>
/// Class that collects utility functions around `ByteBuffer`.

View File

@@ -23,7 +23,7 @@ using System.Text;
/// @addtogroup flatbuffers_csharp_api
/// @{
namespace FlatBuffers
namespace Google.FlatBuffers
{
/// <summary>
/// Responsible for building up and accessing a FlatBuffer formatted byte

View File

@@ -19,7 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FlatBuffers
namespace Google.FlatBuffers
{
public static class FlatBufferConstants
{
@@ -32,6 +32,6 @@ namespace FlatBuffers
Changes to the C# implementation need to be sure to change
the version here and in the code generator on every possible
incompatible change */
public static void FLATBUFFERS_2_0_8() {}
public static void FLATBUFFERS_22_9_29() {}
}
}

View File

@@ -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>

View 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>

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
namespace FlatBuffers
namespace Google.FlatBuffers
{
/// <summary>
/// This is the base for both structs and tables.

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
namespace FlatBuffers
namespace Google.FlatBuffers
{
/// <summary>
/// Offset class for typesafe assignments.

View File

@@ -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")]

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
namespace FlatBuffers
namespace Google.FlatBuffers
{
/// <summary>
/// All structs in the generated code derive from this class, and add their own accessors.

View File

@@ -18,7 +18,7 @@ using System;
using System.Text;
using System.Runtime.InteropServices;
namespace FlatBuffers
namespace Google.FlatBuffers
{
/// <summary>
/// All tables in the generated code derive from this struct, and add their own accessors.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

View File

@@ -1,6 +1,6 @@
{
"name": "flatbuffers",
"version": "2.0.8",
"version": "22.9.29",
"description": "Memory Efficient Serialization Library",
"files": [
"js/**/*.js",
@@ -16,7 +16,8 @@
"test": "tests"
},
"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",
"prepublishOnly": "npm install --only=dev && npm run compile"
},
@@ -35,12 +36,12 @@
"homepage": "https://google.github.io/flatbuffers/",
"dependencies": {},
"devDependencies": {
"@bazel/typescript": "^5.2.0",
"@types/node": "17.0.21",
"@typescript-eslint/eslint-plugin": "^4.12.0",
"@typescript-eslint/parser": "^4.12.0",
"eslint": "^7.17.0",
"rollup": "^2.78.0",
"typescript": "^4.5.5"
"@bazel/typescript": "5.2.0",
"@types/node": "18.7.16",
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"eslint": "^8.23.1",
"rollup": "^2.79.0",
"typescript": "^4.8.3"
}
}

View File

@@ -14,4 +14,4 @@
# Placeholder, to be updated during the release process
# by the setup.py
__version__ = u"2.0.8"
__version__ = u"22.9.29"

View File

@@ -113,6 +113,15 @@ class Table(object):
numpy_dtype = N.to_numpy_type(flags)
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):
"""
GetVOffsetTSlot retrieves the VOffsetT that the given vtable location
@@ -125,5 +134,5 @@ class Table(object):
off = self.Offset(slot)
if off == 0:
return d
return d
return off

View File

@@ -20,33 +20,46 @@ maximum memory efficiency. It allows you to directly access serialized data with
* MacOS X
* Linux
* Android
* And any others with a recent C++ compiler.
* And any others with a recent C++ compiler (C++ 11 and newer)
## Supported programming languages
* C++
* C#
* C
* Dart
* Go
* Java
* JavaScript
* Lobster
* Lua
* PHP
* Python
* Rust
* Swift
* TypeScript
Code generation and runtime libraries for many popular languages.
1. C
1. C++ - [snapcraft.io](https://snapcraft.io/flatbuffers)
1. C# - [nuget.org](https://www.nuget.org/packages/Google.FlatBuffers)
1. Dart - [pub.dev](https://pub.dev/packages/flat_buffers)
1. Go - [go.dev](https://pkg.go.dev/github.com/google/flatbuffers/go)
1. Java - [Maven](https://search.maven.org/artifact/com.google.flatbuffers/flatbuffers-java)
1. JavaScript - [NPM](https://www.npmjs.com/package/flatbuffers)
1. Kotlin
1. Lobster
1. Lua
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...*
1. [Nim](https://github.com/google/flatbuffers/pull/7362)
## Contribution
* [FlatBuffers Google Group][] to discuss FlatBuffers with other developers and users.
* [FlatBuffers Issues Tracker][] to submit an issue.
* [stackoverflow.com][] with [`flatbuffers` tag][] for any questions regarding FlatBuffers.
*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
Please see our [Security Policy](SECURITY.md) for reporting vulnerabilities.

View File

@@ -17,7 +17,6 @@ no_std = ["core2", "thiserror_core2"]
serialize = ["serde"]
[dependencies]
smallvec = "1.6.1"
bitflags = "1.2.1"
serde = { version = "1.0", optional = true }
thiserror = { version = "1.0.30", optional = true }

View File

@@ -37,14 +37,18 @@ where
#[allow(clippy::len_without_is_empty)]
#[allow(clippy::from_over_into)] // TODO(caspern): Go from From to Into.
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)]
pub fn new(buf: &'a [u8]) -> Self {
assert!(size_of::<T>() * N == buf.len());
pub unsafe fn new(buf: &'a [u8]) -> Self {
assert_eq!(size_of::<T>() * N, buf.len());
Array {
0: buf,
1: PhantomData,
}
Array(buf, PhantomData)
}
#[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 {
assert!(idx < N);
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)]
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> {
#[inline(always)]
fn into(self) -> [T::Inner; N] {
array_init(|i| self.get(i))
impl<'a, T: Follow<'a> + Debug, const N: usize> From<Array<'a, T, N>> for [T::Inner; N] {
fn from(array: Array<'a, T, N>) -> Self {
array_init(|i| array.get(i))
}
}
// TODO(caspern): Implement some future safe version of SafeSliceAccess.
/// 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> {
type Inner = Array<'a, T, N>;
#[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>()])
}
}
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],
loc: usize,
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();
for item in src.iter() {
let item_le = item.to_little_endian();
unsafe {
core::ptr::copy_nonoverlapping(
&item_le as *const T as *const u8,
buf_ptr,
size_of::<T>(),
);
buf_ptr = buf_ptr.add(size_of::<T>());
}
core::ptr::copy_nonoverlapping(
&item_le as *const T::Scalar as *const u8,
buf_ptr,
size_of::<T::Scalar>(),
);
buf_ptr = buf_ptr.add(size_of::<T::Scalar>());
}
}
@@ -124,6 +131,8 @@ where
let mut array: core::mem::MaybeUninit<[T; N]> = core::mem::MaybeUninit::uninit();
let mut ptr_i = array.as_mut_ptr() as *mut T;
// Safety:
// array is aligned by T, and has length N
unsafe {
for i in 0..N {
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>
where
T: 'a + Follow<'a>,

View File

@@ -14,26 +14,22 @@
* limitations under the License.
*/
extern crate smallvec;
#[cfg(feature = "no_std")]
use alloc::{vec, vec::Vec};
use core::cmp::max;
use core::iter::{DoubleEndedIterator, ExactSizeIterator};
use core::marker::PhantomData;
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::push::{Push, PushAlignment};
use crate::read_scalar;
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_writer::VTableWriter;
pub const N_SMALLVEC_STRING_VECTOR_CAPACITY: usize = 16;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct FieldLoc {
off: UOffsetT,
@@ -121,6 +117,8 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
{
let to_clear = self.owned_buf.len() - self.head;
let ptr = (&mut self.owned_buf[self.head..]).as_mut_ptr();
// Safety:
// Verified ptr is valid for `to_clear` above
unsafe {
write_bytes(ptr, 0, to_clear);
}
@@ -153,7 +151,9 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
self.make_space(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)
}
@@ -309,73 +309,32 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
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.
///
/// 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<'a: 'b, 'b, T: Push + Copy + 'b>(
pub fn create_vector<'a: 'b, 'b, T: Push + 'b>(
&'a mut self,
items: &'b [T],
) -> WIPOffset<Vector<'fbb, T::Output>> {
let elem_size = T::size();
self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET));
for i in (0..items.len()).rev() {
self.push(items[i]);
let slice_size = items.len() * elem_size;
self.align(slice_size, T::alignment().max_of(SIZE_UOFFSET));
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())
}
@@ -384,17 +343,18 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
/// 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_from_iter<T: Push + Copy>(
pub fn create_vector_from_iter<T: Push>(
&mut self,
items: impl ExactSizeIterator<Item = T> + DoubleEndedIterator,
) -> WIPOffset<Vector<'fbb, T::Output>> {
let elem_size = T::size();
let len = items.len();
self.align(len * elem_size, T::alignment().max_of(SIZE_UOFFSET));
self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET));
let mut actual = 0;
for item in items.rev() {
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.
@@ -443,7 +403,15 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
assert_msg_name: &'static str,
) {
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;
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 found = self.written_vtable_revpos.binary_search_by(|old_vtable_revpos: &UOffsetT| {
let old_vtable_pos = self.owned_buf.len() - *old_vtable_revpos as usize;
let old_vtable = VTable::init(&self.owned_buf, old_vtable_pos);
new_vt_bytes.cmp(old_vtable.as_bytes())
});
let found = self
.written_vtable_revpos
.binary_search_by(|old_vtable_revpos: &UOffsetT| {
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 {
Ok(i) => {
// 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.
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) };
debug_assert_eq!(tmp_soffset_to_vt, 0xF0F0_F0F0);
if cfg!(debug_assertions) {
// 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 {
emplace_scalar::<SOffsetT>(
&mut self.owned_buf[table_pos..table_pos + SIZE_SOFFSET],
final_vtable_revpos as SOffsetT - object_revloc_to_vtable.value() as SOffsetT
buf,
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.
{
let ptr = (&mut self.owned_buf[..middle]).as_mut_ptr();
// Safety:
// ptr is byte aligned and of length middle
unsafe {
write_bytes(ptr, 0, middle);
}

View File

@@ -17,6 +17,24 @@
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
/// might be represented in memory as big-endian. Every type that implements
/// 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
/// invalid FlatBuffers type.
pub trait EndianScalar: Sized + PartialEq + Copy + Clone {
fn to_little_endian(self) -> Self;
fn from_little_endian(self) -> Self;
}
type Scalar: private::TriviallyTransmutable;
/// Macro for implementing a no-op endian conversion. This is used for types
/// that are one byte wide.
macro_rules! impl_endian_scalar_noop {
($ty:ident) => {
impl EndianScalar for $ty {
#[inline]
fn to_little_endian(self) -> Self {
self
}
#[inline]
fn from_little_endian(self) -> Self {
self
}
}
};
fn to_little_endian(self) -> Self::Scalar;
fn from_little_endian(v: Self::Scalar) -> Self;
}
/// 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
/// floats, because the `to_le` and `from_le` are not implemented for them in
/// the stdlib.
macro_rules! impl_endian_scalar_stdlib_le_conversion {
macro_rules! impl_endian_scalar {
($ty:ident) => {
impl EndianScalar for $ty {
type Scalar = Self;
#[inline]
fn to_little_endian(self) -> Self {
fn to_little_endian(self) -> Self::Scalar {
Self::to_le(self)
}
#[inline]
fn from_little_endian(self) -> Self {
Self::from_le(self)
fn from_little_endian(v: Self::Scalar) -> Self {
Self::from_le(v)
}
}
};
}
impl_endian_scalar_noop!(bool);
impl_endian_scalar_noop!(u8);
impl_endian_scalar_noop!(i8);
impl_endian_scalar!(u8);
impl_endian_scalar!(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_endian_scalar_stdlib_le_conversion!(u32);
impl_endian_scalar_stdlib_le_conversion!(u64);
impl_endian_scalar_stdlib_le_conversion!(i16);
impl_endian_scalar_stdlib_le_conversion!(i32);
impl_endian_scalar_stdlib_le_conversion!(i64);
impl EndianScalar for bool {
type Scalar = u8;
fn to_little_endian(self) -> Self::Scalar {
self as u8
}
fn from_little_endian(v: Self::Scalar) -> Self {
v != 0
}
}
impl EndianScalar for f32 {
type Scalar = u32;
/// Convert f32 from host endian-ness to little-endian.
#[inline]
fn to_little_endian(self) -> Self {
#[cfg(target_endian = "little")]
{
self
}
#[cfg(not(target_endian = "little"))]
{
byte_swap_f32(self)
}
fn to_little_endian(self) -> u32 {
// Floats and Ints have the same endianness on all supported platforms.
// <https://doc.rust-lang.org/std/primitive.f32.html#method.from_bits>
self.to_bits().to_le()
}
/// Convert f32 from little-endian to host endian-ness.
#[inline]
fn from_little_endian(self) -> Self {
#[cfg(target_endian = "little")]
{
self
}
#[cfg(not(target_endian = "little"))]
{
byte_swap_f32(self)
}
fn from_little_endian(v: u32) -> Self {
// Floats and Ints have the same endianness on all supported platforms.
// <https://doc.rust-lang.org/std/primitive.f32.html#method.from_bits>
f32::from_bits(u32::from_le(v))
}
}
impl EndianScalar for f64 {
type Scalar = u64;
/// Convert f64 from host endian-ness to little-endian.
#[inline]
fn to_little_endian(self) -> Self {
#[cfg(target_endian = "little")]
{
self
}
#[cfg(not(target_endian = "little"))]
{
byte_swap_f64(self)
}
fn to_little_endian(self) -> u64 {
// Floats and Ints have the same endianness on all supported platforms.
// <https://doc.rust-lang.org/std/primitive.f64.html#method.from_bits>
self.to_bits().to_le()
}
/// Convert f64 from little-endian to host endian-ness.
#[inline]
fn from_little_endian(self) -> Self {
#[cfg(target_endian = "little")]
{
self
}
#[cfg(not(target_endian = "little"))]
{
byte_swap_f64(self)
}
fn from_little_endian(v: u64) -> Self {
// Floats and Ints have the same endianness on all supported platforms.
// <https://doc.rust-lang.org/std/primitive.f64.html#method.from_bits>
f64::from_bits(u64::from_le(v))
}
}
/// 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
/// endian conversion, if necessary.
/// # Safety
/// Caller must ensure `s.len() > size_of::<T>()`
/// and `x` does not overlap with `s`.
/// Caller must ensure `s.len() >= size_of::<T>()`
#[inline]
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();
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,
size_of::<T>(),
size,
);
}
/// Read an EndianScalar from the provided byte slice at the specified location.
/// Performs endian conversion, if necessary.
/// # Safety
/// Caller must ensure `s.len() > loc + size_of::<T>()`.
/// Caller must ensure `s.len() >= loc + size_of::<T>()`.
#[inline]
pub unsafe fn read_scalar_at<T: EndianScalar>(s: &[u8], loc: usize) -> T {
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>()`.
#[inline]
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.
core::ptr::copy_nonoverlapping(s.as_ptr(), mem.as_mut_ptr() as *mut u8, size_of::<T>());
mem.assume_init().from_little_endian()
core::ptr::copy_nonoverlapping(
s.as_ptr(),
mem.as_mut_ptr() as *mut u8,
size,
);
T::from_little_endian(mem.assume_init())
}

View File

@@ -29,7 +29,11 @@ use core::marker::PhantomData;
/// continue traversing the FlatBuffer.
pub trait Follow<'buf> {
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
@@ -39,17 +43,21 @@ pub struct FollowStart<T>(PhantomData<T>);
impl<'a, T: Follow<'a> + 'a> FollowStart<T> {
#[inline]
pub fn new() -> Self {
Self { 0: PhantomData }
Self(PhantomData)
}
/// # Safety
///
/// `buf[loc..]` must contain a valid value of `T`
#[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)
}
}
impl<'a, T: Follow<'a>> Follow<'a> for FollowStart<T> {
type Inner = T::Inner;
#[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
T::follow(buf, loc)
}
}

View File

@@ -45,6 +45,8 @@ where
{
let mut v = Verifier::new(opts, data);
<ForwardsUOffset<T>>::run_verifier(&mut v, 0)?;
// Safety:
// Run verifier above
Ok(unsafe { root_unchecked::<T>(data) })
}
@@ -75,6 +77,8 @@ where
{
let mut v = Verifier::new(opts, data);
<SkipSizePrefix<ForwardsUOffset<T>>>::run_verifier(&mut v, 0)?;
// Safety:
// Run verifier above
Ok(unsafe { size_prefixed_root_unchecked::<T>(data) })
}

View File

@@ -48,14 +48,12 @@ mod vtable_writer;
pub use crate::array::{array_init, emplace_scalar_array, Array};
pub use crate::builder::FlatBufferBuilder;
pub use crate::endian_scalar::{
byte_swap_f32, byte_swap_f64, emplace_scalar, read_scalar, read_scalar_at, EndianScalar,
};
pub use crate::endian_scalar::{emplace_scalar, read_scalar, read_scalar_at, EndianScalar};
pub use crate::follow::{Follow, FollowStart};
pub use crate::primitives::*;
pub use crate::push::Push;
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::{
ErrorTraceDetail, InvalidFlatbuffer, SimpleToVerifyInSlice, Verifiable, Verifier,
VerifierOptions,
@@ -64,6 +62,4 @@ pub use crate::vtable::field_index_to_field_offset;
pub use bitflags;
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++.

View File

@@ -112,10 +112,7 @@ impl<'a, T: 'a> WIPOffset<T> {
/// Create a new WIPOffset.
#[inline]
pub fn new(o: UOffsetT) -> WIPOffset<T> {
WIPOffset {
0: o,
1: PhantomData,
}
WIPOffset(o, PhantomData)
}
/// 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>;
#[inline(always)]
fn push(&self, dst: &mut [u8], rest: &[u8]) {
let n = (SIZE_UOFFSET + rest.len() - self.value() as usize) as UOffsetT;
unsafe {
emplace_scalar::<UOffsetT>(dst, n);
}
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
let n = (SIZE_UOFFSET + written_len - self.value() as usize) as UOffsetT;
emplace_scalar::<UOffsetT>(dst, n);
}
}
@@ -147,8 +142,8 @@ impl<T> Push for ForwardsUOffset<T> {
type Output = Self;
#[inline(always)]
fn push(&self, dst: &mut [u8], rest: &[u8]) {
self.value().push(dst, rest);
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
self.value().push(dst, written_len);
}
}
@@ -179,9 +174,9 @@ impl<T> ForwardsUOffset<T> {
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsUOffset<T> {
type Inner = T::Inner;
#[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 off = unsafe { read_scalar::<u32>(slice) as usize };
let off = read_scalar::<u32>(slice) as usize;
T::follow(buf, loc + off)
}
}
@@ -200,9 +195,9 @@ impl<T> ForwardsVOffset<T> {
impl<'a, T: Follow<'a>> Follow<'a> for ForwardsVOffset<T> {
type Inner = T::Inner;
#[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 off = unsafe { read_scalar::<VOffsetT>(slice) as usize };
let off = read_scalar::<VOffsetT>(slice) as usize;
T::follow(buf, loc + off)
}
}
@@ -211,8 +206,8 @@ impl<T> Push for ForwardsVOffset<T> {
type Output = Self;
#[inline]
fn push(&self, dst: &mut [u8], rest: &[u8]) {
self.value().push(dst, rest);
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
self.value().push(dst, written_len);
}
}
@@ -230,9 +225,9 @@ impl<T> BackwardsSOffset<T> {
impl<'a, T: Follow<'a>> Follow<'a> for BackwardsSOffset<T> {
type Inner = T::Inner;
#[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 off = unsafe { read_scalar::<SOffsetT>(slice) };
let off = read_scalar::<SOffsetT>(slice);
T::follow(buf, (loc as SOffsetT - off) as usize)
}
}
@@ -241,8 +236,8 @@ impl<T> Push for BackwardsSOffset<T> {
type Output = Self;
#[inline]
fn push(&self, dst: &mut [u8], rest: &[u8]) {
self.value().push(dst, rest);
unsafe fn push(&self, dst: &mut [u8], written_len: usize) {
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> {
type Inner = T::Inner;
#[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)
}
}
@@ -263,7 +258,7 @@ pub struct SkipRootOffset<T>(PhantomData<T>);
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipRootOffset<T> {
type Inner = T::Inner;
#[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)
}
}
@@ -274,7 +269,7 @@ pub struct FileIdentifier;
impl<'a> Follow<'a> for FileIdentifier {
type Inner = &'a [u8];
#[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]
}
}
@@ -286,7 +281,7 @@ pub struct SkipFileIdentifier<T>(PhantomData<T>);
impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> {
type Inner = T::Inner;
#[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)
}
}
@@ -294,8 +289,8 @@ impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> {
impl<'a> Follow<'a> for bool {
type Inner = bool;
#[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
unsafe { read_scalar_at::<u8>(buf, loc) != 0 }
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
read_scalar_at::<u8>(buf, loc) != 0
}
}
@@ -309,8 +304,8 @@ macro_rules! impl_follow_for_endian_scalar {
impl<'a> Follow<'a> for $ty {
type Inner = $ty;
#[inline(always)]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
unsafe { read_scalar_at::<$ty>(buf, loc) }
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
read_scalar_at::<$ty>(buf, loc)
}
}
};

View File

@@ -24,7 +24,11 @@ use crate::endian_scalar::emplace_scalar;
/// types.
pub trait Push: Sized {
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]
fn size() -> usize {
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
/// implementation issues when using FlatBufferBuilder::align).
pub struct PushAlignment(usize);
impl PushAlignment {
#[inline]
pub fn new(x: usize) -> Self {
PushAlignment { 0: x }
PushAlignment(x)
}
#[inline]
pub fn value(&self) -> usize {
@@ -60,10 +80,8 @@ macro_rules! impl_push_for_endian_scalar {
type Output = $ty;
#[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
unsafe {
emplace_scalar::<$ty>(dst, *self);
}
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
emplace_scalar::<$ty>(dst, *self);
}
}
};

View File

@@ -18,23 +18,36 @@ use crate::follow::Follow;
use crate::primitives::*;
use crate::vtable::VTable;
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Table<'a> {
pub buf: &'a [u8],
pub loc: usize,
buf: &'a [u8],
loc: usize,
}
impl<'a> Table<'a> {
/// # Safety
///
/// `buf` must contain a `soffset_t` at `loc`, which points to a valid vtable
#[inline]
pub fn new(buf: &'a [u8], loc: usize) -> Self {
pub unsafe fn new(buf: &'a [u8], loc: usize) -> Self {
Table { buf, loc }
}
#[inline]
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]
pub fn get<T: Follow<'a> + 'a>(
pub unsafe fn get<T: Follow<'a> + 'a>(
&self,
slot_byte_loc: VOffsetT,
default: Option<T::Inner>,
@@ -50,19 +63,26 @@ impl<'a> Table<'a> {
impl<'a> Follow<'a> for Table<'a> {
type Inner = Table<'a>;
#[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Table { buf, loc }
}
}
/// Returns true if data contains a prefix of `ident`
#[inline]
pub fn buffer_has_identifier(data: &[u8], ident: &str, size_prefixed: bool) -> bool {
assert_eq!(ident.len(), FILE_IDENTIFIER_LENGTH);
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 {
<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

View File

@@ -17,13 +17,10 @@
use core::fmt::{Debug, Formatter, Result};
use core::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
use core::marker::PhantomData;
use core::mem::size_of;
use core::slice::from_raw_parts;
use core::mem::{align_of, size_of};
use core::str::from_utf8_unchecked;
use crate::endian_scalar::read_scalar_at;
#[cfg(target_endian = "little")]
use crate::endian_scalar::EndianScalar;
use crate::follow::Follow;
use crate::primitives::*;
@@ -55,6 +52,7 @@ where
// and Clone for `T: Copy` and `T: Clone` respectively. However `Vector<'a, T>`
// can always be copied, no matter that `T` you have.
impl<'a, T> Copy for Vector<'a, T> {}
impl<'a, T> Clone for Vector<'a, T> {
fn clone(&self) -> Self {
*self
@@ -62,32 +60,46 @@ impl<'a, T> Clone for 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)]
pub fn new(buf: &'a [u8], loc: usize) -> Self {
Vector {
0: buf,
1: loc,
2: PhantomData,
}
pub unsafe fn new(buf: &'a [u8], loc: usize) -> Self {
Vector(buf, loc, PhantomData)
}
#[inline(always)]
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 }
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
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> {
#[inline(always)]
pub fn get(&self, idx: usize) -> T::Inner {
assert!(idx < self.len() as usize);
assert!(idx < self.len());
let sz = size_of::<T>();
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)]
@@ -96,84 +108,40 @@ impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
}
}
pub trait SafeSliceAccess {}
impl<'a, T: SafeSliceAccess + 'a> Vector<'a, T> {
pub fn safe_slice(self) -> &'a [T] {
let buf = self.0;
let loc = self.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 {
/// # Safety
///
/// `buf` must contain a value of T at `loc` and have alignment of 1
pub unsafe fn follow_cast_ref<'a, T: Sized + 'a>(buf: &'a [u8], loc: usize) -> &'a T {
assert_eq!(align_of::<T>(), 1);
let sz = size_of::<T>();
let buf = &buf[loc..loc + sz];
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 {
type Inner = &'a str;
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let len = unsafe { read_scalar_at::<UOffsetT>(buf, loc) } as usize;
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let len = read_scalar_at::<UOffsetT>(buf, loc) as usize;
let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len];
unsafe { from_utf8_unchecked(slice) }
from_utf8_unchecked(slice)
}
}
#[cfg(target_endian = "little")]
fn follow_slice_helper<T>(buf: &[u8], loc: usize) -> &[T] {
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: &[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)
impl<'a> Follow<'a> for &'a [u8] {
type Inner = &'a [u8];
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let len = read_scalar_at::<UOffsetT>(buf, loc) as usize;
&buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len]
}
}
/// Implement Follow for all possible Vectors that have Follow-able elements.
impl<'a, T: Follow<'a> + 'a> Follow<'a> for 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)
}
}
@@ -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]
pub fn from_slice(buf: &'a [u8], items_num: usize) -> Self {
pub unsafe fn from_slice(buf: &'a [u8], items_num: usize) -> Self {
VectorIter {
buf,
loc: 0,
@@ -235,7 +209,10 @@ impl<'a, T: Follow<'a> + 'a> Iterator for VectorIter<'a, T> {
if self.remaining == 0 {
None
} 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.remaining -= 1;
Some(result)
@@ -272,7 +249,10 @@ impl<'a, T: Follow<'a> + 'a> DoubleEndedIterator for VectorIter<'a, T> {
None
} else {
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>
where
T: 'a + Follow<'a>,

View File

@@ -1,14 +1,14 @@
use crate::follow::Follow;
use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
#[cfg(feature = "no_std")]
use alloc::vec::Vec;
use core::ops::Range;
use core::option::Option;
use crate::follow::Follow;
use crate::{ForwardsUOffset, SOffsetT, SkipSizePrefix, UOffsetT, VOffsetT, Vector, SIZE_UOFFSET};
#[cfg(feature="no_std")]
use thiserror_core2::Error;
#[cfg(not(feature="no_std"))]
#[cfg(not(feature = "no_std"))]
use thiserror::Error;
#[cfg(feature = "no_std")]
use thiserror_core2::Error;
/// Traces the location of data errors. Not populated for Dos detecting errors.
/// Useful for MissingRequiredField and Utf8Error in particular, though
@@ -28,8 +28,10 @@ pub enum ErrorTraceDetail {
position: usize,
},
}
#[derive(PartialEq, Eq, Default, Debug, Clone)]
pub struct ErrorTrace(Vec<ErrorTraceDetail>);
impl core::convert::AsRef<[ErrorTraceDetail]> for ErrorTrace {
#[inline]
fn as_ref(&self) -> &[ErrorTraceDetail] {
@@ -63,7 +65,7 @@ pub enum InvalidFlatbuffer {
error_trace: ErrorTrace,
},
#[error("String in range [{}, {}) is missing its null terminator.\n{error_trace}",
range.start, range.end)]
range.start, range.end)]
MissingNullTerminator {
range: Range<usize>,
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.
fn trace_elem<T>(res: Result<T>, index: usize, position: usize) -> Result<T> {
append_trace(res, ErrorTraceDetail::VectorElement { index, position })
@@ -205,6 +208,7 @@ pub struct VerifierOptions {
// options to error un-recognized enums and unions? possible footgun.
// Ignore nested flatbuffers, etc?
}
impl Default for VerifierOptions {
fn default() -> Self {
Self {
@@ -226,6 +230,7 @@ pub struct Verifier<'opts, 'buf> {
num_tables: usize,
apparent_size: usize,
}
impl<'opts, 'buf> Verifier<'opts, 'buf> {
pub fn new(opts: &'opts VerifierOptions, buffer: &'buf [u8]) -> Self {
Self {
@@ -247,9 +252,12 @@ impl<'opts, 'buf> Verifier<'opts, 'buf> {
/// memory since `buffer: &[u8]` has alignment 1.
///
/// ### WARNING
///
/// 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.
/// `buffer[0]`. TODO(caspern).
///
/// Note this does not impact soundness as this crate does not assume alignment of structs
#[inline]
fn is_aligned<T>(&self, pos: usize) -> Result<()> {
if pos % core::mem::align_of::<T>() == 0 {
@@ -307,9 +315,9 @@ impl<'opts, 'buf> Verifier<'opts, 'buf> {
// signed offsets are subtracted.
let derefed = if offset > 0 {
pos.checked_sub(offset.abs() as usize)
pos.checked_sub(offset.unsigned_abs() as usize)
} else {
pos.checked_add(offset.abs() as usize)
pos.checked_add(offset.unsigned_abs() as usize)
};
if let Some(x) = derefed {
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: &'ver mut Verifier<'opts, 'buf>,
}
impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> {
fn deref(&mut self, field: VOffsetT) -> Result<Option<usize>> {
let field = field as usize;
@@ -439,7 +448,9 @@ impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> {
}
(Some(k), Some(v)) => {
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(
verify_union(discriminant, self.verifier, v),
val_field_name,
@@ -486,16 +497,27 @@ fn verify_vector_range<T>(v: &mut Verifier, pos: usize) -> Result<core::ops::Ran
}
pub trait SimpleToVerifyInSlice {}
impl SimpleToVerifyInSlice for bool {}
impl SimpleToVerifyInSlice for i8 {}
impl SimpleToVerifyInSlice for u8 {}
impl SimpleToVerifyInSlice for i16 {}
impl SimpleToVerifyInSlice for u16 {}
impl SimpleToVerifyInSlice for i32 {}
impl SimpleToVerifyInSlice for u32 {}
impl SimpleToVerifyInSlice for f32 {}
impl SimpleToVerifyInSlice for i64 {}
impl SimpleToVerifyInSlice for u64 {}
impl SimpleToVerifyInSlice for f64 {}
impl<T: SimpleToVerifyInSlice> Verifiable for Vector<'_, T> {

View File

@@ -33,24 +33,42 @@ impl<'a> PartialEq for 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 }
}
pub fn num_fields(&self) -> usize {
(self.num_bytes() / SIZE_VOFFSET) - 2
}
pub fn num_bytes(&self) -> usize {
// Safety:
// Valid VTable at time of construction
unsafe { read_scalar_at::<VOffsetT>(self.buf, self.loc) as 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) };
n as usize
}
pub fn get_field(&self, idx: usize) -> VOffsetT {
// TODO(rw): distinguish between None and 0?
if idx > self.num_fields() {
return 0;
}
// Safety:
// Valid VTable at time of construction
unsafe {
read_scalar_at::<VOffsetT>(
self.buf,
@@ -58,13 +76,17 @@ impl<'a> VTable<'a> {
)
}
}
pub fn get(&self, byte_loc: VOffsetT) -> VOffsetT {
// 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;
}
// 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) }
}
pub fn as_bytes(&self) -> &[u8] {
let len = self.num_bytes();
&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> {
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)
}
}

View File

@@ -40,8 +40,11 @@ impl<'a> VTableWriter<'a> {
/// to the provided value.
#[inline(always)]
pub fn write_vtable_byte_length(&mut self, n: VOffsetT) {
let buf = &mut self.buf[..SIZE_VOFFSET];
// Safety:
// Validated range above
unsafe {
emplace_scalar::<VOffsetT>(&mut self.buf[..SIZE_VOFFSET], n);
emplace_scalar::<VOffsetT>(buf, n);
}
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.
#[inline(always)]
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 {
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)]
pub fn write_field_offset(&mut self, vtable_offset: VOffsetT, object_data_offset: VOffsetT) {
let idx = vtable_offset as usize;
let buf = &mut self.buf[idx..idx + SIZE_VOFFSET];
// Safety:
// Validated range above
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.
let len = self.buf.len();
let p = self.buf.as_mut_ptr() as *mut u8;
// Safety:
// p is byte aligned and of length `len`
unsafe {
write_bytes(p, 0, len);
}

View File

@@ -8,9 +8,9 @@
// 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,
static_assert(FLATBUFFERS_VERSION_MAJOR == 22 &&
FLATBUFFERS_VERSION_MINOR == 9 &&
FLATBUFFERS_VERSION_REVISION == 29,
"Non-compatible flatbuffers version included");
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 = 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 = 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(); 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) {

View File

@@ -31,7 +31,7 @@ public enum MyGame_Sample_Equipment: UInt8, Enum {
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 _y: Float32
@@ -56,7 +56,7 @@ public struct MyGame_Sample_Vec3: NativeStruct {
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 }
private var _accessor: Struct
@@ -72,7 +72,7 @@ public struct MyGame_Sample_Vec3_Mutable: 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 }
private var _accessor: Table
@@ -162,7 +162,7 @@ public struct MyGame_Sample_Monster: 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 }
private var _accessor: Table

View File

@@ -59,10 +59,8 @@ impl core::fmt::Debug for Color {
impl<'a> flatbuffers::Follow<'a> for Color {
type Inner = Self;
#[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let b = unsafe {
flatbuffers::read_scalar_at::<i8>(buf, loc)
};
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let b = flatbuffers::read_scalar_at::<i8>(buf, loc);
Self(b)
}
}
@@ -70,21 +68,21 @@ impl<'a> flatbuffers::Follow<'a> for Color {
impl flatbuffers::Push for Color {
type Output = Color;
#[inline]
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
unsafe { flatbuffers::emplace_scalar::<i8>(dst, self.0); }
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
flatbuffers::emplace_scalar::<i8>(dst, self.0);
}
}
impl flatbuffers::EndianScalar for Color {
type Scalar = i8;
#[inline]
fn to_little_endian(self) -> Self {
let b = i8::to_le(self.0);
Self(b)
fn to_little_endian(self) -> i8 {
self.0.to_le()
}
#[inline]
#[allow(clippy::wrong_self_convention)]
fn from_little_endian(self) -> Self {
let b = i8::from_le(self.0);
fn from_little_endian(v: i8) -> Self {
let b = i8::from_le(v);
Self(b)
}
}

Some files were not shown because too many files have changed in this diff Show More