mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-19 09:03:05 +00:00
Compare commits
77 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81edeb17d9 | ||
|
|
5982eb6495 | ||
|
|
38df29380a | ||
|
|
1f438bd40f | ||
|
|
392165432a | ||
|
|
e6bbb3d22e | ||
|
|
a6979fe14a | ||
|
|
bab10754d9 | ||
|
|
ac7ef1176a | ||
|
|
d6444fb7fc | ||
|
|
e223d69b36 | ||
|
|
05cc7a2eff | ||
|
|
8a12183c3b | ||
|
|
21b706b62d | ||
|
|
c5f151ab33 | ||
|
|
3860f1cf7f | ||
|
|
4e582b0c1d | ||
|
|
8396e00dd8 | ||
|
|
48babd417d | ||
|
|
22770f7e85 | ||
|
|
21b033227e | ||
|
|
93f587a6d3 | ||
|
|
8afb68f074 | ||
|
|
2e07f269b9 | ||
|
|
10c994155c | ||
|
|
fc9909c30a | ||
|
|
e35817577c | ||
|
|
9e3fe5d3f6 | ||
|
|
dc9217347e | ||
|
|
a7fed2ce67 | ||
|
|
de3b97355d | ||
|
|
8aa7084f01 | ||
|
|
0f469cad54 | ||
|
|
72e51c61f7 | ||
|
|
31590a8a3b | ||
|
|
24c2432d99 | ||
|
|
292870612c | ||
|
|
57659d9f38 | ||
|
|
2b8e4d3af0 | ||
|
|
08b6372a36 | ||
|
|
9c383559e0 | ||
|
|
c13c3bf956 | ||
|
|
47eeb8f4e9 | ||
|
|
e7c6874192 | ||
|
|
8d2c333b36 | ||
|
|
abc9bfebff | ||
|
|
94d6b8086b | ||
|
|
fa709636b4 | ||
|
|
60463e25a8 | ||
|
|
b8e3d215b8 | ||
|
|
d71c0ab4ac | ||
|
|
fcf75449b8 | ||
|
|
c21bda1649 | ||
|
|
03fffb25e2 | ||
|
|
1a7495a6dd | ||
|
|
3c1bb67ae1 | ||
|
|
5b9de8b6c0 | ||
|
|
ea0a73d168 | ||
|
|
4623cfa4bc | ||
|
|
9c2c56dc6a | ||
|
|
429c28c783 | ||
|
|
e5a9ff757f | ||
|
|
e53732b9b9 | ||
|
|
b84b676c89 | ||
|
|
3211f857d1 | ||
|
|
95ff1f1d80 | ||
|
|
af8997b567 | ||
|
|
0d67abde45 | ||
|
|
d74e2945f7 | ||
|
|
8914d06ab7 | ||
|
|
522f2379a6 | ||
|
|
7cb0bcb212 | ||
|
|
b1e7868db6 | ||
|
|
68e3c839c3 | ||
|
|
0723245085 | ||
|
|
9d64b9c0c0 | ||
|
|
d01f20f2fb |
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -1,5 +1,5 @@
|
|||||||
# Default owner
|
# Default owner
|
||||||
* @aardappel @dbaileychess derekbailey@google.com
|
* @dbaileychess derekbailey@google.com
|
||||||
|
|
||||||
# Prevent modification of this file
|
# Prevent modification of this file
|
||||||
.github/CODEOWNERS @dbaileychess derekbailey@google.com
|
.github/CODEOWNERS @dbaileychess derekbailey@google.com
|
||||||
|
|||||||
6
.github/dependabot.yml
vendored
Normal file
6
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
39
.github/workflows/build.yml
vendored
39
.github/workflows/build.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
|||||||
chmod +x flatc
|
chmod +x flatc
|
||||||
./flatc --version
|
./flatc --version
|
||||||
- name: upload build artifacts
|
- name: upload build artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: Linux flatc binary ${{ matrix.cxx }}
|
name: Linux flatc binary ${{ matrix.cxx }}
|
||||||
path: flatc
|
path: flatc
|
||||||
@@ -170,7 +170,7 @@ jobs:
|
|||||||
- name: test
|
- name: test
|
||||||
run: Release\flattests.exe
|
run: Release\flattests.exe
|
||||||
- name: upload build artifacts
|
- name: upload build artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: Windows flatc binary
|
name: Windows flatc binary
|
||||||
path: Release\flatc.exe
|
path: Release\flatc.exe
|
||||||
@@ -191,14 +191,13 @@ jobs:
|
|||||||
|
|
||||||
build-dotnet-windows:
|
build-dotnet-windows:
|
||||||
name: Build .NET Windows
|
name: Build .NET Windows
|
||||||
runs-on: windows-2022-64core
|
runs-on: windows-2022
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
configuration: [
|
configuration: [
|
||||||
'',
|
'',
|
||||||
'-p:UnsafeByteBuffer=true',
|
'-p:UnsafeByteBuffer=true',
|
||||||
# Fails two tests currently.
|
'-p:EnableSpanT=true,UnsafeByteBuffer=true'
|
||||||
#'-p:EnableSpanT=true,UnsafeByteBuffer=true'
|
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
@@ -209,7 +208,7 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
cd tests\FlatBuffers.Test
|
cd tests\FlatBuffers.Test
|
||||||
dotnet new sln --force --name FlatBuffers.Test
|
dotnet new sln --force --name FlatBuffers.Test --format sln
|
||||||
dotnet sln FlatBuffers.Test.sln add FlatBuffers.Test.csproj
|
dotnet sln FlatBuffers.Test.sln add FlatBuffers.Test.csproj
|
||||||
dotnet build -c Release ${{matrix.configuration}} FlatBuffers.Test.sln
|
dotnet build -c Release ${{matrix.configuration}} FlatBuffers.Test.sln
|
||||||
- name: Run net6.0
|
- name: Run net6.0
|
||||||
@@ -247,7 +246,7 @@ jobs:
|
|||||||
chmod +x Release/flatc
|
chmod +x Release/flatc
|
||||||
Release/flatc --version
|
Release/flatc --version
|
||||||
- name: upload build artifacts
|
- name: upload build artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: Mac flatc binary Intel
|
name: Mac flatc binary Intel
|
||||||
path: Release/flatc
|
path: Release/flatc
|
||||||
@@ -290,7 +289,7 @@ jobs:
|
|||||||
chmod +x Release/flatc
|
chmod +x Release/flatc
|
||||||
Release/flatc --version
|
Release/flatc --version
|
||||||
- name: upload build artifacts
|
- name: upload build artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: Mac flatc binary Universal
|
name: Mac flatc binary Universal
|
||||||
path: Release/flatc
|
path: Release/flatc
|
||||||
@@ -315,7 +314,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
- name: set up Java
|
- name: set up Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v5
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: 17
|
java-version: 17
|
||||||
@@ -374,7 +373,7 @@ jobs:
|
|||||||
- name: Run benchmarks
|
- name: Run benchmarks
|
||||||
run: ./flatbenchmark --benchmark_repetitions=5 --benchmark_display_aggregates_only=true --benchmark_out_format=console --benchmark_out=benchmarks/results_${{matrix.cxx}}
|
run: ./flatbenchmark --benchmark_repetitions=5 --benchmark_display_aggregates_only=true --benchmark_out_format=console --benchmark_out=benchmarks/results_${{matrix.cxx}}
|
||||||
- name: Upload benchmarks results
|
- name: Upload benchmarks results
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: Linux flatbenchmark results ${{matrix.cxx}}
|
name: Linux flatbenchmark results ${{matrix.cxx}}
|
||||||
path: benchmarks/results_${{matrix.cxx}}
|
path: benchmarks/results_${{matrix.cxx}}
|
||||||
@@ -395,7 +394,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
- name: set up Java
|
- name: set up Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v5
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: 17
|
java-version: 17
|
||||||
@@ -418,7 +417,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
- name: set up Java
|
- name: set up Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v5
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: 17
|
java-version: 17
|
||||||
@@ -447,7 +446,7 @@ jobs:
|
|||||||
|
|
||||||
build-rust-windows:
|
build-rust-windows:
|
||||||
name: Build Rust Windows
|
name: Build Rust Windows
|
||||||
runs-on: windows-2022-64core
|
runs-on: windows-2022
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
- name: test
|
- name: test
|
||||||
@@ -496,7 +495,7 @@ jobs:
|
|||||||
name: Test Swift Linux
|
name: Test Swift Linux
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
swift: ["5.10", "6.1", "6.2"]
|
swift: ["6.0", "6.1", "6.2"]
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
@@ -535,7 +534,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
swift sdk list
|
swift sdk list
|
||||||
swift build --build-tests --swift-sdk swift-6.2.1-RELEASE_wasm
|
swift build --build-tests --swift-sdk swift-6.2.1-RELEASE_wasm
|
||||||
wasmtime --dir . .build/wasm32-unknown-wasip1/debug/FlatBuffers.Test.Swift.WasmPackageTests.xctest
|
wasmtime --dir . .build/wasm32-unknown-wasip1/debug/FlatBuffers.Test.Swift.WasmPackageTests.xctest --testing-library swift-testing
|
||||||
|
|
||||||
build-ts:
|
build-ts:
|
||||||
name: Build TS
|
name: Build TS
|
||||||
@@ -546,7 +545,7 @@ jobs:
|
|||||||
# FIXME: make test script not rely on flatc
|
# FIXME: make test script not rely on flatc
|
||||||
run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF . && make -j
|
run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF . && make -j
|
||||||
- name: pnpm
|
- name: pnpm
|
||||||
run: npm install -g pnpm esbuild
|
run: npm install -g pnpm@10
|
||||||
- name: deps
|
- name: deps
|
||||||
run: pnpm i
|
run: pnpm i
|
||||||
- name: compile
|
- name: compile
|
||||||
@@ -592,11 +591,16 @@ jobs:
|
|||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
|
# Explicitly use 8.5.1 until we can update or https://github.com/actions/runner-images/issues/13564 is fixed.
|
||||||
|
- name: Set env
|
||||||
|
run: >
|
||||||
|
echo "USE_BAZEL_VERSION=8.5.1" >> $GITHUB_ENV
|
||||||
- name: bazel build
|
- name: bazel build
|
||||||
run: >
|
run: >
|
||||||
bazel build
|
bazel build
|
||||||
//:flatc
|
//:flatc
|
||||||
//:flatbuffers
|
//:flatbuffers
|
||||||
|
//tests:flatbuffers_test
|
||||||
- name: bazel test
|
- name: bazel test
|
||||||
run: >
|
run: >
|
||||||
bazel test
|
bazel test
|
||||||
@@ -633,8 +637,7 @@ jobs:
|
|||||||
actions: read # To read the workflow path.
|
actions: read # To read the workflow path.
|
||||||
id-token: write # To sign the provenance.
|
id-token: write # To sign the provenance.
|
||||||
contents: write # To add assets to a release.
|
contents: write # To add assets to a release.
|
||||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.2.1
|
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
|
||||||
with:
|
with:
|
||||||
base64-subjects: "${{ needs.release-digests.outputs.digests }}"
|
base64-subjects: "${{ needs.release-digests.outputs.digests }}"
|
||||||
upload-assets: true # Optional: Upload to a new release
|
upload-assets: true # Optional: Upload to a new release
|
||||||
compile-generator: true # Workaround for https://github.com/slsa-framework/slsa-github-generator/issues/1163
|
|
||||||
|
|||||||
4
.github/workflows/docs.yml
vendored
4
.github/workflows/docs.yml
vendored
@@ -21,11 +21,11 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
git config user.name github-actions[bot]
|
git config user.name github-actions[bot]
|
||||||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
|
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
|
||||||
- uses: actions/cache@v4
|
- uses: actions/cache@v5
|
||||||
with:
|
with:
|
||||||
key: mkdocs-material-${{ env.cache_id }}
|
key: mkdocs-material-${{ env.cache_id }}
|
||||||
path: .cache
|
path: .cache
|
||||||
|
|||||||
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
|||||||
language: c++
|
language: c++
|
||||||
fuzz-seconds: 60
|
fuzz-seconds: 60
|
||||||
- name: Upload Crash
|
- name: Upload Crash
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v7
|
||||||
if: failure() && steps.build.outcome == 'success'
|
if: failure() && steps.build.outcome == 'success'
|
||||||
with:
|
with:
|
||||||
name: artifacts
|
name: artifacts
|
||||||
|
|||||||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: '20.x'
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
@@ -30,7 +30,7 @@ jobs:
|
|||||||
working-directory: ./python
|
working-directory: ./python
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: '3.10'
|
python-version: '3.10'
|
||||||
|
|
||||||
|
|||||||
@@ -305,8 +305,7 @@ function(flatbuffers_generate_headers)
|
|||||||
${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
|
${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
|
||||||
add_dependencies(
|
add_dependencies(
|
||||||
${FLATBUFFERS_GENERATE_HEADERS_TARGET}
|
${FLATBUFFERS_GENERATE_HEADERS_TARGET}
|
||||||
${FLATC}
|
${FLATC_TARGET})
|
||||||
${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
|
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
${FLATBUFFERS_GENERATE_HEADERS_TARGET}
|
${FLATBUFFERS_GENERATE_HEADERS_TARGET}
|
||||||
INTERFACE ${generated_target_dir})
|
INTERFACE ${generated_target_dir})
|
||||||
|
|||||||
@@ -559,6 +559,7 @@ if(FLATBUFFERS_BUILD_TESTS)
|
|||||||
compile_schema_for_test(tests/64bit/evolution/v1.fbs "${FLATC_OPT_COMP}")
|
compile_schema_for_test(tests/64bit/evolution/v1.fbs "${FLATC_OPT_COMP}")
|
||||||
compile_schema_for_test(tests/64bit/evolution/v2.fbs "${FLATC_OPT_COMP}")
|
compile_schema_for_test(tests/64bit/evolution/v2.fbs "${FLATC_OPT_COMP}")
|
||||||
compile_schema_for_test(tests/union_underlying_type_test.fbs "${FLATC_OPT_SCOPED_ENUMS}")
|
compile_schema_for_test(tests/union_underlying_type_test.fbs "${FLATC_OPT_SCOPED_ENUMS}")
|
||||||
|
compile_schema_for_test(tests/cross_namespace_pack_test.fbs "${FLATC_OPT_COMP}")
|
||||||
|
|
||||||
if(FLATBUFFERS_CODE_SANITIZE)
|
if(FLATBUFFERS_CODE_SANITIZE)
|
||||||
add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
|
add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
|
||||||
|
|||||||
14
MODULE.bazel
14
MODULE.bazel
@@ -7,7 +7,7 @@ module(
|
|||||||
|
|
||||||
bazel_dep(
|
bazel_dep(
|
||||||
name = "aspect_bazel_lib",
|
name = "aspect_bazel_lib",
|
||||||
version = "2.11.0",
|
version = "2.14.0",
|
||||||
)
|
)
|
||||||
bazel_dep(
|
bazel_dep(
|
||||||
name = "aspect_rules_esbuild",
|
name = "aspect_rules_esbuild",
|
||||||
@@ -23,16 +23,16 @@ bazel_dep(
|
|||||||
)
|
)
|
||||||
bazel_dep(
|
bazel_dep(
|
||||||
name = "grpc",
|
name = "grpc",
|
||||||
version = "1.70.1",
|
version = "1.76.0",
|
||||||
repo_name = "com_github_grpc_grpc",
|
repo_name = "com_github_grpc_grpc",
|
||||||
)
|
)
|
||||||
bazel_dep(
|
bazel_dep(
|
||||||
name = "platforms",
|
name = "platforms",
|
||||||
version = "0.0.10",
|
version = "0.0.11",
|
||||||
)
|
)
|
||||||
bazel_dep(
|
bazel_dep(
|
||||||
name = "rules_cc",
|
name = "rules_cc",
|
||||||
version = "0.0.16",
|
version = "0.1.1",
|
||||||
)
|
)
|
||||||
bazel_dep(
|
bazel_dep(
|
||||||
name = "rules_go",
|
name = "rules_go",
|
||||||
@@ -49,7 +49,8 @@ bazel_dep(
|
|||||||
)
|
)
|
||||||
bazel_dep(
|
bazel_dep(
|
||||||
name = "rules_swift",
|
name = "rules_swift",
|
||||||
version = "2.1.1",
|
version = "3.1.2",
|
||||||
|
max_compatibility_level = 3,
|
||||||
repo_name = "build_bazel_rules_swift",
|
repo_name = "build_bazel_rules_swift",
|
||||||
)
|
)
|
||||||
bazel_dep(
|
bazel_dep(
|
||||||
@@ -62,9 +63,6 @@ npm.npm_translate_lock(
|
|||||||
name = "flatbuffers_npm",
|
name = "flatbuffers_npm",
|
||||||
npmrc = "//:.npmrc",
|
npmrc = "//:.npmrc",
|
||||||
pnpm_lock = "//ts:pnpm-lock.yaml",
|
pnpm_lock = "//ts:pnpm-lock.yaml",
|
||||||
# Override the Bazel package where pnpm-lock.yaml is located and link
|
|
||||||
# to the specified package instead.
|
|
||||||
root_package = "ts",
|
|
||||||
verify_node_modules_ignored = "//:.bazelignore",
|
verify_node_modules_ignored = "//:.bazelignore",
|
||||||
)
|
)
|
||||||
use_repo(npm, "flatbuffers_npm")
|
use_repo(npm, "flatbuffers_npm")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// swift-tools-version:5.10
|
// swift-tools-version:6.0
|
||||||
/*
|
/*
|
||||||
* Copyright 2020 Google Inc. All rights reserved.
|
* Copyright 2020 Google Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -36,14 +36,17 @@ let package = Package(
|
|||||||
.target(
|
.target(
|
||||||
name: "FlatBuffers",
|
name: "FlatBuffers",
|
||||||
dependencies: ["Common"],
|
dependencies: ["Common"],
|
||||||
path: "swift/Sources/FlatBuffers"),
|
path: "swift/Sources/FlatBuffers",
|
||||||
|
swiftSettings: .settings),
|
||||||
.target(
|
.target(
|
||||||
name: "FlexBuffers",
|
name: "FlexBuffers",
|
||||||
dependencies: ["Common"],
|
dependencies: ["Common"],
|
||||||
path: "swift/Sources/FlexBuffers"),
|
path: "swift/Sources/FlexBuffers",
|
||||||
|
swiftSettings: .settings),
|
||||||
.target(
|
.target(
|
||||||
name: "Common",
|
name: "Common",
|
||||||
path: "swift/Sources/Common"),
|
path: "swift/Sources/Common",
|
||||||
|
swiftSettings: .settings),
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: "FlatbuffersTests",
|
name: "FlatbuffersTests",
|
||||||
dependencies: .dependencies,
|
dependencies: .dependencies,
|
||||||
@@ -52,7 +55,14 @@ let package = Package(
|
|||||||
name: "FlexbuffersTests",
|
name: "FlexbuffersTests",
|
||||||
dependencies: ["FlexBuffers"],
|
dependencies: ["FlexBuffers"],
|
||||||
path: "tests/swift/Tests/Flexbuffers"),
|
path: "tests/swift/Tests/Flexbuffers"),
|
||||||
])
|
],
|
||||||
|
swiftLanguageModes: [.v6])
|
||||||
|
|
||||||
|
extension Array where Element == SwiftSetting {
|
||||||
|
static var settings: [SwiftSetting] {
|
||||||
|
[.enableUpcomingFeature("ExistentialAny")]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension Array where Element == Package.Dependency {
|
extension Array where Element == Package.Dependency {
|
||||||
static var dependencies: [Package.Dependency] {
|
static var dependencies: [Package.Dependency] {
|
||||||
@@ -60,7 +70,12 @@ extension Array where Element == Package.Dependency {
|
|||||||
[]
|
[]
|
||||||
#else
|
#else
|
||||||
// Test only Dependency
|
// Test only Dependency
|
||||||
[.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.4.1")]
|
[
|
||||||
|
.package(url: "https://github.com/grpc/grpc-swift-2.git", from: "2.0.0"),
|
||||||
|
.package(
|
||||||
|
url: "https://github.com/grpc/grpc-swift-nio-transport.git",
|
||||||
|
from: "2.0.0"),
|
||||||
|
]
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,7 +87,10 @@ extension Array where Element == PackageDescription.Target.Dependency {
|
|||||||
#else
|
#else
|
||||||
// Test only Dependency
|
// Test only Dependency
|
||||||
[
|
[
|
||||||
.product(name: "GRPC", package: "grpc-swift"),
|
.product(name: "GRPCCore", package: "grpc-swift-2"),
|
||||||
|
.product(
|
||||||
|
name: "GRPCNIOTransportHTTP2",
|
||||||
|
package: "grpc-swift-nio-transport"),
|
||||||
"FlatBuffers",
|
"FlatBuffers",
|
||||||
]
|
]
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ let benchmarks = {
|
|||||||
for _ in benchmark.scaledIterations {
|
for _ in benchmark.scaledIterations {
|
||||||
blackHole(ByteBuffer(assumingMemoryBound: memory, capacity: Int(oneGB)))
|
blackHole(ByteBuffer(assumingMemoryBound: memory, capacity: Int(oneGB)))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark("Clearing 1GB", configuration: singleConfiguration) { benchmark in
|
Benchmark("Clearing 1GB", configuration: singleConfiguration) { benchmark in
|
||||||
@@ -105,6 +106,7 @@ let benchmarks = {
|
|||||||
for _ in benchmark.scaledIterations {
|
for _ in benchmark.scaledIterations {
|
||||||
blackHole(fb.clear())
|
blackHole(fb.clear())
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark("Strings 10") { benchmark in
|
Benchmark("Strings 10") { benchmark in
|
||||||
@@ -113,6 +115,7 @@ let benchmarks = {
|
|||||||
for _ in benchmark.scaledIterations {
|
for _ in benchmark.scaledIterations {
|
||||||
blackHole(fb.create(string: str10))
|
blackHole(fb.create(string: str10))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark("Strings 100") { benchmark in
|
Benchmark("Strings 100") { benchmark in
|
||||||
@@ -121,6 +124,7 @@ let benchmarks = {
|
|||||||
for _ in benchmark.scaledIterations {
|
for _ in benchmark.scaledIterations {
|
||||||
blackHole(fb.create(string: str100))
|
blackHole(fb.create(string: str100))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark("Vector 1 Bytes") { benchmark in
|
Benchmark("Vector 1 Bytes") { benchmark in
|
||||||
@@ -129,6 +133,7 @@ let benchmarks = {
|
|||||||
for _ in benchmark.scaledIterations {
|
for _ in benchmark.scaledIterations {
|
||||||
blackHole(fb.createVector(bytes: bytes))
|
blackHole(fb.createVector(bytes: bytes))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark("Vector 1 Ints") { benchmark in
|
Benchmark("Vector 1 Ints") { benchmark in
|
||||||
@@ -137,6 +142,7 @@ let benchmarks = {
|
|||||||
for _ in benchmark.scaledIterations {
|
for _ in benchmark.scaledIterations {
|
||||||
blackHole(fb.createVector(ints))
|
blackHole(fb.createVector(ints))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark("Vector 100 Ints") { benchmark in
|
Benchmark("Vector 100 Ints") { benchmark in
|
||||||
@@ -145,6 +151,7 @@ let benchmarks = {
|
|||||||
for i in benchmark.scaledIterations {
|
for i in benchmark.scaledIterations {
|
||||||
blackHole(fb.createVector(ints))
|
blackHole(fb.createVector(ints))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark("Vector 100 Bytes") { benchmark in
|
Benchmark("Vector 100 Bytes") { benchmark in
|
||||||
@@ -153,6 +160,7 @@ let benchmarks = {
|
|||||||
for i in benchmark.scaledIterations {
|
for i in benchmark.scaledIterations {
|
||||||
blackHole(fb.createVector(bytes))
|
blackHole(fb.createVector(bytes))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark("Vector 100 ContiguousBytes") { benchmark in
|
Benchmark("Vector 100 ContiguousBytes") { benchmark in
|
||||||
@@ -161,6 +169,7 @@ let benchmarks = {
|
|||||||
for i in benchmark.scaledIterations {
|
for i in benchmark.scaledIterations {
|
||||||
blackHole(fb.createVector(bytes: bytes))
|
blackHole(fb.createVector(bytes: bytes))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark(
|
Benchmark(
|
||||||
@@ -178,6 +187,7 @@ let benchmarks = {
|
|||||||
fb.add(offset: off, at: 8)
|
fb.add(offset: off, at: 8)
|
||||||
blackHole(fb.endTable(at: s))
|
blackHole(fb.endTable(at: s))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark(
|
Benchmark(
|
||||||
@@ -190,6 +200,7 @@ let benchmarks = {
|
|||||||
let s = fb.startTable(with: 4)
|
let s = fb.startTable(with: 4)
|
||||||
blackHole(fb.endTable(at: s))
|
blackHole(fb.endTable(at: s))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark("Struct") { benchmark in
|
Benchmark("Struct") { benchmark in
|
||||||
@@ -198,6 +209,7 @@ let benchmarks = {
|
|||||||
for _ in benchmark.scaledIterations {
|
for _ in benchmark.scaledIterations {
|
||||||
blackHole(fb.create(struct: array.first!))
|
blackHole(fb.create(struct: array.first!))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark("Structs") { benchmark in
|
Benchmark("Structs") { benchmark in
|
||||||
@@ -219,6 +231,7 @@ let benchmarks = {
|
|||||||
fb.add(offset: vector, at: 4)
|
fb.add(offset: vector, at: 4)
|
||||||
let root = Offset(offset: fb.endTable(at: start))
|
let root = Offset(offset: fb.endTable(at: start))
|
||||||
blackHole(fb.finish(offset: root))
|
blackHole(fb.finish(offset: root))
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark("Vector of Offsets") { benchmark in
|
Benchmark("Vector of Offsets") { benchmark in
|
||||||
@@ -239,12 +252,15 @@ let benchmarks = {
|
|||||||
fb.add(offset: off, at: 2)
|
fb.add(offset: off, at: 2)
|
||||||
blackHole(fb.endTable(at: s))
|
blackHole(fb.endTable(at: s))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
|
|
||||||
Benchmark("Reading Doubles") { benchmark in
|
Benchmark("Reading Doubles") { benchmark in
|
||||||
let byteBuffer = ByteBuffer(data: data)
|
let byteBuffer = ByteBuffer(data: data)
|
||||||
|
benchmark.startMeasurement()
|
||||||
for _ in benchmark.scaledIterations {
|
for _ in benchmark.scaledIterations {
|
||||||
blackHole(byteBuffer.read(def: Double.self, position: 0))
|
blackHole(byteBuffer.read(def: Double.self, position: 0))
|
||||||
}
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Benchmark
|
||||||
|
import FlexBuffers
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
let benchmarks = {
|
||||||
|
let data = {
|
||||||
|
var array = [8888.88, 8888.88]
|
||||||
|
var data = Data()
|
||||||
|
array.withUnsafeBytes { ptr in
|
||||||
|
data.append(contentsOf: ptr)
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}()
|
||||||
|
let ints: [Int32] = Array(repeating: 42, count: 100)
|
||||||
|
let str10 = (0...9).map { _ -> String in "x" }.joined()
|
||||||
|
let str100 = (0...99).map { _ -> String in "x" }.joined()
|
||||||
|
|
||||||
|
// A representative map: 50 keyed scalars, a keyed string and a keyed vector
|
||||||
|
// of 100 scalars. Used for the realistic decode benchmarks.
|
||||||
|
let mapBuffer: ByteBuffer = {
|
||||||
|
var fbx = FlexBuffersWriter(initialSize: 1 << 16)
|
||||||
|
fbx.map {
|
||||||
|
for i in 0..<50 { $0.add(int: i, key: "i\(i)") }
|
||||||
|
$0.add(string: "hello world", key: "s")
|
||||||
|
$0.vector(key: "v") { v in
|
||||||
|
for x in 0..<100 { v.add(int: x) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fbx.finish()
|
||||||
|
return fbx.sizedByteBuffer
|
||||||
|
}()
|
||||||
|
|
||||||
|
let metrics: [BenchmarkMetric] = [
|
||||||
|
.cpuTotal,
|
||||||
|
.wallClock,
|
||||||
|
.mallocCountTotal,
|
||||||
|
.releaseCount,
|
||||||
|
.peakMemoryResident,
|
||||||
|
]
|
||||||
|
let maxIterations = 1_000_000
|
||||||
|
let maxDuration: Duration = .seconds(3)
|
||||||
|
let megaConfiguration: Benchmark.Configuration = .init(
|
||||||
|
metrics: metrics,
|
||||||
|
warmupIterations: 1,
|
||||||
|
scalingFactor: .mega,
|
||||||
|
maxDuration: maxDuration,
|
||||||
|
maxIterations: maxIterations)
|
||||||
|
|
||||||
|
Benchmark.defaultConfiguration = megaConfiguration
|
||||||
|
|
||||||
|
// Decode (read path)
|
||||||
|
|
||||||
|
// Raw scalar read: isolates `read<T: BitwiseCopyable>` and the `let` blob.
|
||||||
|
Benchmark("Reading Doubles") { benchmark in
|
||||||
|
let byteBuffer = ByteBuffer(data: data)
|
||||||
|
benchmark.startMeasurement()
|
||||||
|
for _ in benchmark.scaledIterations {
|
||||||
|
blackHole(byteBuffer.read(def: Double.self, position: 0))
|
||||||
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Realistic decode: resolve root map and read a keyed scalar.
|
||||||
|
Benchmark("Decode Map Scalar") { benchmark in
|
||||||
|
benchmark.startMeasurement()
|
||||||
|
for _ in benchmark.scaledIterations {
|
||||||
|
let map = try! getRoot(buffer: mapBuffer)!.map!
|
||||||
|
blackHole(map["i25"]?.int)
|
||||||
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Realistic decode: resolve root map and read a keyed string.
|
||||||
|
Benchmark("Decode Map String") { benchmark in
|
||||||
|
benchmark.startMeasurement()
|
||||||
|
for _ in benchmark.scaledIterations {
|
||||||
|
let map = try! getRoot(buffer: mapBuffer)!.map!
|
||||||
|
blackHole(map["s"]?.string())
|
||||||
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Realistic decode: resolve a nested vector and sum its scalars.
|
||||||
|
Benchmark("Decode Vector") { benchmark in
|
||||||
|
benchmark.startMeasurement()
|
||||||
|
for _ in benchmark.scaledIterations {
|
||||||
|
let map = try! getRoot(buffer: mapBuffer)!.map!
|
||||||
|
let vector = map["v"]!.vector!
|
||||||
|
var sum: Int64 = 0
|
||||||
|
for i in 0..<vector.count {
|
||||||
|
sum &+= vector[i]?.int ?? 0
|
||||||
|
}
|
||||||
|
blackHole(sum)
|
||||||
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode (write path)
|
||||||
|
// Writers are reused with `reset(keepingCapacity:)` so per-iteration
|
||||||
|
// allocation does not dominate and mask the write-path cost (which is what
|
||||||
|
// the `@exclusivity(unchecked)` storage pointer affects).
|
||||||
|
|
||||||
|
Benchmark("Strings 10") { benchmark in
|
||||||
|
var fbx = FlexBuffersWriter(initialSize: 1 << 20)
|
||||||
|
benchmark.startMeasurement()
|
||||||
|
for _ in benchmark.scaledIterations {
|
||||||
|
fbx.add(string: str10)
|
||||||
|
fbx.finish()
|
||||||
|
blackHole(fbx.sizedByteBuffer)
|
||||||
|
fbx.reset(keepingCapacity: true)
|
||||||
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
|
}
|
||||||
|
|
||||||
|
Benchmark("Strings 100") { benchmark in
|
||||||
|
var fbx = FlexBuffersWriter(initialSize: 1 << 20)
|
||||||
|
benchmark.startMeasurement()
|
||||||
|
for _ in benchmark.scaledIterations {
|
||||||
|
fbx.add(string: str100)
|
||||||
|
fbx.finish()
|
||||||
|
blackHole(fbx.sizedByteBuffer)
|
||||||
|
fbx.reset(keepingCapacity: true)
|
||||||
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
|
}
|
||||||
|
|
||||||
|
Benchmark("Encoding Vector Of Ints") { benchmark in
|
||||||
|
var fbx = FlexBuffersWriter(initialSize: 1 << 20)
|
||||||
|
benchmark.startMeasurement()
|
||||||
|
for _ in benchmark.scaledIterations {
|
||||||
|
fbx.vector {
|
||||||
|
$0.create(vector: ints)
|
||||||
|
}
|
||||||
|
fbx.finish()
|
||||||
|
blackHole(fbx.sizedByteBuffer)
|
||||||
|
fbx.reset(keepingCapacity: true)
|
||||||
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
|
}
|
||||||
|
|
||||||
|
Benchmark("Encoding Map") { benchmark in
|
||||||
|
var fbx = FlexBuffersWriter(initialSize: 1 << 20)
|
||||||
|
benchmark.startMeasurement()
|
||||||
|
for _ in benchmark.scaledIterations {
|
||||||
|
fbx.map {
|
||||||
|
for i in 0..<50 { $0.add(int: i, key: "i\(i)") }
|
||||||
|
$0.add(string: "hello world", key: "s")
|
||||||
|
$0.vector(key: "v") { v in
|
||||||
|
for x in 0..<100 { v.add(int: x) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fbx.finish()
|
||||||
|
blackHole(fbx.sizedByteBuffer)
|
||||||
|
fbx.reset(keepingCapacity: true)
|
||||||
|
}
|
||||||
|
benchmark.stopMeasurement()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,4 +39,14 @@ let package = Package(
|
|||||||
plugins: [
|
plugins: [
|
||||||
.plugin(name: "BenchmarkPlugin", package: "package-benchmark"),
|
.plugin(name: "BenchmarkPlugin", package: "package-benchmark"),
|
||||||
]),
|
]),
|
||||||
|
.executableTarget(
|
||||||
|
name: "FlexBuffersBenchmarks",
|
||||||
|
dependencies: [
|
||||||
|
.product(name: "FlexBuffers", package: "flatbuffers"),
|
||||||
|
.product(name: "Benchmark", package: "package-benchmark"),
|
||||||
|
],
|
||||||
|
path: "Benchmarks/FlexBuffersBenchmarks",
|
||||||
|
plugins: [
|
||||||
|
.plugin(name: "BenchmarkPlugin", package: "package-benchmark"),
|
||||||
|
]),
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import 'types.dart';
|
|||||||
|
|
||||||
/// The main builder class for creation of a FlexBuffer.
|
/// The main builder class for creation of a FlexBuffer.
|
||||||
class Builder {
|
class Builder {
|
||||||
final ByteData _buffer;
|
ByteData _buffer;
|
||||||
List<_StackValue> _stack = [];
|
List<_StackValue> _stack = [];
|
||||||
List<_StackPointer> _stackPointers = [];
|
List<_StackPointer> _stackPointers = [];
|
||||||
int _offset = 0;
|
int _offset = 0;
|
||||||
@@ -506,6 +506,7 @@ class Builder {
|
|||||||
if (prevSize < size) {
|
if (prevSize < size) {
|
||||||
final newBuf = ByteData(size);
|
final newBuf = ByteData(size);
|
||||||
newBuf.buffer.asUint8List().setAll(0, _buffer.buffer.asUint8List());
|
newBuf.buffer.asUint8List().setAll(0, _buffer.buffer.asUint8List());
|
||||||
|
_buffer = newBuf;
|
||||||
}
|
}
|
||||||
return newOffset;
|
return newOffset;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -318,6 +318,21 @@ void main() {
|
|||||||
1,
|
1,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
// Default buffer is 2048 bytes, add 2300 bytes of strings that force it
|
||||||
|
// to grow.
|
||||||
|
final s1 = 'A' * 1000;
|
||||||
|
final s2 = 'B' * 800;
|
||||||
|
final s3 = 'C' * 500;
|
||||||
|
|
||||||
|
var flx = Builder()
|
||||||
|
..startVector()
|
||||||
|
..addString(s1)
|
||||||
|
..addString(s2)
|
||||||
|
..addString(s3)
|
||||||
|
..end();
|
||||||
|
expect(flx.finish().length, 2323);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('build map', () {
|
test('build map', () {
|
||||||
|
|||||||
@@ -79,11 +79,12 @@ list of `FILES...`.
|
|||||||
`myschema.fbs` to JSON:
|
`myschema.fbs` to JSON:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
flatc --json myschema.fbs mydata.bin
|
flatc --json myschema.fbs -- mydata.bin
|
||||||
```
|
```
|
||||||
|
|
||||||
This will generate a `mydata.json` file.
|
This will generate a `mydata.json` file. If there is no
|
||||||
|
[`file_identifier`](schema.md/#file-identification-and-extension) defined
|
||||||
|
for this schema, you will need to use the `--raw-binary` option.
|
||||||
|
|
||||||
### Additional options
|
### Additional options
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ a `char *` array, which you pass to `GetMonster()`.
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "monster_test_generate.h"
|
#include "monster_test_generated.h"
|
||||||
#include <iostream> // C++ header file for printing
|
#include <iostream> // C++ header file for printing
|
||||||
#include <fstream> // C++ header file for file access
|
#include <fstream> // C++ header file for file access
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,61 @@ convenient accessors for all fields, e.g. `hp()`, `mana()`, etc:
|
|||||||
|
|
||||||
*Note: That we never stored a `mana` value, so it will return the default.*
|
*Note: That we never stored a `mana` value, so it will return the default.*
|
||||||
|
|
||||||
|
## Fallible API and Custom Allocators
|
||||||
|
|
||||||
|
Every `FlatBufferBuilder` method that may allocate has a `try_*` counterpart
|
||||||
|
(e.g. `try_create_string`, `try_push`, `try_finish`) that returns
|
||||||
|
`Result<T, A::Error>` instead of panicking. This is useful when allocation
|
||||||
|
failures must be handled gracefully: for example in `no_std` environments or
|
||||||
|
with fixed-capacity buffers.
|
||||||
|
|
||||||
|
The existing panicking methods are unchanged and remain the simplest option
|
||||||
|
when using the default allocator.
|
||||||
|
|
||||||
|
#### Custom allocators
|
||||||
|
|
||||||
|
Implement the `Allocator` trait and pass it to `FlatBufferBuilder::new_in()`:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs}
|
||||||
|
use flatbuffers::{Allocator, FlatBufferBuilder};
|
||||||
|
|
||||||
|
struct MyAllocator { /* ... */ }
|
||||||
|
|
||||||
|
unsafe impl Allocator for MyAllocator {
|
||||||
|
type Error = MyError;
|
||||||
|
fn grow_downwards(&mut self) -> Result<(), Self::Error> { /* ... */ }
|
||||||
|
fn len(&self) -> usize { /* ... */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
let alloc = MyAllocator::new(/* ... */);
|
||||||
|
let mut builder = FlatBufferBuilder::new_in(alloc);
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The built-in `DefaultAllocator` uses `Vec<u8>` and sets `Error = Infallible`,
|
||||||
|
so the `try_*` methods on a default builder can never fail.
|
||||||
|
|
||||||
|
#### Example: building a buffer with error propagation
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs}
|
||||||
|
fn build<A: flatbuffers::Allocator>(
|
||||||
|
builder: &mut FlatBufferBuilder<A>,
|
||||||
|
) -> Result<(), A::Error> {
|
||||||
|
let name = builder.try_create_string("Orc")?;
|
||||||
|
let inventory = builder.try_create_vector(&[0u8, 1, 2, 3, 4])?;
|
||||||
|
|
||||||
|
let table_start = builder.start_table();
|
||||||
|
builder.try_push_slot_always(Monster::VT_NAME, name)?;
|
||||||
|
builder.try_push_slot_always(Monster::VT_INVENTORY, inventory)?;
|
||||||
|
builder.try_push_slot(Monster::VT_HP, 80i16, 100)?;
|
||||||
|
let root = builder.try_end_table(table_start)?;
|
||||||
|
|
||||||
|
builder.try_finish(root, None)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
See the `FlatBufferBuilder` rustdoc for the full list of `try_*` methods.
|
||||||
|
|
||||||
## Direct memory access
|
## Direct memory access
|
||||||
|
|
||||||
As you can see from the above examples, all elements in a buffer are
|
As you can see from the above examples, all elements in a buffer are
|
||||||
@@ -205,6 +260,47 @@ And example of usage, for the time being, can be found in
|
|||||||
- Safe getters in [SafeBuffer](https://docs.rs/flatbuffers-reflection/latest/flatbuffers_reflection/struct.SafeBuffer.html),
|
- Safe getters in [SafeBuffer](https://docs.rs/flatbuffers-reflection/latest/flatbuffers_reflection/struct.SafeBuffer.html),
|
||||||
which does verification when constructed so you can use it for any data source
|
which does verification when constructed so you can use it for any data source
|
||||||
|
|
||||||
|
## Buffer pre allocation in a latency-sensitive context
|
||||||
|
|
||||||
|
In latency-sensitive applications, dynamic memory allocations can introduce unpredictable latency spikes. The `FlatBufferBuilder` internally uses several `Vec`s that may reallocate during serialization:
|
||||||
|
|
||||||
|
- The backing buffer for the FlatBuffer data
|
||||||
|
- `field_locs` for tracking field locations within tables
|
||||||
|
- `written_vtable_revpos` for deduplicating vtables
|
||||||
|
- `strings_pool` for shared string interning
|
||||||
|
|
||||||
|
To avoid allocations during serialization, you can preallocate all internal vectors upfront using the `with_internal_capacity` constructor:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs}
|
||||||
|
// Preallocate: 1KB buffer, 8 field locations, 16 vtables, 32 shared strings
|
||||||
|
let mut builder = FlatBufferBuilder::with_internal_capacity(1024, 8, 16, 32);
|
||||||
|
|
||||||
|
// All subsequent operations will not allocate (if capacities are sufficient)
|
||||||
|
let name = builder.create_shared_string("MyMonster");
|
||||||
|
// ... build your FlatBuffer ...
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
There are three variants available:
|
||||||
|
|
||||||
|
- `with_internal_capacity(size, field_locs, vtables, strings)` - Creates a new builder with all capacities preallocated
|
||||||
|
- `from_vec_with_internal_capacity(buffer, field_locs, vtables, strings)` - Reuses an existing `Vec<u8>` as the backing buffer
|
||||||
|
- `new_in_with_internal_capacity(allocator, field_locs, vtables, strings)` - Uses a custom `Allocator` with preallocated internal vecs
|
||||||
|
|
||||||
|
When combined with `reset()`, you can reuse the same builder across multiple serializations without any allocations after the initial setup:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs}
|
||||||
|
let mut builder = FlatBufferBuilder::with_internal_capacity(1024, 8, 16, 32);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// Build a FlatBuffer (allocation-free if capacities are sufficient)
|
||||||
|
let data = build_message(&mut builder);
|
||||||
|
send(data);
|
||||||
|
|
||||||
|
// Reset for reuse - clears state but retains allocated capacity
|
||||||
|
builder.reset();
|
||||||
|
}
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
## Useful tools created by others
|
## Useful tools created by others
|
||||||
|
|
||||||
* [flatc-rust](https://github.com/frol/flatc-rust) - FlatBuffers compiler
|
* [flatc-rust](https://github.com/frol/flatc-rust) - FlatBuffers compiler
|
||||||
|
|||||||
@@ -427,9 +427,6 @@ Current understood attributes:
|
|||||||
it won't be accessible anymore by newer code. Note that if you deprecate a
|
it won't be accessible anymore by newer code. Note that if you deprecate a
|
||||||
field that was previous required, old code may fail to validate new data (when
|
field that was previous required, old code may fail to validate new data (when
|
||||||
using the optional verifier).
|
using the optional verifier).
|
||||||
|
|
||||||
### `required`
|
|
||||||
|
|
||||||
- `required` (on a non-scalar table field): this field must always be set. By
|
- `required` (on a non-scalar table field): this field must always be set. By
|
||||||
default, fields do not need to be present in the binary. This is desirable, as
|
default, fields do not need to be present in the binary. This is desirable, as
|
||||||
it helps with forwards/backwards compatibility, and flexibility of data
|
it helps with forwards/backwards compatibility, and flexibility of data
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Simple mutation | Yes | Yes | Yes | Yes | No | No
|
|||||||
Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No | No
|
Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No | No
|
||||||
Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No | Yes
|
Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No | Yes
|
||||||
Native Object API | Yes | No | Yes | Yes | Yes | Yes | Yes | No | No | Yes | No | No | Yes
|
Native Object API | Yes | No | Yes | Yes | Yes | Yes | Yes | No | No | Yes | No | No | Yes
|
||||||
Optional Scalars | Yes | Yes | Yes | No | No | Yes | Yes | Yes | No | No | Yes | Yes | Yes
|
Optional Scalars | Yes | Yes | Yes | Yes | No | Yes | Yes | Yes | No | No | Yes | Yes | Yes
|
||||||
Flexbuffers | Yes | Yes | ? | ? | ? | ? | ? | ? | ? | ? | ? | Yes | Yes
|
Flexbuffers | Yes | Yes | ? | ? | ? | ? | ? | ? | ? | ? | ? | Yes | Yes
|
||||||
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes | Yes
|
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes | Yes
|
||||||
Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | No | No | Yes | No
|
Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | No | No | Yes | No
|
||||||
|
|||||||
@@ -1134,12 +1134,8 @@ The Builder provides multiple ways to create `vectors`.
|
|||||||
=== "Python"
|
=== "Python"
|
||||||
|
|
||||||
```py
|
```py
|
||||||
# Create a FlatBuffer vector and prepend the weapons.
|
# Use the generated helper to create the weapons vector from offsets.
|
||||||
# Note: Since we prepend the data, prepend them in reverse order.
|
weapons = MyGame.Sample.Monster.CreateWeaponsVector(builder, [sword, axe])
|
||||||
MyGame.Sample.Monster.StartWeaponsVector(builder, 2)
|
|
||||||
builder.PrependUOffsetTRelative(axe)
|
|
||||||
builder.PrependUOffsetTRelative(sword)
|
|
||||||
weapons = builder.EndVector()
|
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Rust"
|
=== "Rust"
|
||||||
@@ -1352,16 +1348,13 @@ bit more directly.
|
|||||||
```py
|
```py
|
||||||
# Create a `vector` representing the inventory of the Orc. Each number
|
# Create a `vector` representing the inventory of the Orc. Each number
|
||||||
# could correspond to an item that can be claimed after he is slain.
|
# could correspond to an item that can be claimed after he is slain.
|
||||||
# Note: Since we prepend the bytes, this loop iterates in reverse.
|
inv = MyGame.Sample.Monster.CreateInventoryVector(builder, range(0, 10))
|
||||||
MyGame.Sample.Monster.StartInventoryVector(builder, 10)
|
|
||||||
for i in reversed(range(0, 10)):
|
|
||||||
builder.PrependByte(i)
|
|
||||||
inv = builder.EndVector()
|
|
||||||
|
|
||||||
MyGame.Sample.Monster.StartPathVector(builder, 2)
|
path_points = [
|
||||||
MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
|
MyGame.Sample.Vec3T(x=1.0, y=2.0, z=3.0),
|
||||||
MyGame.Sample.Vec3.CreateVec3(builder, 4.0, 5.0, 6.0)
|
MyGame.Sample.Vec3T(x=4.0, y=5.0, z=6.0),
|
||||||
path = builder.EndVector()
|
]
|
||||||
|
path = MyGame.Sample.Monster.CreatePathVector(builder, path_points)
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "Rust"
|
=== "Rust"
|
||||||
|
|||||||
15
go/table.go
15
go/table.go
@@ -31,10 +31,25 @@ func (t *Table) String(off UOffsetT) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ByteVector gets a byte slice from data stored inside the flatbuffer.
|
// ByteVector gets a byte slice from data stored inside the flatbuffer.
|
||||||
|
// If the offset is invalid or out of bounds, returns nil to prevent crashes.
|
||||||
func (t *Table) ByteVector(off UOffsetT) []byte {
|
func (t *Table) ByteVector(off UOffsetT) []byte {
|
||||||
|
n := UOffsetT(len(t.Bytes))
|
||||||
|
// Need at least SizeUOffsetT bytes to read the relative vector offset.
|
||||||
|
u := UOffsetT(SizeUOffsetT)
|
||||||
|
if n < u || off > n-u {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
off += GetUOffsetT(t.Bytes[off:])
|
off += GetUOffsetT(t.Bytes[off:])
|
||||||
|
// Need at least SizeUOffsetT bytes to read the vector length.
|
||||||
|
if n < u || off > n-u {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
start := off + UOffsetT(SizeUOffsetT)
|
start := off + UOffsetT(SizeUOffsetT)
|
||||||
length := GetUOffsetT(t.Bytes[off:])
|
length := GetUOffsetT(t.Bytes[off:])
|
||||||
|
// Avoid overflow by checking the length against the remaining buffer space.
|
||||||
|
if length > n-start {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return t.Bytes[start : start+length]
|
return t.Bytes[start : start+length]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,12 @@ def UniverseStartGalaxiesVector(builder, numElems):
|
|||||||
def StartGalaxiesVector(builder, numElems):
|
def StartGalaxiesVector(builder, numElems):
|
||||||
return UniverseStartGalaxiesVector(builder, numElems)
|
return UniverseStartGalaxiesVector(builder, numElems)
|
||||||
|
|
||||||
|
def UniverseCreateGalaxiesVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateGalaxiesVector(builder, data):
|
||||||
|
UniverseCreateGalaxiesVector(builder, data)
|
||||||
|
|
||||||
def UniverseEnd(builder):
|
def UniverseEnd(builder):
|
||||||
return builder.EndObject()
|
return builder.EndObject()
|
||||||
|
|
||||||
|
|||||||
@@ -2,294 +2,321 @@
|
|||||||
// @generated
|
// @generated
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
|
||||||
#[allow(unused_imports, dead_code)]
|
#[allow(unused_imports, dead_code)]
|
||||||
pub mod flatbuffers {
|
pub mod flatbuffers {
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
#[allow(unused_imports, dead_code)]
|
#[allow(unused_imports, dead_code)]
|
||||||
pub mod goldens {
|
pub mod goldens {
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
pub enum GalaxyOffset {}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
|
pub struct Galaxy<'a> {
|
||||||
|
pub _tab: ::flatbuffers::Table<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ::flatbuffers::Follow<'a> for Galaxy<'a> {
|
||||||
|
type Inner = Galaxy<'a>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
|
Self { _tab: unsafe { ::flatbuffers::Table::new(buf, loc) } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Galaxy<'a> {
|
||||||
|
pub const VT_NUM_STARS: ::flatbuffers::VOffsetT = 4;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn init_from_table(table: ::flatbuffers::Table<'a>) -> Self {
|
||||||
|
Galaxy { _tab: table }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: ::flatbuffers::Allocator + 'bldr>(
|
||||||
|
_fbb: &'mut_bldr mut ::flatbuffers::FlatBufferBuilder<'bldr, A>,
|
||||||
|
args: &'args GalaxyArgs
|
||||||
|
) -> ::flatbuffers::WIPOffset<Galaxy<'bldr>> {
|
||||||
|
let mut builder = GalaxyBuilder::new(_fbb);
|
||||||
|
builder.add_num_stars(args.num_stars);
|
||||||
|
builder.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub enum GalaxyOffset {}
|
#[inline]
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
pub fn num_stars(&self) -> i64 {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<i64>(Galaxy::VT_NUM_STARS, Some(0)).unwrap()}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Galaxy<'a> {
|
impl ::flatbuffers::Verifiable for Galaxy<'_> {
|
||||||
pub _tab: ::flatbuffers::Table<'a>,
|
#[inline]
|
||||||
}
|
fn run_verifier(
|
||||||
|
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||||
|
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||||
|
v.visit_table(pos)?
|
||||||
|
.visit_field::<i64>("num_stars", Self::VT_NUM_STARS, false)?
|
||||||
|
.finish();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ::flatbuffers::Follow<'a> for Galaxy<'a> {
|
pub struct GalaxyArgs {
|
||||||
type Inner = Galaxy<'a>;
|
pub num_stars: i64,
|
||||||
#[inline]
|
}
|
||||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
|
||||||
Self { _tab: unsafe { ::flatbuffers::Table::new(buf, loc) } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Galaxy<'a> {
|
impl<'a> Default for GalaxyArgs {
|
||||||
pub const VT_NUM_STARS: ::flatbuffers::VOffsetT = 4;
|
#[inline]
|
||||||
|
fn default() -> Self {
|
||||||
|
GalaxyArgs {
|
||||||
|
num_stars: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
pub struct GalaxyBuilder<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> {
|
||||||
pub unsafe fn init_from_table(table: ::flatbuffers::Table<'a>) -> Self {
|
fbb_: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
||||||
Galaxy { _tab: table }
|
start_: ::flatbuffers::WIPOffset<::flatbuffers::TableUnfinishedWIPOffset>,
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
|
||||||
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: ::flatbuffers::Allocator + 'bldr>(
|
impl<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> GalaxyBuilder<'a, 'b, A> {
|
||||||
_fbb: &'mut_bldr mut ::flatbuffers::FlatBufferBuilder<'bldr, A>,
|
#[inline]
|
||||||
args: &'args GalaxyArgs
|
pub fn add_num_stars(&mut self, num_stars: i64) {
|
||||||
) -> ::flatbuffers::WIPOffset<Galaxy<'bldr>> {
|
self.fbb_.push_slot::<i64>(Galaxy::VT_NUM_STARS, num_stars, 0);
|
||||||
let mut builder = GalaxyBuilder::new(_fbb);
|
}
|
||||||
builder.add_num_stars(args.num_stars);
|
|
||||||
builder.finish()
|
#[inline]
|
||||||
}
|
pub fn new(_fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>) -> GalaxyBuilder<'a, 'b, A> {
|
||||||
|
let start = _fbb.start_table();
|
||||||
|
GalaxyBuilder {
|
||||||
|
fbb_: _fbb,
|
||||||
|
start_: start,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn finish(self) -> ::flatbuffers::WIPOffset<Galaxy<'a>> {
|
||||||
|
let o = self.fbb_.end_table(self.start_);
|
||||||
|
::flatbuffers::WIPOffset::new(o.value())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::core::fmt::Debug for Galaxy<'_> {
|
||||||
|
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
||||||
|
let mut ds = f.debug_struct("Galaxy");
|
||||||
|
ds.field("num_stars", &self.num_stars());
|
||||||
|
ds.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum UniverseOffset {}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
|
pub struct Universe<'a> {
|
||||||
|
pub _tab: ::flatbuffers::Table<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ::flatbuffers::Follow<'a> for Universe<'a> {
|
||||||
|
type Inner = Universe<'a>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
|
Self { _tab: unsafe { ::flatbuffers::Table::new(buf, loc) } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Universe<'a> {
|
||||||
|
pub const VT_AGE: ::flatbuffers::VOffsetT = 4;
|
||||||
|
pub const VT_GALAXIES: ::flatbuffers::VOffsetT = 6;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn init_from_table(table: ::flatbuffers::Table<'a>) -> Self {
|
||||||
|
Universe { _tab: table }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: ::flatbuffers::Allocator + 'bldr>(
|
||||||
|
_fbb: &'mut_bldr mut ::flatbuffers::FlatBufferBuilder<'bldr, A>,
|
||||||
|
args: &'args UniverseArgs<'args>
|
||||||
|
) -> ::flatbuffers::WIPOffset<Universe<'bldr>> {
|
||||||
|
let mut builder = UniverseBuilder::new(_fbb);
|
||||||
|
builder.add_age(args.age);
|
||||||
|
if let Some(x) = args.galaxies { builder.add_galaxies(x); }
|
||||||
|
builder.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn num_stars(&self) -> i64 {
|
pub fn age(&self) -> f64 {
|
||||||
// Safety:
|
// Safety:
|
||||||
// Created from valid Table for this object
|
// Created from valid Table for this object
|
||||||
// which contains a valid value in this slot
|
// which contains a valid value in this slot
|
||||||
unsafe { self._tab.get::<i64>(Galaxy::VT_NUM_STARS, Some(0)).unwrap()}
|
unsafe { self._tab.get::<f64>(Universe::VT_AGE, Some(0.0)).unwrap()}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl ::flatbuffers::Verifiable for Galaxy<'_> {
|
#[inline]
|
||||||
#[inline]
|
pub fn galaxies(&self) -> Option<::flatbuffers::Vector<'a, ::flatbuffers::ForwardsUOffset<Galaxy<'a>>>> {
|
||||||
fn run_verifier(
|
// Safety:
|
||||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
// Created from valid Table for this object
|
||||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
// which contains a valid value in this slot
|
||||||
v.visit_table(pos)?
|
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'a, ::flatbuffers::ForwardsUOffset<Galaxy>>>>(Universe::VT_GALAXIES, None)}
|
||||||
.visit_field::<i64>("num_stars", Self::VT_NUM_STARS, false)?
|
}
|
||||||
.finish();
|
}
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub struct GalaxyArgs {
|
|
||||||
pub num_stars: i64,
|
|
||||||
}
|
|
||||||
impl<'a> Default for GalaxyArgs {
|
|
||||||
#[inline]
|
|
||||||
fn default() -> Self {
|
|
||||||
GalaxyArgs {
|
|
||||||
num_stars: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct GalaxyBuilder<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> {
|
impl ::flatbuffers::Verifiable for Universe<'_> {
|
||||||
fbb_: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
#[inline]
|
||||||
start_: ::flatbuffers::WIPOffset<::flatbuffers::TableUnfinishedWIPOffset>,
|
fn run_verifier(
|
||||||
}
|
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||||
impl<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> GalaxyBuilder<'a, 'b, A> {
|
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||||
#[inline]
|
v.visit_table(pos)?
|
||||||
pub fn add_num_stars(&mut self, num_stars: i64) {
|
.visit_field::<f64>("age", Self::VT_AGE, false)?
|
||||||
self.fbb_.push_slot::<i64>(Galaxy::VT_NUM_STARS, num_stars, 0);
|
.visit_field::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'_, ::flatbuffers::ForwardsUOffset<Galaxy>>>>("galaxies", Self::VT_GALAXIES, false)?
|
||||||
}
|
.finish();
|
||||||
#[inline]
|
Ok(())
|
||||||
pub fn new(_fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>) -> GalaxyBuilder<'a, 'b, A> {
|
}
|
||||||
let start = _fbb.start_table();
|
}
|
||||||
GalaxyBuilder {
|
|
||||||
fbb_: _fbb,
|
|
||||||
start_: start,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn finish(self) -> ::flatbuffers::WIPOffset<Galaxy<'a>> {
|
|
||||||
let o = self.fbb_.end_table(self.start_);
|
|
||||||
::flatbuffers::WIPOffset::new(o.value())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::core::fmt::Debug for Galaxy<'_> {
|
pub struct UniverseArgs<'a> {
|
||||||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
pub age: f64,
|
||||||
let mut ds = f.debug_struct("Galaxy");
|
pub galaxies: Option<::flatbuffers::WIPOffset<::flatbuffers::Vector<'a, ::flatbuffers::ForwardsUOffset<Galaxy<'a>>>>>,
|
||||||
ds.field("num_stars", &self.num_stars());
|
}
|
||||||
ds.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub enum UniverseOffset {}
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
|
||||||
|
|
||||||
pub struct Universe<'a> {
|
impl<'a> Default for UniverseArgs<'a> {
|
||||||
pub _tab: ::flatbuffers::Table<'a>,
|
#[inline]
|
||||||
}
|
fn default() -> Self {
|
||||||
|
UniverseArgs {
|
||||||
|
age: 0.0,
|
||||||
|
galaxies: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ::flatbuffers::Follow<'a> for Universe<'a> {
|
pub struct UniverseBuilder<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> {
|
||||||
type Inner = Universe<'a>;
|
fbb_: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
||||||
#[inline]
|
start_: ::flatbuffers::WIPOffset<::flatbuffers::TableUnfinishedWIPOffset>,
|
||||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
}
|
||||||
Self { _tab: unsafe { ::flatbuffers::Table::new(buf, loc) } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Universe<'a> {
|
impl<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> UniverseBuilder<'a, 'b, A> {
|
||||||
pub const VT_AGE: ::flatbuffers::VOffsetT = 4;
|
#[inline]
|
||||||
pub const VT_GALAXIES: ::flatbuffers::VOffsetT = 6;
|
pub fn add_age(&mut self, age: f64) {
|
||||||
|
self.fbb_.push_slot::<f64>(Universe::VT_AGE, age, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn init_from_table(table: ::flatbuffers::Table<'a>) -> Self {
|
pub fn add_galaxies(&mut self, galaxies: ::flatbuffers::WIPOffset<::flatbuffers::Vector<'b , ::flatbuffers::ForwardsUOffset<Galaxy<'b >>>>) {
|
||||||
Universe { _tab: table }
|
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Universe::VT_GALAXIES, galaxies);
|
||||||
}
|
}
|
||||||
#[allow(unused_mut)]
|
|
||||||
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: ::flatbuffers::Allocator + 'bldr>(
|
|
||||||
_fbb: &'mut_bldr mut ::flatbuffers::FlatBufferBuilder<'bldr, A>,
|
|
||||||
args: &'args UniverseArgs<'args>
|
|
||||||
) -> ::flatbuffers::WIPOffset<Universe<'bldr>> {
|
|
||||||
let mut builder = UniverseBuilder::new(_fbb);
|
|
||||||
builder.add_age(args.age);
|
|
||||||
if let Some(x) = args.galaxies { builder.add_galaxies(x); }
|
|
||||||
builder.finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn new(_fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>) -> UniverseBuilder<'a, 'b, A> {
|
||||||
|
let start = _fbb.start_table();
|
||||||
|
UniverseBuilder {
|
||||||
|
fbb_: _fbb,
|
||||||
|
start_: start,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn age(&self) -> f64 {
|
pub fn finish(self) -> ::flatbuffers::WIPOffset<Universe<'a>> {
|
||||||
// Safety:
|
let o = self.fbb_.end_table(self.start_);
|
||||||
// Created from valid Table for this object
|
::flatbuffers::WIPOffset::new(o.value())
|
||||||
// which contains a valid value in this slot
|
}
|
||||||
unsafe { self._tab.get::<f64>(Universe::VT_AGE, Some(0.0)).unwrap()}
|
}
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn galaxies(&self) -> Option<::flatbuffers::Vector<'a, ::flatbuffers::ForwardsUOffset<Galaxy<'a>>>> {
|
|
||||||
// Safety:
|
|
||||||
// Created from valid Table for this object
|
|
||||||
// which contains a valid value in this slot
|
|
||||||
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'a, ::flatbuffers::ForwardsUOffset<Galaxy>>>>(Universe::VT_GALAXIES, None)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::flatbuffers::Verifiable for Universe<'_> {
|
impl ::core::fmt::Debug for Universe<'_> {
|
||||||
#[inline]
|
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
||||||
fn run_verifier(
|
let mut ds = f.debug_struct("Universe");
|
||||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
ds.field("age", &self.age());
|
||||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
ds.field("galaxies", &self.galaxies());
|
||||||
v.visit_table(pos)?
|
ds.finish()
|
||||||
.visit_field::<f64>("age", Self::VT_AGE, false)?
|
}
|
||||||
.visit_field::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'_, ::flatbuffers::ForwardsUOffset<Galaxy>>>>("galaxies", Self::VT_GALAXIES, false)?
|
}
|
||||||
.finish();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub struct UniverseArgs<'a> {
|
|
||||||
pub age: f64,
|
|
||||||
pub galaxies: Option<::flatbuffers::WIPOffset<::flatbuffers::Vector<'a, ::flatbuffers::ForwardsUOffset<Galaxy<'a>>>>>,
|
|
||||||
}
|
|
||||||
impl<'a> Default for UniverseArgs<'a> {
|
|
||||||
#[inline]
|
|
||||||
fn default() -> Self {
|
|
||||||
UniverseArgs {
|
|
||||||
age: 0.0,
|
|
||||||
galaxies: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct UniverseBuilder<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> {
|
/// Verifies that a buffer of bytes contains a `Universe`
|
||||||
fbb_: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
/// and returns it.
|
||||||
start_: ::flatbuffers::WIPOffset<::flatbuffers::TableUnfinishedWIPOffset>,
|
/// Note that verification is still experimental and may not
|
||||||
}
|
/// catch every error, or be maximally performant. For the
|
||||||
impl<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> UniverseBuilder<'a, 'b, A> {
|
/// previous, unchecked, behavior use
|
||||||
#[inline]
|
/// `root_as_universe_unchecked`.
|
||||||
pub fn add_age(&mut self, age: f64) {
|
#[inline]
|
||||||
self.fbb_.push_slot::<f64>(Universe::VT_AGE, age, 0.0);
|
pub fn root_as_universe(buf: &[u8]) -> Result<Universe<'_>, ::flatbuffers::InvalidFlatbuffer> {
|
||||||
}
|
::flatbuffers::root::<Universe>(buf)
|
||||||
#[inline]
|
}
|
||||||
pub fn add_galaxies(&mut self, galaxies: ::flatbuffers::WIPOffset<::flatbuffers::Vector<'b , ::flatbuffers::ForwardsUOffset<Galaxy<'b >>>>) {
|
|
||||||
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Universe::VT_GALAXIES, galaxies);
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn new(_fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>) -> UniverseBuilder<'a, 'b, A> {
|
|
||||||
let start = _fbb.start_table();
|
|
||||||
UniverseBuilder {
|
|
||||||
fbb_: _fbb,
|
|
||||||
start_: start,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn finish(self) -> ::flatbuffers::WIPOffset<Universe<'a>> {
|
|
||||||
let o = self.fbb_.end_table(self.start_);
|
|
||||||
::flatbuffers::WIPOffset::new(o.value())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::core::fmt::Debug for Universe<'_> {
|
/// Verifies that a buffer of bytes contains a size prefixed
|
||||||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
/// `Universe` and returns it.
|
||||||
let mut ds = f.debug_struct("Universe");
|
/// Note that verification is still experimental and may not
|
||||||
ds.field("age", &self.age());
|
/// catch every error, or be maximally performant. For the
|
||||||
ds.field("galaxies", &self.galaxies());
|
/// previous, unchecked, behavior use
|
||||||
ds.finish()
|
/// `size_prefixed_root_as_universe_unchecked`.
|
||||||
}
|
#[inline]
|
||||||
}
|
pub fn size_prefixed_root_as_universe(buf: &[u8]) -> Result<Universe<'_>, ::flatbuffers::InvalidFlatbuffer> {
|
||||||
#[inline]
|
::flatbuffers::size_prefixed_root::<Universe>(buf)
|
||||||
/// Verifies that a buffer of bytes contains a `Universe`
|
}
|
||||||
/// and returns it.
|
|
||||||
/// Note that verification is still experimental and may not
|
|
||||||
/// catch every error, or be maximally performant. For the
|
|
||||||
/// previous, unchecked, behavior use
|
|
||||||
/// `root_as_universe_unchecked`.
|
|
||||||
pub fn root_as_universe(buf: &[u8]) -> Result<Universe<'_>, ::flatbuffers::InvalidFlatbuffer> {
|
|
||||||
::flatbuffers::root::<Universe>(buf)
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
/// Verifies that a buffer of bytes contains a size prefixed
|
|
||||||
/// `Universe` and returns it.
|
|
||||||
/// Note that verification is still experimental and may not
|
|
||||||
/// catch every error, or be maximally performant. For the
|
|
||||||
/// previous, unchecked, behavior use
|
|
||||||
/// `size_prefixed_root_as_universe_unchecked`.
|
|
||||||
pub fn size_prefixed_root_as_universe(buf: &[u8]) -> Result<Universe<'_>, ::flatbuffers::InvalidFlatbuffer> {
|
|
||||||
::flatbuffers::size_prefixed_root::<Universe>(buf)
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
/// Verifies, with the given options, that a buffer of bytes
|
|
||||||
/// contains a `Universe` and returns it.
|
|
||||||
/// Note that verification is still experimental and may not
|
|
||||||
/// catch every error, or be maximally performant. For the
|
|
||||||
/// previous, unchecked, behavior use
|
|
||||||
/// `root_as_universe_unchecked`.
|
|
||||||
pub fn root_as_universe_with_opts<'b, 'o>(
|
|
||||||
opts: &'o ::flatbuffers::VerifierOptions,
|
|
||||||
buf: &'b [u8],
|
|
||||||
) -> Result<Universe<'b>, ::flatbuffers::InvalidFlatbuffer> {
|
|
||||||
::flatbuffers::root_with_opts::<Universe<'b>>(opts, buf)
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
/// Verifies, with the given verifier options, that a buffer of
|
|
||||||
/// bytes contains a size prefixed `Universe` and returns
|
|
||||||
/// it. Note that verification is still experimental and may not
|
|
||||||
/// catch every error, or be maximally performant. For the
|
|
||||||
/// previous, unchecked, behavior use
|
|
||||||
/// `root_as_universe_unchecked`.
|
|
||||||
pub fn size_prefixed_root_as_universe_with_opts<'b, 'o>(
|
|
||||||
opts: &'o ::flatbuffers::VerifierOptions,
|
|
||||||
buf: &'b [u8],
|
|
||||||
) -> Result<Universe<'b>, ::flatbuffers::InvalidFlatbuffer> {
|
|
||||||
::flatbuffers::size_prefixed_root_with_opts::<Universe<'b>>(opts, buf)
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
/// Assumes, without verification, that a buffer of bytes contains a Universe and returns it.
|
|
||||||
/// # Safety
|
|
||||||
/// Callers must trust the given bytes do indeed contain a valid `Universe`.
|
|
||||||
pub unsafe fn root_as_universe_unchecked(buf: &[u8]) -> Universe<'_> {
|
|
||||||
unsafe { ::flatbuffers::root_unchecked::<Universe>(buf) }
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
/// Assumes, without verification, that a buffer of bytes contains a size prefixed Universe and returns it.
|
|
||||||
/// # Safety
|
|
||||||
/// Callers must trust the given bytes do indeed contain a valid size prefixed `Universe`.
|
|
||||||
pub unsafe fn size_prefixed_root_as_universe_unchecked(buf: &[u8]) -> Universe<'_> {
|
|
||||||
unsafe { ::flatbuffers::size_prefixed_root_unchecked::<Universe>(buf) }
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn finish_universe_buffer<'a, 'b, A: ::flatbuffers::Allocator + 'a>(
|
|
||||||
fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
|
||||||
root: ::flatbuffers::WIPOffset<Universe<'a>>) {
|
|
||||||
fbb.finish(root, None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
/// Verifies, with the given options, that a buffer of bytes
|
||||||
pub fn finish_size_prefixed_universe_buffer<'a, 'b, A: ::flatbuffers::Allocator + 'a>(fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>, root: ::flatbuffers::WIPOffset<Universe<'a>>) {
|
/// contains a `Universe` and returns it.
|
||||||
fbb.finish_size_prefixed(root, None);
|
/// Note that verification is still experimental and may not
|
||||||
}
|
/// catch every error, or be maximally performant. For the
|
||||||
} // pub mod goldens
|
/// previous, unchecked, behavior use
|
||||||
} // pub mod flatbuffers
|
/// `root_as_universe_unchecked`.
|
||||||
|
#[inline]
|
||||||
|
pub fn root_as_universe_with_opts<'b, 'o>(
|
||||||
|
opts: &'o ::flatbuffers::VerifierOptions,
|
||||||
|
buf: &'b [u8],
|
||||||
|
) -> Result<Universe<'b>, ::flatbuffers::InvalidFlatbuffer> {
|
||||||
|
::flatbuffers::root_with_opts::<Universe<'b>>(opts, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Verifies, with the given verifier options, that a buffer of
|
||||||
|
/// bytes contains a size prefixed `Universe` and returns
|
||||||
|
/// it. Note that verification is still experimental and may not
|
||||||
|
/// catch every error, or be maximally performant. For the
|
||||||
|
/// previous, unchecked, behavior use
|
||||||
|
/// `root_as_universe_unchecked`.
|
||||||
|
#[inline]
|
||||||
|
pub fn size_prefixed_root_as_universe_with_opts<'b, 'o>(
|
||||||
|
opts: &'o ::flatbuffers::VerifierOptions,
|
||||||
|
buf: &'b [u8],
|
||||||
|
) -> Result<Universe<'b>, ::flatbuffers::InvalidFlatbuffer> {
|
||||||
|
::flatbuffers::size_prefixed_root_with_opts::<Universe<'b>>(opts, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assumes, without verification, that a buffer of bytes contains a Universe and returns it.
|
||||||
|
/// # Safety
|
||||||
|
/// Callers must trust the given bytes do indeed contain a valid `Universe`.
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn root_as_universe_unchecked(buf: &[u8]) -> Universe<'_> {
|
||||||
|
unsafe { ::flatbuffers::root_unchecked::<Universe>(buf) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assumes, without verification, that a buffer of bytes contains a size prefixed Universe and returns it.
|
||||||
|
/// # Safety
|
||||||
|
/// Callers must trust the given bytes do indeed contain a valid size prefixed `Universe`.
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn size_prefixed_root_as_universe_unchecked(buf: &[u8]) -> Universe<'_> {
|
||||||
|
unsafe { ::flatbuffers::size_prefixed_root_unchecked::<Universe>(buf) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn finish_universe_buffer<'a, 'b, A: ::flatbuffers::Allocator + 'a>(
|
||||||
|
fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
||||||
|
root: ::flatbuffers::WIPOffset<Universe<'a>>
|
||||||
|
) {
|
||||||
|
fbb.finish(root, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn finish_size_prefixed_universe_buffer<'a, 'b, A: ::flatbuffers::Allocator + 'a>(
|
||||||
|
fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
||||||
|
root: ::flatbuffers::WIPOffset<Universe<'a>>
|
||||||
|
) {
|
||||||
|
fbb.finish_size_prefixed(root, None);
|
||||||
|
}
|
||||||
|
} // pub mod goldens
|
||||||
|
} // pub mod flatbuffers
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import * as flatbuffers from 'flatbuffers';
|
import * as flatbuffers from 'flatbuffers';
|
||||||
|
|
||||||
import { Galaxy } from '../../flatbuffers/goldens/galaxy.js';
|
import { Galaxy } from './galaxy.js';
|
||||||
|
|
||||||
|
|
||||||
export class Universe {
|
export class Universe {
|
||||||
|
|||||||
16
grpc/examples/greeter_v2.fbs
Normal file
16
grpc/examples/greeter_v2.fbs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
namespace models;
|
||||||
|
|
||||||
|
table HelloResponse {
|
||||||
|
message:string;
|
||||||
|
}
|
||||||
|
|
||||||
|
table HelloRequest {
|
||||||
|
name:string;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc_service Greeter {
|
||||||
|
Get(HelloRequest):HelloResponse;
|
||||||
|
Collect(HelloRequest):HelloResponse (streaming: "client");
|
||||||
|
Expand(HelloRequest):HelloResponse (streaming: "server");
|
||||||
|
Update(HelloRequest):HelloResponse (streaming: "bidi");
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// swift-tools-version:5.10
|
// swift-tools-version:6.2
|
||||||
/*
|
/*
|
||||||
* Copyright 2020 Google Inc. All rights reserved.
|
* Copyright 2020 Google Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -20,39 +20,43 @@ import PackageDescription
|
|||||||
let package = Package(
|
let package = Package(
|
||||||
name: "Greeter",
|
name: "Greeter",
|
||||||
platforms: [
|
platforms: [
|
||||||
.iOS(.v12),
|
.iOS(.v18),
|
||||||
.macOS(.v10_14),
|
.macOS(.v15),
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.package(path: "../../../../swift"),
|
.package(path: "../../../.."),
|
||||||
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0"),
|
.package(url: "https://github.com/grpc/grpc-swift-2.git", from: "2.0.0"),
|
||||||
|
.package(
|
||||||
|
url: "https://github.com/grpc/grpc-swift-nio-transport.git",
|
||||||
|
from: "2.0.0"),
|
||||||
|
.package(
|
||||||
|
url: "https://github.com/apple/swift-argument-parser.git",
|
||||||
|
from: "1.5.0"),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||||
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
|
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
|
||||||
.target(
|
.target(
|
||||||
name: "Model",
|
name: "Models",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"GRPC",
|
.product(name: "FlatBuffers", package: "flatbuffers"),
|
||||||
"FlatBuffers",
|
.product(name: "GRPCCore", package: "grpc-swift-2"),
|
||||||
],
|
.product(
|
||||||
path: "Sources/Model"),
|
name: "GRPCNIOTransportHTTP2",
|
||||||
|
package: "grpc-swift-nio-transport"),
|
||||||
|
]),
|
||||||
|
|
||||||
// Client for the Greeter example
|
// Client for the Greeter example
|
||||||
.target(
|
.executableTarget(
|
||||||
name: "Client",
|
name: "Commands",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"GRPC",
|
.product(name: "GRPCCore", package: "grpc-swift-2"),
|
||||||
"Model",
|
.product(
|
||||||
],
|
name: "GRPCNIOTransportHTTP2",
|
||||||
path: "Sources/client"),
|
package: "grpc-swift-nio-transport"),
|
||||||
|
.product(
|
||||||
// Server for the Greeter example
|
name: "ArgumentParser",
|
||||||
.target(
|
package: "swift-argument-parser"),
|
||||||
name: "Server",
|
"Models",
|
||||||
dependencies: [
|
]),
|
||||||
"GRPC",
|
|
||||||
"Model",
|
|
||||||
],
|
|
||||||
path: "Sources/server"),
|
|
||||||
])
|
])
|
||||||
|
|||||||
28
grpc/examples/swift/Greeter/Sources/Commands/Commands.swift
Normal file
28
grpc/examples/swift/Greeter/Sources/Commands/Commands.swift
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import ArgumentParser
|
||||||
|
|
||||||
|
let port = 3000
|
||||||
|
|
||||||
|
@main
|
||||||
|
struct GreeterCommand: AsyncParsableCommand {
|
||||||
|
static let configuration = CommandConfiguration(
|
||||||
|
commandName: "greeter",
|
||||||
|
abstract: "A multi-tool to run an echo server and execute RPCs against it.",
|
||||||
|
subcommands: [ServerCommand.self, ClientCommand.self])
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import FlatBuffers
|
||||||
|
import GRPCCore
|
||||||
|
import Models
|
||||||
|
|
||||||
|
struct GreeterService: models_Greeter.SimpleServiceProtocol {
|
||||||
|
func Get(
|
||||||
|
request: GRPCMessage<models_HelloResponse>,
|
||||||
|
context: GRPCCore
|
||||||
|
.ServerContext) async throws -> GRPCMessage<models_HelloResponse>
|
||||||
|
{
|
||||||
|
let model = try request.decode()
|
||||||
|
print("## GreeterService.Get: \(model.message)")
|
||||||
|
|
||||||
|
var builder = FlatBufferBuilder(initialSize: 128)
|
||||||
|
let off = builder.create(string: "Hello \(model.message ?? "Unknown")")
|
||||||
|
let root = models_HelloResponse.createHelloResponse(
|
||||||
|
&builder,
|
||||||
|
messageOffset: off)
|
||||||
|
builder.finish(offset: root)
|
||||||
|
return try GRPCMessage<models_HelloResponse>(builder: &builder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Collect(
|
||||||
|
request: GRPCCore.RPCAsyncSequence<
|
||||||
|
GRPCMessage<models_HelloResponse>,
|
||||||
|
any Swift.Error
|
||||||
|
>,
|
||||||
|
context: GRPCCore
|
||||||
|
.ServerContext) async throws -> GRPCMessage<models_HelloResponse>
|
||||||
|
{
|
||||||
|
let messages: [String] = try await request
|
||||||
|
.reduce(into: []) { array, message in
|
||||||
|
let model = try message.decode()
|
||||||
|
return array.append(model.message ?? "Unknown")
|
||||||
|
}
|
||||||
|
|
||||||
|
let joined = messages.joined(separator: ", ")
|
||||||
|
print("## GreeterService.Collect: \(joined)")
|
||||||
|
|
||||||
|
var builder = FlatBufferBuilder(initialSize: 128)
|
||||||
|
let off = builder.create(string: "Hello \(joined)")
|
||||||
|
let root = models_HelloResponse.createHelloResponse(
|
||||||
|
&builder,
|
||||||
|
messageOffset: off)
|
||||||
|
builder.finish(offset: root)
|
||||||
|
return try GRPCMessage<models_HelloResponse>(builder: &builder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Expand(
|
||||||
|
request: GRPCMessage<models_HelloResponse>,
|
||||||
|
response: GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext) async throws
|
||||||
|
{
|
||||||
|
|
||||||
|
let model = try request.decode()
|
||||||
|
print("## GreeterService.Expand: \(model.message)")
|
||||||
|
|
||||||
|
let message = model.message ?? "Unknown"
|
||||||
|
let stream = AsyncThrowingStream<
|
||||||
|
GRPCMessage<models_HelloResponse>,
|
||||||
|
Error
|
||||||
|
> { continuation in
|
||||||
|
var builder = FlatBufferBuilder(initialSize: 128)
|
||||||
|
for char in message {
|
||||||
|
let off = builder.create(string: "\(char)")
|
||||||
|
let root = models_HelloResponse.createHelloResponse(
|
||||||
|
&builder,
|
||||||
|
messageOffset: off)
|
||||||
|
builder.finish(offset: root)
|
||||||
|
|
||||||
|
do {
|
||||||
|
continuation
|
||||||
|
.yield(try GRPCMessage<models_HelloResponse>(builder: &builder))
|
||||||
|
} catch {
|
||||||
|
continuation.finish(throwing: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continuation.finish()
|
||||||
|
}
|
||||||
|
try await response.write(contentsOf: stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Update(
|
||||||
|
request: GRPCCore.RPCAsyncSequence<
|
||||||
|
GRPCMessage<models_HelloResponse>,
|
||||||
|
any Swift.Error
|
||||||
|
>,
|
||||||
|
response: GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext) async throws
|
||||||
|
{
|
||||||
|
for try await message in request {
|
||||||
|
let model = try message.decode()
|
||||||
|
print("## GreeterService.Update: \(model.message)")
|
||||||
|
var builder = FlatBufferBuilder(initialSize: 128)
|
||||||
|
let off = builder.create(string: "Hello \(model.message ?? "Unknown")")
|
||||||
|
let root = models_HelloResponse.createHelloResponse(
|
||||||
|
&builder,
|
||||||
|
messageOffset: off)
|
||||||
|
builder.finish(offset: root)
|
||||||
|
try await response
|
||||||
|
.write(try GRPCMessage<models_HelloResponse>(builder: &builder))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import ArgumentParser
|
||||||
|
import FlatBuffers
|
||||||
|
import GRPCCore
|
||||||
|
import GRPCNIOTransportHTTP2
|
||||||
|
import Models
|
||||||
|
|
||||||
|
enum ClientRequest: String, ExpressibleByArgument {
|
||||||
|
case get, expand, collect, update
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ClientCommand: AsyncParsableCommand {
|
||||||
|
static let configuration = CommandConfiguration(
|
||||||
|
commandName: "client")
|
||||||
|
|
||||||
|
@Option(help: "Name to send to the server")
|
||||||
|
var name: String
|
||||||
|
|
||||||
|
@Option(help: "request type")
|
||||||
|
var request: ClientRequest
|
||||||
|
|
||||||
|
func run() async throws {
|
||||||
|
try await withGRPCClient(
|
||||||
|
transport: .http2NIOPosix(
|
||||||
|
target: .dns(host: "localhost", port: port),
|
||||||
|
transportSecurity: .plaintext))
|
||||||
|
{
|
||||||
|
let client = models_Greeter.Client(wrapping: $0)
|
||||||
|
|
||||||
|
switch request {
|
||||||
|
case .get: try await get(client: client)
|
||||||
|
case .expand: try await expand(client: client)
|
||||||
|
case .collect: try await collect(client: client)
|
||||||
|
case .update: try await update(client: client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func get(
|
||||||
|
client: models_Greeter
|
||||||
|
.Client<HTTP2ClientTransport.Posix>) async throws
|
||||||
|
{
|
||||||
|
for _ in 0..<3 {
|
||||||
|
var builder = FlatBufferBuilder(initialSize: 64)
|
||||||
|
let off = builder.create(string: name)
|
||||||
|
let root = models_HelloRequest.createHelloRequest(
|
||||||
|
&builder,
|
||||||
|
nameOffset: off)
|
||||||
|
builder.finish(offset: root)
|
||||||
|
|
||||||
|
let response = try await client
|
||||||
|
.Get(GRPCMessage(builder: &builder))
|
||||||
|
let message = try? response.decode().message
|
||||||
|
print("get message: \(message ?? "nil")")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func expand(
|
||||||
|
client: models_Greeter
|
||||||
|
.Client<HTTP2ClientTransport.Posix>) async throws
|
||||||
|
{
|
||||||
|
for _ in 0..<3 {
|
||||||
|
var builder = FlatBufferBuilder(initialSize: 64)
|
||||||
|
let off = builder.create(string: name)
|
||||||
|
let root = models_HelloRequest.createHelloRequest(
|
||||||
|
&builder,
|
||||||
|
nameOffset: off)
|
||||||
|
builder.finish(offset: root)
|
||||||
|
try await client.Expand(GRPCMessage(builder: &builder)) { response in
|
||||||
|
for try await message in response.messages {
|
||||||
|
let message = try? message.decode().message
|
||||||
|
print("expand message: \(message ?? "nil")")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func collect(
|
||||||
|
client: models_Greeter
|
||||||
|
.Client<HTTP2ClientTransport.Posix>) async throws
|
||||||
|
{
|
||||||
|
for _ in 0..<3 {
|
||||||
|
let response = try await client.Collect { writer in
|
||||||
|
for part in name {
|
||||||
|
print("collect sending: \(part)")
|
||||||
|
var builder = FlatBufferBuilder(initialSize: 64)
|
||||||
|
let off = builder.create(string: String(part))
|
||||||
|
let root = models_HelloRequest.createHelloRequest(
|
||||||
|
&builder,
|
||||||
|
nameOffset: off)
|
||||||
|
builder.finish(offset: root)
|
||||||
|
try await writer.write(GRPCMessage(builder: &builder))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let message = try response.decode().message
|
||||||
|
print("collect message: \(message ?? "nil")")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(
|
||||||
|
client: models_Greeter
|
||||||
|
.Client<HTTP2ClientTransport.Posix>) async throws
|
||||||
|
{
|
||||||
|
for _ in 0..<3 {
|
||||||
|
try await client.Update { writer in
|
||||||
|
for part in name {
|
||||||
|
print("update sending: \(part)")
|
||||||
|
var builder = FlatBufferBuilder(initialSize: 64)
|
||||||
|
let off = builder.create(string: String(part))
|
||||||
|
let root = models_HelloRequest.createHelloRequest(
|
||||||
|
&builder,
|
||||||
|
nameOffset: off)
|
||||||
|
builder.finish(offset: root)
|
||||||
|
try await writer.write(GRPCMessage(builder: &builder))
|
||||||
|
}
|
||||||
|
} onResponse: { response in
|
||||||
|
for try await message in response.messages {
|
||||||
|
let message = try message.decode().message
|
||||||
|
print("collect message: \(message ?? "nil")")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import ArgumentParser
|
||||||
|
import GRPCCore
|
||||||
|
import GRPCNIOTransportHTTP2
|
||||||
|
|
||||||
|
struct ServerCommand: AsyncParsableCommand {
|
||||||
|
static let configuration = CommandConfiguration(
|
||||||
|
commandName: "serve")
|
||||||
|
|
||||||
|
func run() async throws {
|
||||||
|
let server = GRPCServer(
|
||||||
|
transport: .http2NIOPosix(
|
||||||
|
address: .ipv4(host: "127.0.0.1", port: port),
|
||||||
|
transportSecurity: .plaintext),
|
||||||
|
services: [GreeterService()])
|
||||||
|
|
||||||
|
try await withThrowingDiscardingTaskGroup { group in
|
||||||
|
group.addTask { try await server.serve() }
|
||||||
|
if let address = try await server.listeningAddress {
|
||||||
|
print("Echo listening on \(address)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
// Generated GRPC code for FlatBuffers swift!
|
|
||||||
/// The following code is generated by the Flatbuffers library which might not be in sync with grpc-swift
|
|
||||||
/// in case of an issue please open github issue, though it would be maintained
|
|
||||||
|
|
||||||
// swiftlint:disable all
|
|
||||||
// swiftformat:disable all
|
|
||||||
|
|
||||||
#if !os(Windows)
|
|
||||||
import Foundation
|
|
||||||
import GRPC
|
|
||||||
import NIO
|
|
||||||
import NIOHTTP1
|
|
||||||
import FlatBuffers
|
|
||||||
|
|
||||||
public protocol GRPCFlatBufPayload: GRPCPayload, FlatBufferGRPCMessage {}
|
|
||||||
public extension GRPCFlatBufPayload {
|
|
||||||
init(serializedByteBuffer: inout NIO.ByteBuffer) throws {
|
|
||||||
self.init(byteBuffer: FlatBuffers.ByteBuffer(contiguousBytes: serializedByteBuffer.readableBytesView, count: serializedByteBuffer.readableBytes))
|
|
||||||
}
|
|
||||||
func serialize(into buffer: inout NIO.ByteBuffer) throws {
|
|
||||||
withUnsafeReadableBytes { buffer.writeBytes($0) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
extension Message: GRPCFlatBufPayload {}
|
|
||||||
|
|
||||||
/// Usage: instantiate models_GreeterServiceClient, then call methods of this protocol to make API calls.
|
|
||||||
public protocol models_GreeterClientProtocol: GRPCClient {
|
|
||||||
|
|
||||||
var serviceName: String { get }
|
|
||||||
|
|
||||||
var interceptors: models_GreeterClientInterceptorFactoryProtocol? { get }
|
|
||||||
|
|
||||||
func SayHello(
|
|
||||||
_ request: Message<models_HelloRequest>
|
|
||||||
, callOptions: CallOptions?
|
|
||||||
) -> UnaryCall<Message<models_HelloRequest>, Message<models_HelloReply>>
|
|
||||||
|
|
||||||
func SayManyHellos(
|
|
||||||
_ request: Message<models_HelloRequest>
|
|
||||||
, callOptions: CallOptions?,
|
|
||||||
handler: @escaping (Message<models_HelloReply>) -> Void
|
|
||||||
) -> ServerStreamingCall<Message<models_HelloRequest>, Message<models_HelloReply>>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension models_GreeterClientProtocol {
|
|
||||||
|
|
||||||
public var serviceName: String { "models.Greeter" }
|
|
||||||
|
|
||||||
public func SayHello(
|
|
||||||
_ request: Message<models_HelloRequest>
|
|
||||||
, callOptions: CallOptions? = nil
|
|
||||||
) -> UnaryCall<Message<models_HelloRequest>, Message<models_HelloReply>> {
|
|
||||||
return self.makeUnaryCall(
|
|
||||||
path: "/models.Greeter/SayHello",
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeSayHelloInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func SayManyHellos(
|
|
||||||
_ request: Message<models_HelloRequest>
|
|
||||||
, callOptions: CallOptions? = nil,
|
|
||||||
handler: @escaping (Message<models_HelloReply>) -> Void
|
|
||||||
) -> ServerStreamingCall<Message<models_HelloRequest>, Message<models_HelloReply>> {
|
|
||||||
return self.makeServerStreamingCall(
|
|
||||||
path: "/models.Greeter/SayManyHellos",
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeSayManyHellosInterceptors() ?? [],
|
|
||||||
handler: handler
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public protocol models_GreeterClientInterceptorFactoryProtocol {
|
|
||||||
/// - Returns: Interceptors to use when invoking 'SayHello'.
|
|
||||||
func makeSayHelloInterceptors() -> [ClientInterceptor<Message<models_HelloRequest>, Message<models_HelloReply>>]
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when invoking 'SayManyHellos'.
|
|
||||||
func makeSayManyHellosInterceptors() -> [ClientInterceptor<Message<models_HelloRequest>, Message<models_HelloReply>>]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class models_GreeterServiceClient: models_GreeterClientProtocol {
|
|
||||||
public let channel: GRPCChannel
|
|
||||||
public var defaultCallOptions: CallOptions
|
|
||||||
public var interceptors: models_GreeterClientInterceptorFactoryProtocol?
|
|
||||||
|
|
||||||
public init(
|
|
||||||
channel: GRPCChannel,
|
|
||||||
defaultCallOptions: CallOptions = CallOptions(),
|
|
||||||
interceptors: models_GreeterClientInterceptorFactoryProtocol? = nil
|
|
||||||
) {
|
|
||||||
self.channel = channel
|
|
||||||
self.defaultCallOptions = defaultCallOptions
|
|
||||||
self.interceptors = interceptors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public protocol models_GreeterProvider: CallHandlerProvider {
|
|
||||||
var interceptors: models_GreeterServerInterceptorFactoryProtocol? { get }
|
|
||||||
func SayHello(request: Message<models_HelloRequest>, context: StatusOnlyCallContext) -> EventLoopFuture<Message<models_HelloReply>>
|
|
||||||
func SayManyHellos(request: Message<models_HelloRequest>, context: StreamingResponseCallContext<Message<models_HelloReply>>) -> EventLoopFuture<GRPCStatus>
|
|
||||||
}
|
|
||||||
|
|
||||||
public extension models_GreeterProvider {
|
|
||||||
|
|
||||||
var serviceName: Substring { return "models.Greeter" }
|
|
||||||
|
|
||||||
func handle(method name: Substring, context: CallHandlerContext) -> GRPCServerHandlerProtocol? {
|
|
||||||
switch name {
|
|
||||||
case "SayHello":
|
|
||||||
return UnaryServerHandler(
|
|
||||||
context: context,
|
|
||||||
requestDeserializer: GRPCPayloadDeserializer<Message<models_HelloRequest>>(),
|
|
||||||
responseSerializer: GRPCPayloadSerializer<Message<models_HelloReply>>(),
|
|
||||||
interceptors: self.interceptors?.makeSayHelloInterceptors() ?? [],
|
|
||||||
userFunction: self.SayHello(request:context:))
|
|
||||||
|
|
||||||
case "SayManyHellos":
|
|
||||||
return ServerStreamingServerHandler(
|
|
||||||
context: context,
|
|
||||||
requestDeserializer: GRPCPayloadDeserializer<Message<models_HelloRequest>>(),
|
|
||||||
responseSerializer: GRPCPayloadSerializer<Message<models_HelloReply>>(),
|
|
||||||
interceptors: self.interceptors?.makeSayManyHellosInterceptors() ?? [],
|
|
||||||
userFunction: self.SayManyHellos(request:context:))
|
|
||||||
|
|
||||||
default: return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public protocol models_GreeterServerInterceptorFactoryProtocol {
|
|
||||||
/// - Returns: Interceptors to use when handling 'SayHello'.
|
|
||||||
/// Defaults to calling `self.makeInterceptors()`.
|
|
||||||
func makeSayHelloInterceptors() -> [ServerInterceptor<Message<models_HelloRequest>, Message<models_HelloReply>>]
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when handling 'SayManyHellos'.
|
|
||||||
/// Defaults to calling `self.makeInterceptors()`.
|
|
||||||
func makeSayManyHellosInterceptors() -> [ServerInterceptor<Message<models_HelloRequest>, Message<models_HelloReply>>]
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
572
grpc/examples/swift/Greeter/Sources/Models/greeter_v2.grpc.swift
Normal file
572
grpc/examples/swift/Greeter/Sources/Models/greeter_v2.grpc.swift
Normal file
@@ -0,0 +1,572 @@
|
|||||||
|
// Generated GRPC code for FlatBuffers swift!
|
||||||
|
/// The following code is generated by the Flatbuffers library which might not be in sync with grpc-swift
|
||||||
|
/// in case of an issue please open github issue, though it would be maintained
|
||||||
|
|
||||||
|
// swiftlint:disable all
|
||||||
|
// swiftformat:disable all
|
||||||
|
|
||||||
|
#if !os(Windows) && compiler(>=6.0)
|
||||||
|
import FlatBuffers
|
||||||
|
import Foundation
|
||||||
|
import GRPCCore
|
||||||
|
import GRPCNIOTransportCore
|
||||||
|
|
||||||
|
|
||||||
|
/// Usage: instantiate models.GreeterServiceClient, then call methods of this protocol to make API calls.
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension FlatBuffersMessageSerializer: MessageSerializer {
|
||||||
|
public func serialize<Bytes>(_ message: Message) throws -> Bytes where Bytes : GRPCCore.GRPCContiguousBytes {
|
||||||
|
do {
|
||||||
|
return try self.serialize(message: message) { GRPCNIOTransportBytes($0) } as! Bytes
|
||||||
|
} catch let error {
|
||||||
|
throw RPCError(
|
||||||
|
code: .invalidArgument,
|
||||||
|
message: "Can't serialize message",
|
||||||
|
cause: error
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension FlatBuffersMessageDeserializer: MessageDeserializer {
|
||||||
|
public func deserialize<Bytes>(_ serializedMessageBytes: Bytes) throws -> Message where Bytes : GRPCCore.GRPCContiguousBytes {
|
||||||
|
do {
|
||||||
|
return try serializedMessageBytes.withUnsafeBytes {
|
||||||
|
try self.deserialize(pointer: $0)
|
||||||
|
}
|
||||||
|
} catch let error {
|
||||||
|
throw RPCError(
|
||||||
|
code: .invalidArgument,
|
||||||
|
message: "Can't Decode message of type \(Message.self)",
|
||||||
|
cause: error
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
public enum models_Greeter: Sendable {
|
||||||
|
public static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "models.Greeter")
|
||||||
|
public enum Method: Sendable {
|
||||||
|
public enum Get: Sendable {
|
||||||
|
public typealias Input = FlatBufferBuilder
|
||||||
|
public typealias Output = models_HelloResponse
|
||||||
|
public static let descriptor = GRPCCore.MethodDescriptor(
|
||||||
|
service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "models.Greeter"),
|
||||||
|
method: "Get"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public enum Collect: Sendable {
|
||||||
|
public typealias Input = FlatBufferBuilder
|
||||||
|
public typealias Output = models_HelloResponse
|
||||||
|
public static let descriptor = GRPCCore.MethodDescriptor(
|
||||||
|
service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "models.Greeter"),
|
||||||
|
method: "Collect"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public enum Expand: Sendable {
|
||||||
|
public typealias Input = FlatBufferBuilder
|
||||||
|
public typealias Output = models_HelloResponse
|
||||||
|
public static let descriptor = GRPCCore.MethodDescriptor(
|
||||||
|
service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "models.Greeter"),
|
||||||
|
method: "Expand"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public enum Update: Sendable {
|
||||||
|
public typealias Input = FlatBufferBuilder
|
||||||
|
public typealias Output = models_HelloResponse
|
||||||
|
public static let descriptor = GRPCCore.MethodDescriptor(
|
||||||
|
service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "models.Greeter"),
|
||||||
|
method: "Update"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public static let descriptors: [GRPCCore.MethodDescriptor] = [
|
||||||
|
Get.descriptor,
|
||||||
|
Collect.descriptor,
|
||||||
|
Expand.descriptor,
|
||||||
|
Update.descriptor,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension GRPCCore.ServiceDescriptor {
|
||||||
|
public static let models_Greeter = GRPCCore.ServiceDescriptor(fullyQualifiedService: "models.Greeter")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: models.Greeter Server
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension models_Greeter {
|
||||||
|
public protocol StreamingServiceProtocol: GRPCCore.RegistrableRPCService {
|
||||||
|
func Get(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>
|
||||||
|
|
||||||
|
func Collect(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>
|
||||||
|
|
||||||
|
func Expand(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>
|
||||||
|
|
||||||
|
func Update(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol ServiceProtocol: models_Greeter.StreamingServiceProtocol {
|
||||||
|
func Get(
|
||||||
|
request: GRPCCore.ServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.ServerResponse<GRPCMessage<models_HelloResponse>>
|
||||||
|
|
||||||
|
func Collect(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.ServerResponse<GRPCMessage<models_HelloResponse>>
|
||||||
|
|
||||||
|
func Expand(
|
||||||
|
request: GRPCCore.ServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>
|
||||||
|
|
||||||
|
func Update(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol SimpleServiceProtocol: models_Greeter.ServiceProtocol {
|
||||||
|
func Get(
|
||||||
|
request: GRPCMessage<models_HelloResponse>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCMessage<models_HelloResponse>
|
||||||
|
|
||||||
|
func Collect(
|
||||||
|
request: GRPCCore.RPCAsyncSequence<GRPCMessage<models_HelloResponse>, any Swift.Error>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCMessage<models_HelloResponse>
|
||||||
|
|
||||||
|
func Expand(
|
||||||
|
request: GRPCMessage<models_HelloResponse>,
|
||||||
|
response: GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws
|
||||||
|
|
||||||
|
func Update(
|
||||||
|
request: GRPCCore.RPCAsyncSequence<GRPCMessage<models_HelloResponse>, any Swift.Error>,
|
||||||
|
response: GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension models_Greeter.StreamingServiceProtocol {
|
||||||
|
public func registerMethods<Transport>(with router: inout GRPCCore.RPCRouter<Transport>) where Transport: GRPCCore.ServerTransport {
|
||||||
|
router.registerHandler(
|
||||||
|
forMethod: models_Greeter.Method.Get.descriptor,
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
handler: { request, context in
|
||||||
|
try await self.Get(
|
||||||
|
request: request,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
router.registerHandler(
|
||||||
|
forMethod: models_Greeter.Method.Collect.descriptor,
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
handler: { request, context in
|
||||||
|
try await self.Collect(
|
||||||
|
request: request,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
router.registerHandler(
|
||||||
|
forMethod: models_Greeter.Method.Expand.descriptor,
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
handler: { request, context in
|
||||||
|
try await self.Expand(
|
||||||
|
request: request,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
router.registerHandler(
|
||||||
|
forMethod: models_Greeter.Method.Update.descriptor,
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
handler: { request, context in
|
||||||
|
try await self.Update(
|
||||||
|
request: request,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension models_Greeter.ServiceProtocol {
|
||||||
|
public func Get(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>> {
|
||||||
|
let response = try await self.Get(
|
||||||
|
request: GRPCCore.ServerRequest(stream: request),
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
return GRPCCore.StreamingServerResponse(single: response)
|
||||||
|
}
|
||||||
|
public func Collect(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>> {
|
||||||
|
let response = try await self.Collect(
|
||||||
|
request: request,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
return GRPCCore.StreamingServerResponse(single: response)
|
||||||
|
}
|
||||||
|
public func Expand(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>> {
|
||||||
|
let response = try await self.Expand(
|
||||||
|
request: GRPCCore.ServerRequest(stream: request),
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension models_Greeter.SimpleServiceProtocol {
|
||||||
|
public func Get(
|
||||||
|
request: GRPCCore.ServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.ServerResponse<GRPCMessage<models_HelloResponse>> {
|
||||||
|
return GRPCCore.ServerResponse<GRPCMessage<models_HelloResponse>>(
|
||||||
|
message: try await self.Get(
|
||||||
|
request: request.message,
|
||||||
|
context: context
|
||||||
|
),
|
||||||
|
metadata: [:]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public func Collect(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.ServerResponse<GRPCMessage<models_HelloResponse>> {
|
||||||
|
return GRPCCore.ServerResponse<GRPCMessage<models_HelloResponse>>(
|
||||||
|
message: try await self.Collect(
|
||||||
|
request: request.messages,
|
||||||
|
context: context
|
||||||
|
),
|
||||||
|
metadata: [:]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public func Expand(
|
||||||
|
request: GRPCCore.ServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>> {
|
||||||
|
return GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>(
|
||||||
|
metadata: [:],
|
||||||
|
producer: { writer in
|
||||||
|
try await self.Expand(
|
||||||
|
request: request.message,
|
||||||
|
response: writer,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
return [:]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public func Update(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>> {
|
||||||
|
return GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>(
|
||||||
|
metadata: [:],
|
||||||
|
producer: { writer in
|
||||||
|
try await self.Update(
|
||||||
|
request: request.messages,
|
||||||
|
response: writer,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
return [:]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: models.Greeter Client
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension models_Greeter {
|
||||||
|
public protocol ClientProtocol: Sendable {
|
||||||
|
func Get<Result>(
|
||||||
|
request: GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
options: GRPCCore.CallOptions,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable
|
||||||
|
|
||||||
|
func Collect<Result>(
|
||||||
|
request: GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
options: GRPCCore.CallOptions,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable
|
||||||
|
|
||||||
|
func Expand<Result>(
|
||||||
|
request: GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
options: GRPCCore.CallOptions,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable
|
||||||
|
|
||||||
|
func Update<Result>(
|
||||||
|
request: GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
options: GRPCCore.CallOptions,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension models_Greeter {
|
||||||
|
public struct Client<Transport>: ClientProtocol where Transport: GRPCCore.ClientTransport {
|
||||||
|
private let client: GRPCCore.GRPCClient<Transport>
|
||||||
|
|
||||||
|
public init(wrapping client: GRPCCore.GRPCClient<Transport>) {
|
||||||
|
self.client = client
|
||||||
|
}
|
||||||
|
|
||||||
|
public func Get<Result>(
|
||||||
|
request: GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result = { response in try response.message }
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.client.unary(
|
||||||
|
request: request,
|
||||||
|
descriptor: models_Greeter.Method.Get.descriptor,
|
||||||
|
serializer: serializer,
|
||||||
|
deserializer: deserializer,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func Collect<Result>(
|
||||||
|
request: GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result = { response in try response.message }
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.client.clientStreaming(
|
||||||
|
request: request,
|
||||||
|
descriptor: models_Greeter.Method.Collect.descriptor,
|
||||||
|
serializer: serializer,
|
||||||
|
deserializer: deserializer,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func Expand<Result>(
|
||||||
|
request: GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.client.serverStreaming(
|
||||||
|
request: request,
|
||||||
|
descriptor: models_Greeter.Method.Expand.descriptor,
|
||||||
|
serializer: serializer,
|
||||||
|
deserializer: deserializer,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func Update<Result>(
|
||||||
|
request: GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.client.bidirectionalStreaming(
|
||||||
|
request: request,
|
||||||
|
descriptor: models_Greeter.Method.Update.descriptor,
|
||||||
|
serializer: serializer,
|
||||||
|
deserializer: deserializer,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension models_Greeter.ClientProtocol {
|
||||||
|
public func Get<Result>(
|
||||||
|
request: GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result = { response in try response.message }
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.Get(
|
||||||
|
request: request,
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func Collect<Result>(
|
||||||
|
request: GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result = { response in try response.message }
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.Collect(
|
||||||
|
request: request,
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func Expand<Result>(
|
||||||
|
request: GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.Expand(
|
||||||
|
request: request,
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func Update<Result>(
|
||||||
|
request: GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.Update(
|
||||||
|
request: request,
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension models_Greeter.ClientProtocol {
|
||||||
|
public func Get<Result>(
|
||||||
|
_ message: GRPCMessage<models_HelloResponse>,
|
||||||
|
metadata: GRPCCore.Metadata = [:],
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result = { try $0.message }
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
let request = GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>(
|
||||||
|
message: message,
|
||||||
|
metadata: metadata
|
||||||
|
)
|
||||||
|
return try await self.Get(
|
||||||
|
request: request,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func Collect<Result>(
|
||||||
|
metadata: GRPCCore.Metadata = [:],
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>) async throws -> Void,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result = { try $0.message }
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
let request = GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>(
|
||||||
|
metadata: metadata,
|
||||||
|
producer: producer
|
||||||
|
)
|
||||||
|
return try await self.Collect(
|
||||||
|
request: request,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func Expand<Result>(
|
||||||
|
_ message: GRPCMessage<models_HelloResponse>,
|
||||||
|
metadata: GRPCCore.Metadata = [:],
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
let request = GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>(
|
||||||
|
message: message,
|
||||||
|
metadata: metadata
|
||||||
|
)
|
||||||
|
return try await self.Expand(
|
||||||
|
request: request,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func Update<Result>(
|
||||||
|
metadata: GRPCCore.Metadata = [:],
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>) async throws -> Void,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
let request = GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>(
|
||||||
|
metadata: metadata,
|
||||||
|
producer: producer
|
||||||
|
)
|
||||||
|
return try await self.Update(
|
||||||
|
request: request,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ import Common
|
|||||||
|
|
||||||
import FlatBuffers
|
import FlatBuffers
|
||||||
|
|
||||||
public struct models_HelloReply: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable {
|
public struct models_HelloResponse: FlatBufferVerifiableTable, FlatbuffersVectorInitializable {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
@@ -17,45 +17,43 @@ public struct models_HelloReply: FlatBufferTable, FlatbuffersVectorInitializable
|
|||||||
private init(_ t: Table) { _accessor = t }
|
private init(_ t: Table) { _accessor = t }
|
||||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||||
|
|
||||||
private enum VTOFFSET: VOffset {
|
private struct VT {
|
||||||
case message = 4
|
static let message: VOffset = 4
|
||||||
var v: Int32 { Int32(self.rawValue) }
|
|
||||||
var p: VOffset { self.rawValue }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var message: String? { let o = _accessor.offset(VTOFFSET.message.v); return o == 0 ? nil : _accessor.string(at: o) }
|
public var message: String? { let o = _accessor.offset(VT.message); return o == 0 ? nil : _accessor.string(at: o) }
|
||||||
public var messageSegmentArray: [UInt8]? { return _accessor.getVector(at: VTOFFSET.message.v) }
|
public var messageSegmentArray: [UInt8]? { return _accessor.getVector(at: VT.message) }
|
||||||
public static func startHelloReply(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
public static func startHelloResponse(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
||||||
public static func add(message: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: message, at: VTOFFSET.message.p) }
|
public static func add(message: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: message, at: VT.message) }
|
||||||
public static func endHelloReply(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
|
public static func endHelloResponse(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
|
||||||
public static func createHelloReply(
|
public static func createHelloResponse(
|
||||||
_ fbb: inout FlatBufferBuilder,
|
_ fbb: inout FlatBufferBuilder,
|
||||||
messageOffset message: Offset = Offset()
|
messageOffset message: Offset = Offset()
|
||||||
) -> Offset {
|
) -> Offset {
|
||||||
let __start = models_HelloReply.startHelloReply(&fbb)
|
let __start = models_HelloResponse.startHelloResponse(&fbb)
|
||||||
models_HelloReply.add(message: message, &fbb)
|
models_HelloResponse.add(message: message, &fbb)
|
||||||
return models_HelloReply.endHelloReply(&fbb, start: __start)
|
return models_HelloResponse.endHelloResponse(&fbb, start: __start)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||||
var _v = try verifier.visitTable(at: position)
|
var _v = try verifier.visitTable(at: position)
|
||||||
try _v.visit(field: VTOFFSET.message.p, fieldName: "message", required: false, type: ForwardOffset<String>.self)
|
try _v.visit(field: VT.message, fieldName: "message", required: false, type: ForwardOffset<String>.self)
|
||||||
_v.finish()
|
_v.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension models_HelloReply: Encodable {
|
extension models_HelloResponse: Encodable {
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case message = "message"
|
case message = "message"
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encodeIfPresent(message, forKey: .message)
|
try container.encodeIfPresent(message, forKey: .message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct models_HelloRequest: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable {
|
public struct models_HelloRequest: FlatBufferVerifiableTable, FlatbuffersVectorInitializable {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
@@ -64,16 +62,14 @@ public struct models_HelloRequest: FlatBufferTable, FlatbuffersVectorInitializab
|
|||||||
private init(_ t: Table) { _accessor = t }
|
private init(_ t: Table) { _accessor = t }
|
||||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||||
|
|
||||||
private enum VTOFFSET: VOffset {
|
private struct VT {
|
||||||
case name = 4
|
static let name: VOffset = 4
|
||||||
var v: Int32 { Int32(self.rawValue) }
|
|
||||||
var p: VOffset { self.rawValue }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var name: String? { let o = _accessor.offset(VTOFFSET.name.v); return o == 0 ? nil : _accessor.string(at: o) }
|
public var name: String? { let o = _accessor.offset(VT.name); return o == 0 ? nil : _accessor.string(at: o) }
|
||||||
public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: VTOFFSET.name.v) }
|
public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: VT.name) }
|
||||||
public static func startHelloRequest(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
public static func startHelloRequest(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
||||||
public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VTOFFSET.name.p) }
|
public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VT.name) }
|
||||||
public static func endHelloRequest(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
|
public static func endHelloRequest(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
|
||||||
public static func createHelloRequest(
|
public static func createHelloRequest(
|
||||||
_ fbb: inout FlatBufferBuilder,
|
_ fbb: inout FlatBufferBuilder,
|
||||||
@@ -86,16 +82,16 @@ public struct models_HelloRequest: FlatBufferTable, FlatbuffersVectorInitializab
|
|||||||
|
|
||||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||||
var _v = try verifier.visitTable(at: position)
|
var _v = try verifier.visitTable(at: position)
|
||||||
try _v.visit(field: VTOFFSET.name.p, fieldName: "name", required: false, type: ForwardOffset<String>.self)
|
try _v.visit(field: VT.name, fieldName: "name", required: false, type: ForwardOffset<String>.self)
|
||||||
_v.finish()
|
_v.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension models_HelloRequest: Encodable {
|
extension models_HelloRequest: Encodable {
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case name = "name"
|
case name = "name"
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encodeIfPresent(name, forKey: .name)
|
try container.encodeIfPresent(name, forKey: .name)
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2024 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import FlatBuffers
|
|
||||||
import GRPC
|
|
||||||
import Logging
|
|
||||||
import Model
|
|
||||||
import NIO
|
|
||||||
|
|
||||||
// Quieten the logs.
|
|
||||||
LoggingSystem.bootstrap {
|
|
||||||
var handler = StreamLogHandler.standardOutput(label: $0)
|
|
||||||
handler.logLevel = .critical
|
|
||||||
return handler
|
|
||||||
}
|
|
||||||
|
|
||||||
func greet(name: String, client greeter: models_GreeterServiceClient) {
|
|
||||||
// Form the request with the name, if one was provided.
|
|
||||||
var builder = FlatBufferBuilder()
|
|
||||||
let nameOff = builder.create(string: name)
|
|
||||||
let root = models_HelloRequest.createHelloRequest(
|
|
||||||
&builder,
|
|
||||||
nameOffset: nameOff)
|
|
||||||
builder.finish(offset: root)
|
|
||||||
|
|
||||||
// Make the RPC call to the server.
|
|
||||||
let sayHello =
|
|
||||||
greeter
|
|
||||||
.SayHello(Message<models_HelloRequest>(builder: &builder))
|
|
||||||
|
|
||||||
// wait() on the response to stop the program from exiting before the response is received.
|
|
||||||
do {
|
|
||||||
let response = try sayHello.response.wait()
|
|
||||||
print("Greeter SayHello received: \(response.object.message ?? "Unknown")")
|
|
||||||
} catch {
|
|
||||||
print("Greeter failed: \(error)")
|
|
||||||
}
|
|
||||||
|
|
||||||
let surname = builder.create(string: name)
|
|
||||||
let manyRoot = models_HelloRequest.createHelloRequest(
|
|
||||||
&builder,
|
|
||||||
nameOffset: surname)
|
|
||||||
builder.finish(offset: manyRoot)
|
|
||||||
|
|
||||||
let call = greeter.SayManyHellos(Message(builder: &builder)) { message in
|
|
||||||
print(
|
|
||||||
"Greeter SayManyHellos received: \(message.object.message ?? "Unknown")")
|
|
||||||
}
|
|
||||||
|
|
||||||
let status = try! call.status.recover { _ in .processingError }.wait()
|
|
||||||
if status.code != .ok {
|
|
||||||
print("RPC failed: \(status)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main(args: [String]) {
|
|
||||||
// arg0 (dropped) is the program name. We expect arg1 to be the port, and arg2 (optional) to be
|
|
||||||
// the name sent in the request.
|
|
||||||
let arg1 = args.dropFirst(1).first
|
|
||||||
let arg2 = args.dropFirst(2).first
|
|
||||||
|
|
||||||
switch (arg1.flatMap(Int.init), arg2) {
|
|
||||||
case (.none, _):
|
|
||||||
print("Usage: PORT [NAME]")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
case (.some(let port), let name):
|
|
||||||
// Setup an `EventLoopGroup` for the connection to run on.
|
|
||||||
//
|
|
||||||
// See: https://github.com/apple/swift-nio#eventloops-and-eventloopgroups
|
|
||||||
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
|
|
||||||
|
|
||||||
// Make sure the group is shutdown when we're done with it.
|
|
||||||
defer {
|
|
||||||
try! group.syncShutdownGracefully()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure the channel, we're not using TLS so the connection is `insecure`.
|
|
||||||
let channel = ClientConnection.insecure(group: group)
|
|
||||||
.connect(host: "localhost", port: port)
|
|
||||||
|
|
||||||
// Close the connection when we're done with it.
|
|
||||||
defer {
|
|
||||||
try! channel.close().wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide the connection to the generated client.
|
|
||||||
let greeter = models_GreeterServiceClient(channel: channel)
|
|
||||||
|
|
||||||
// Do the greeting.
|
|
||||||
greet(name: name ?? "FlatBuffers!", client: greeter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main(args: CommandLine.arguments)
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2024 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import FlatBuffers
|
|
||||||
import GRPC
|
|
||||||
import Logging
|
|
||||||
import Model
|
|
||||||
import NIO
|
|
||||||
|
|
||||||
class Greeter: models_GreeterProvider {
|
|
||||||
|
|
||||||
var interceptors: models_GreeterServerInterceptorFactoryProtocol?
|
|
||||||
|
|
||||||
let greetings: [String]
|
|
||||||
|
|
||||||
init() {
|
|
||||||
greetings = ["Hi", "Hallo", "Ciao"]
|
|
||||||
}
|
|
||||||
|
|
||||||
func SayHello(
|
|
||||||
request: Message<models_HelloRequest>,
|
|
||||||
context: StatusOnlyCallContext)
|
|
||||||
-> EventLoopFuture<Message<models_HelloReply>>
|
|
||||||
{
|
|
||||||
let recipient = request.object.name ?? "Stranger"
|
|
||||||
|
|
||||||
var builder = FlatBufferBuilder()
|
|
||||||
let off = builder.create(string: "Hello \(recipient)")
|
|
||||||
let root = models_HelloReply.createHelloReply(&builder, messageOffset: off)
|
|
||||||
builder.finish(offset: root)
|
|
||||||
return context.eventLoop
|
|
||||||
.makeSucceededFuture(Message<models_HelloReply>(builder: &builder))
|
|
||||||
}
|
|
||||||
|
|
||||||
func SayManyHellos(
|
|
||||||
request: Message<models_HelloRequest>,
|
|
||||||
context: StreamingResponseCallContext<Message<models_HelloReply>>)
|
|
||||||
-> EventLoopFuture<GRPCStatus>
|
|
||||||
{
|
|
||||||
for name in greetings {
|
|
||||||
var builder = FlatBufferBuilder()
|
|
||||||
let off =
|
|
||||||
builder
|
|
||||||
.create(string: "\(name) \(request.object.name ?? "Unknown")")
|
|
||||||
let root = models_HelloReply.createHelloReply(
|
|
||||||
&builder,
|
|
||||||
messageOffset: off)
|
|
||||||
builder.finish(offset: root)
|
|
||||||
_ = context.sendResponse(Message<models_HelloReply>(builder: &builder))
|
|
||||||
}
|
|
||||||
return context.eventLoop.makeSucceededFuture(.ok)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quieten the logs.
|
|
||||||
LoggingSystem.bootstrap {
|
|
||||||
var handler = StreamLogHandler.standardOutput(label: $0)
|
|
||||||
handler.logLevel = .critical
|
|
||||||
return handler
|
|
||||||
}
|
|
||||||
|
|
||||||
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
|
|
||||||
defer {
|
|
||||||
try! group.syncShutdownGracefully()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create some configuration for the server:
|
|
||||||
let configuration = Server.Configuration(
|
|
||||||
target: .hostAndPort("localhost", 0),
|
|
||||||
eventLoopGroup: group,
|
|
||||||
serviceProviders: [Greeter()])
|
|
||||||
|
|
||||||
// Start the server and print its address once it has started.
|
|
||||||
let server = Server.start(configuration: configuration)
|
|
||||||
server.map {
|
|
||||||
$0.channel.localAddress
|
|
||||||
}.whenSuccess { address in
|
|
||||||
print("server started on port \(address!.port!)")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait on the server's `onClose` future to stop the program from exiting.
|
|
||||||
_ = try server.flatMap {
|
|
||||||
$0.onClose
|
|
||||||
}.wait()
|
|
||||||
@@ -172,6 +172,7 @@ class StubGenerator : public BaseGenerator {
|
|||||||
<< " def __init__(self, channel: grpc.Channel) -> None: ...\n";
|
<< " def __init__(self, channel: grpc.Channel) -> None: ...\n";
|
||||||
|
|
||||||
for (const RPCCall* method : service->calls.vec) {
|
for (const RPCCall* method : service->calls.vec) {
|
||||||
|
imports->Import("typing");
|
||||||
std::string request = "bytes";
|
std::string request = "bytes";
|
||||||
std::string response = "bytes";
|
std::string response = "bytes";
|
||||||
|
|
||||||
@@ -183,14 +184,22 @@ class StubGenerator : public BaseGenerator {
|
|||||||
imports->Import(ModuleFor(method->response), response);
|
imports->Import(ModuleFor(method->response), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
ss << " def " << method->name << "(self, ";
|
ss << " def " << method->name << "(\n";
|
||||||
|
ss << " self,\n";
|
||||||
if (ClientStreaming(method)) {
|
if (ClientStreaming(method)) {
|
||||||
imports->Import("typing");
|
ss << " request_iterator: typing.Iterator[" << request << "]\n";
|
||||||
ss << "request_iterator: typing.Iterator[" << request << "]";
|
|
||||||
} else {
|
} else {
|
||||||
ss << "request: " << request;
|
ss << " request: " << request << ",\n";
|
||||||
}
|
}
|
||||||
ss << ") -> ";
|
|
||||||
|
ss << " timeout: float | None = None,\n";
|
||||||
|
// https://github.com/python/typeshed/blob/ccf9411fb1f5bee2a8e3d278889de17a08f7bbe3/stubs/grpcio/grpc/__init__.pyi#L37
|
||||||
|
ss << " metadata: typing.Sequence[tuple[str, typing.Union[str, bytes]]] | None = None,\n";
|
||||||
|
ss << " credentials: grpc.CallCredentials | None = None,\n";
|
||||||
|
ss << " wait_for_ready: bool | None = None,\n";
|
||||||
|
ss << " compression: grpc.Compression | None = None\n";
|
||||||
|
|
||||||
|
ss << " ) -> ";
|
||||||
if (ServerStreaming(method)) {
|
if (ServerStreaming(method)) {
|
||||||
imports->Import("typing");
|
imports->Import("typing");
|
||||||
ss << "typing.Iterator[" << response << "]";
|
ss << "typing.Iterator[" << response << "]";
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -91,6 +91,14 @@ class Namer {
|
|||||||
std::string keyword_prefix;
|
std::string keyword_prefix;
|
||||||
// Suffix used to escape keywords. It is usually "_".
|
// Suffix used to escape keywords. It is usually "_".
|
||||||
std::string keyword_suffix;
|
std::string keyword_suffix;
|
||||||
|
// The casing used for keywords when escaping. For most languages, keywords
|
||||||
|
// are case sensitive. PHP is an instance where some keywords are case
|
||||||
|
// insensitive.
|
||||||
|
enum class KeywordsCasing {
|
||||||
|
CaseSensitive,
|
||||||
|
CaseInsensitive,
|
||||||
|
};
|
||||||
|
KeywordsCasing keywords_casing;
|
||||||
|
|
||||||
// Files.
|
// Files.
|
||||||
|
|
||||||
@@ -204,8 +212,16 @@ class Namer {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::string NormalizeKeywordCase(const std::string& name) const {
|
||||||
|
if (config_.keywords_casing == Config::KeywordsCasing::CaseInsensitive) {
|
||||||
|
return ConvertCase(name, Case::kAllLower);
|
||||||
|
} else {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual std::string EscapeKeyword(const std::string& name) const {
|
virtual std::string EscapeKeyword(const std::string& name) const {
|
||||||
if (keywords_.find(name) == keywords_.end()) {
|
if (keywords_.find(NormalizeKeywordCase(name)) == keywords_.end()) {
|
||||||
return name;
|
return name;
|
||||||
} else {
|
} else {
|
||||||
return config_.keyword_prefix + name + config_.keyword_suffix;
|
return config_.keyword_prefix + name + config_.keyword_suffix;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ static const Namer::Config kConfig = {
|
|||||||
/*object_suffix=*/"T",
|
/*object_suffix=*/"T",
|
||||||
/*keyword_prefix=*/"",
|
/*keyword_prefix=*/"",
|
||||||
/*keyword_suffix=*/"_",
|
/*keyword_suffix=*/"_",
|
||||||
|
/*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
|
||||||
/*filenames=*/Case::kKeep,
|
/*filenames=*/Case::kKeep,
|
||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
@@ -49,6 +50,7 @@ static const Namer::Config kStubConfig = {
|
|||||||
/*object_suffix=*/"T",
|
/*object_suffix=*/"T",
|
||||||
/*keyword_prefix=*/"",
|
/*keyword_prefix=*/"",
|
||||||
/*keyword_suffix=*/"_",
|
/*keyword_suffix=*/"_",
|
||||||
|
/*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
|
||||||
/*filenames=*/Case::kKeep,
|
/*filenames=*/Case::kKeep,
|
||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
|
|||||||
@@ -260,15 +260,15 @@ inline const char* flatbuffers_version_string() {
|
|||||||
inline FLATBUFFERS_CONSTEXPR_CPP11 E operator ~ (E lhs){\
|
inline FLATBUFFERS_CONSTEXPR_CPP11 E operator ~ (E lhs){\
|
||||||
return E(~T(lhs));\
|
return E(~T(lhs));\
|
||||||
}\
|
}\
|
||||||
inline FLATBUFFERS_CONSTEXPR_CPP11 E operator |= (E &lhs, E rhs){\
|
inline FLATBUFFERS_CONSTEXPR_CPP14 E operator |= (E &lhs, E rhs){\
|
||||||
lhs = lhs | rhs;\
|
lhs = lhs | rhs;\
|
||||||
return lhs;\
|
return lhs;\
|
||||||
}\
|
}\
|
||||||
inline FLATBUFFERS_CONSTEXPR_CPP11 E operator &= (E &lhs, E rhs){\
|
inline FLATBUFFERS_CONSTEXPR_CPP14 E operator &= (E &lhs, E rhs){\
|
||||||
lhs = lhs & rhs;\
|
lhs = lhs & rhs;\
|
||||||
return lhs;\
|
return lhs;\
|
||||||
}\
|
}\
|
||||||
inline FLATBUFFERS_CONSTEXPR_CPP11 E operator ^= (E &lhs, E rhs){\
|
inline FLATBUFFERS_CONSTEXPR_CPP14 E operator ^= (E &lhs, E rhs){\
|
||||||
lhs = lhs ^ rhs;\
|
lhs = lhs ^ rhs;\
|
||||||
return lhs;\
|
return lhs;\
|
||||||
}\
|
}\
|
||||||
|
|||||||
@@ -1207,11 +1207,20 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
String(str);
|
String(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t AlignedBlob(const void* data, size_t len, BitWidth alignment) {
|
||||||
|
// The requested alignment must not be smaller than the one required to
|
||||||
|
// store the length.
|
||||||
|
return CreateAlignedBlob(data, len, 0, FBT_BLOB,
|
||||||
|
std::max(alignment, WidthU(len)));
|
||||||
|
}
|
||||||
|
size_t AlignedBlob(const std::vector<uint8_t>& v, BitWidth alignment) {
|
||||||
|
return AlignedBlob(v.data(), v.size(), alignment);
|
||||||
|
}
|
||||||
size_t Blob(const void* data, size_t len) {
|
size_t Blob(const void* data, size_t len) {
|
||||||
return CreateBlob(data, len, 0, FBT_BLOB);
|
return CreateBlob(data, len, 0, FBT_BLOB);
|
||||||
}
|
}
|
||||||
size_t Blob(const std::vector<uint8_t>& v) {
|
size_t Blob(const std::vector<uint8_t>& v) {
|
||||||
return CreateBlob(v.data(), v.size(), 0, FBT_BLOB);
|
return Blob(v.data(), v.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Blob(const char* key, const void* data, size_t len) {
|
void Blob(const char* key, const void* data, size_t len) {
|
||||||
@@ -1693,11 +1702,16 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
|
|
||||||
size_t CreateBlob(const void* data, size_t len, size_t trailing, Type type) {
|
size_t CreateBlob(const void* data, size_t len, size_t trailing, Type type) {
|
||||||
auto bit_width = WidthU(len);
|
auto bit_width = WidthU(len);
|
||||||
auto byte_width = Align(bit_width);
|
return CreateAlignedBlob(data, len, trailing, type, bit_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CreateAlignedBlob(const void* data, size_t len, size_t trailing,
|
||||||
|
Type type, BitWidth alignment) {
|
||||||
|
auto byte_width = Align(alignment);
|
||||||
Write<uint64_t>(len, byte_width);
|
Write<uint64_t>(len, byte_width);
|
||||||
auto sloc = buf_.size();
|
auto sloc = buf_.size();
|
||||||
WriteBytes(data, len + trailing);
|
WriteBytes(data, len + trailing);
|
||||||
stack_.push_back(Value(static_cast<uint64_t>(sloc), type, bit_width));
|
stack_.push_back(Value(static_cast<uint64_t>(sloc), type, alignment));
|
||||||
return sloc;
|
return sloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1962,7 +1976,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||||||
bool VerifyKey(const uint8_t* p) {
|
bool VerifyKey(const uint8_t* p) {
|
||||||
FLEX_CHECK_VERIFIED(p, PackedType(BIT_WIDTH_8, FBT_KEY));
|
FLEX_CHECK_VERIFIED(p, PackedType(BIT_WIDTH_8, FBT_KEY));
|
||||||
while (p < buf_ + size_)
|
while (p < buf_ + size_)
|
||||||
if (*p++) return true;
|
if (!*p++) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ struct Type {
|
|||||||
uint16_t fixed_length; // only set if t == BASE_TYPE_ARRAY
|
uint16_t fixed_length; // only set if t == BASE_TYPE_ARRAY
|
||||||
};
|
};
|
||||||
|
|
||||||
// Represents a parsed scalar value, it's type, and field offset.
|
// Represents a parsed scalar value, its type, and field offset.
|
||||||
struct Value {
|
struct Value {
|
||||||
Value()
|
Value()
|
||||||
: constant("0"),
|
: constant("0"),
|
||||||
@@ -395,13 +395,20 @@ struct FieldDef : public Definition {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct StructDef : public Definition {
|
struct StructDef : public Definition {
|
||||||
|
enum class CycleStatus {
|
||||||
|
NotChecked,
|
||||||
|
InProgress,
|
||||||
|
Checked,
|
||||||
|
};
|
||||||
|
|
||||||
StructDef()
|
StructDef()
|
||||||
: fixed(false),
|
: fixed(false),
|
||||||
predecl(true),
|
predecl(true),
|
||||||
sortbysize(true),
|
sortbysize(true),
|
||||||
has_key(false),
|
has_key(false),
|
||||||
minalign(1),
|
minalign(1),
|
||||||
bytesize(0) {}
|
bytesize(0),
|
||||||
|
cycle_status{CycleStatus::NotChecked} {}
|
||||||
|
|
||||||
void PadLastField(size_t min_align) {
|
void PadLastField(size_t min_align) {
|
||||||
auto padding = PaddingBytes(bytesize, min_align);
|
auto padding = PaddingBytes(bytesize, min_align);
|
||||||
@@ -423,6 +430,8 @@ struct StructDef : public Definition {
|
|||||||
size_t minalign; // What the whole object needs to be aligned to.
|
size_t minalign; // What the whole object needs to be aligned to.
|
||||||
size_t bytesize; // Size if fixed.
|
size_t bytesize; // Size if fixed.
|
||||||
|
|
||||||
|
CycleStatus cycle_status; // used for determining if we have circular references
|
||||||
|
|
||||||
flatbuffers::unique_ptr<std::string> original_location;
|
flatbuffers::unique_ptr<std::string> original_location;
|
||||||
std::vector<voffset_t> reserved_ids;
|
std::vector<voffset_t> reserved_ids;
|
||||||
};
|
};
|
||||||
@@ -734,6 +743,7 @@ struct IDLOptions {
|
|||||||
bool python_gen_numpy;
|
bool python_gen_numpy;
|
||||||
|
|
||||||
bool ts_omit_entrypoint;
|
bool ts_omit_entrypoint;
|
||||||
|
bool ts_undefined_for_optionals;
|
||||||
ProtoIdGapAction proto_id_gap_action;
|
ProtoIdGapAction proto_id_gap_action;
|
||||||
|
|
||||||
// Possible options for the more general generator below.
|
// Possible options for the more general generator below.
|
||||||
@@ -860,6 +870,7 @@ struct IDLOptions {
|
|||||||
python_typing(false),
|
python_typing(false),
|
||||||
python_gen_numpy(true),
|
python_gen_numpy(true),
|
||||||
ts_omit_entrypoint(false),
|
ts_omit_entrypoint(false),
|
||||||
|
ts_undefined_for_optionals(false),
|
||||||
proto_id_gap_action(ProtoIdGapAction::WARNING),
|
proto_id_gap_action(ProtoIdGapAction::WARNING),
|
||||||
mini_reflect(IDLOptions::kNone),
|
mini_reflect(IDLOptions::kNone),
|
||||||
require_explicit_ids(false),
|
require_explicit_ids(false),
|
||||||
@@ -1099,6 +1110,8 @@ class Parser : public ParserState {
|
|||||||
// others includes.
|
// others includes.
|
||||||
std::vector<IncludedFile> GetIncludedFiles() const;
|
std::vector<IncludedFile> GetIncludedFiles() const;
|
||||||
|
|
||||||
|
bool HasCircularStructDependency();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ParseDepthGuard;
|
class ParseDepthGuard;
|
||||||
|
|
||||||
|
|||||||
@@ -30,50 +30,52 @@ namespace flatbuffers {
|
|||||||
|
|
||||||
// ------------------------- GETTERS -------------------------
|
// ------------------------- GETTERS -------------------------
|
||||||
|
|
||||||
inline bool IsScalar(reflection::BaseType t) {
|
constexpr bool IsScalar(reflection::BaseType t) {
|
||||||
return t >= reflection::UType && t <= reflection::Double;
|
return t >= reflection::UType && t <= reflection::Double;
|
||||||
}
|
}
|
||||||
inline bool IsInteger(reflection::BaseType t) {
|
constexpr bool IsInteger(reflection::BaseType t) {
|
||||||
return t >= reflection::UType && t <= reflection::ULong;
|
return t >= reflection::UType && t <= reflection::ULong;
|
||||||
}
|
}
|
||||||
inline bool IsFloat(reflection::BaseType t) {
|
constexpr bool IsFloat(reflection::BaseType t) {
|
||||||
return t == reflection::Float || t == reflection::Double;
|
return t == reflection::Float || t == reflection::Double;
|
||||||
}
|
}
|
||||||
inline bool IsLong(reflection::BaseType t) {
|
constexpr bool IsLong(reflection::BaseType t) {
|
||||||
return t == reflection::Long || t == reflection::ULong;
|
return t == reflection::Long || t == reflection::ULong;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size of a basic type, don't use with structs.
|
// This needs to correspond to the BaseType enum.
|
||||||
inline size_t GetTypeSize(reflection::BaseType base_type) {
|
constexpr size_t kBaseTypeSize[] = {
|
||||||
// This needs to correspond to the BaseType enum.
|
0, // None
|
||||||
static size_t sizes[] = {
|
1, // UType
|
||||||
0, // None
|
1, // Bool
|
||||||
1, // UType
|
1, // Byte
|
||||||
1, // Bool
|
1, // UByte
|
||||||
1, // Byte
|
2, // Short
|
||||||
1, // UByte
|
2, // UShort
|
||||||
2, // Short
|
4, // Int
|
||||||
2, // UShort
|
4, // UInt
|
||||||
4, // Int
|
8, // Long
|
||||||
4, // UInt
|
8, // ULong
|
||||||
8, // Long
|
4, // Float
|
||||||
8, // ULong
|
8, // Double
|
||||||
4, // Float
|
4, // String
|
||||||
8, // Double
|
4, // Vector
|
||||||
4, // String
|
4, // Obj
|
||||||
4, // Vector
|
4, // Union
|
||||||
4, // Obj
|
0, // Array. Only used in structs. 0 was chosen to prevent out-of-bounds
|
||||||
4, // Union
|
// errors.
|
||||||
0, // Array. Only used in structs. 0 was chosen to prevent out-of-bounds
|
8, // Vector64
|
||||||
// errors.
|
|
||||||
8, // Vector64
|
|
||||||
|
|
||||||
0 // MaxBaseType. This must be kept the last entry in this array.
|
0 // MaxBaseType. This must be kept the last entry in this array.
|
||||||
};
|
};
|
||||||
static_assert(sizeof(sizes) / sizeof(size_t) == reflection::MaxBaseType + 1,
|
static_assert(sizeof(kBaseTypeSize) / sizeof(size_t) ==
|
||||||
"Size of sizes[] array does not match the count of BaseType "
|
reflection::MaxBaseType + 1,
|
||||||
"enum values.");
|
"Size of sizes[] array does not match the count of BaseType "
|
||||||
return sizes[base_type];
|
"enum values.");
|
||||||
|
|
||||||
|
// Size of a basic type, don't use with structs.
|
||||||
|
constexpr size_t GetTypeSize(reflection::BaseType base_type) {
|
||||||
|
return kBaseTypeSize[base_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as above, but now correctly returns the size of a struct if
|
// Same as above, but now correctly returns the size of a struct if
|
||||||
@@ -420,7 +422,7 @@ pointer_inside_vector<T, U> piv(T* ptr, std::vector<U>& vec) {
|
|||||||
return pointer_inside_vector<T, U>(ptr, vec);
|
return pointer_inside_vector<T, U>(ptr, vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char* UnionTypeFieldSuffix() { return "_type"; }
|
constexpr const char* UnionTypeFieldSuffix() { return "_type"; }
|
||||||
|
|
||||||
// Helper to figure out the actual table type a union refers to.
|
// Helper to figure out the actual table type a union refers to.
|
||||||
inline const reflection::Object& GetUnionType(
|
inline const reflection::Object& GetUnionType(
|
||||||
|
|||||||
@@ -14,9 +14,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
@file:Suppress("NOTHING_TO_INLINE")
|
@file:Suppress("NOTHING_TO_INLINE")
|
||||||
|
@file:OptIn(ExperimentalNativeApi::class)
|
||||||
|
|
||||||
package com.google.flatbuffers.kotlin
|
package com.google.flatbuffers.kotlin
|
||||||
|
|
||||||
|
import kotlin.experimental.ExperimentalNativeApi
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation assumes that of native macOSX64 the byte order of the implementation is
|
* This implementation assumes that of native macOSX64 the byte order of the implementation is
|
||||||
* Little Endian.
|
* Little Endian.
|
||||||
|
|||||||
@@ -296,25 +296,62 @@ function mt:Slot(slotnum)
|
|||||||
self.currentVTable[slotnum + 1] = self:Offset()
|
self.currentVTable[slotnum + 1] = self:Offset()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function finish(self, rootTable, sizePrefix)
|
local function finish(self, rootTable, sizePrefix, fileIdentifier)
|
||||||
UOffsetT:EnforceNumber(rootTable)
|
UOffsetT:EnforceNumber(rootTable)
|
||||||
self:Prep(self.minalign, sizePrefix and 8 or 4)
|
local hasFid = fileIdentifier ~= nil
|
||||||
self:PrependUOffsetTRelative(rootTable)
|
if hasFid then
|
||||||
|
assert(#fileIdentifier == 4, "File identifier must be exactly 4 bytes")
|
||||||
|
end
|
||||||
|
|
||||||
|
local fid_byte_count = (hasFid and 4 or 0)
|
||||||
|
|
||||||
|
-- alignment:
|
||||||
|
-- root offset (4)
|
||||||
|
-- optional file id (4)
|
||||||
|
-- optional size prefix (4)
|
||||||
|
self:Prep(
|
||||||
|
self.minalign,
|
||||||
|
(sizePrefix and 4 or 0) +
|
||||||
|
4 +
|
||||||
|
fid_byte_count
|
||||||
|
)
|
||||||
|
|
||||||
|
-- root offset (points past file identifier if present)
|
||||||
|
self:PrependUOffsetTRelative(rootTable + fid_byte_count)
|
||||||
|
|
||||||
|
-- file identifier
|
||||||
|
if hasFid then
|
||||||
|
for i = 4, 1, -1 do
|
||||||
|
self:PrependByte(string.byte(fileIdentifier, i))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- size prefix
|
||||||
if sizePrefix then
|
if sizePrefix then
|
||||||
local size = self.bytes.size - self.head
|
local size = self.bytes.size - self.head
|
||||||
Int32:EnforceNumber(size)
|
Int32:EnforceNumber(size)
|
||||||
self:PrependInt32(size)
|
self:PrependInt32(size)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.finished = true
|
self.finished = true
|
||||||
return self.head
|
return self.head
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function mt:Finish(rootTable)
|
function mt:Finish(rootTable)
|
||||||
return finish(self, rootTable, false)
|
return finish(self, rootTable, false, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mt:FinishSizePrefixed(rootTable)
|
function mt:FinishSizePrefixed(rootTable)
|
||||||
return finish(self, rootTable, true)
|
return finish(self, rootTable, true, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mt:FinishWithIdentifier(rootTable, fileIdentifier)
|
||||||
|
return finish(self, rootTable, false, fileIdentifier)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mt:FinishSizePrefixedWithIdentifier(rootTable, fileIdentifier)
|
||||||
|
return finish(self, rootTable, true, fileIdentifier)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mt:Prepend(flags, off)
|
function mt:Prepend(flags, off)
|
||||||
|
|||||||
@@ -438,8 +438,7 @@ namespace Google.FlatBuffers
|
|||||||
if (off > Offset)
|
if (off > Offset)
|
||||||
throw new ArgumentException();
|
throw new ArgumentException();
|
||||||
|
|
||||||
if (off != 0)
|
off = Offset - off + sizeof(int);
|
||||||
off = Offset - off + sizeof(int);
|
|
||||||
PutInt(off);
|
PutInt(off);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,11 +65,7 @@ namespace Google.FlatBuffers
|
|||||||
// Create a .NET String from UTF-8 data stored inside the flatbuffer.
|
// Create a .NET String from UTF-8 data stored inside the flatbuffer.
|
||||||
public string __string(int offset)
|
public string __string(int offset)
|
||||||
{
|
{
|
||||||
int stringOffset = bb.GetInt(offset);
|
offset += bb.GetInt(offset);
|
||||||
if (stringOffset == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
offset += stringOffset;
|
|
||||||
var len = bb.GetInt(offset);
|
var len = bb.GetInt(offset);
|
||||||
var startPos = offset + sizeof(int);
|
var startPos = offset + sizeof(int);
|
||||||
return bb.GetStringUTF8(startPos, len);
|
return bb.GetStringUTF8(startPos, len);
|
||||||
@@ -150,7 +146,7 @@ namespace Google.FlatBuffers
|
|||||||
|
|
||||||
var pos = this.__vector(o);
|
var pos = this.__vector(o);
|
||||||
var len = this.__vector_len(o);
|
var len = this.__vector_len(o);
|
||||||
return bb.ToArray<T>(pos, len);
|
return bb.ToArray<T>(pos, len * ByteBuffer.SizeOf<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize any Table-derived type to point to the union at the given offset.
|
// Initialize any Table-derived type to point to the union at the given offset.
|
||||||
|
|||||||
44
pnpm-lock.yaml
generated
44
pnpm-lock.yaml
generated
@@ -33,6 +33,12 @@ importers:
|
|||||||
specifier: ^8.34.1
|
specifier: ^8.34.1
|
||||||
version: 8.34.1(eslint@9.29.0)(typescript@5.8.3)
|
version: 8.34.1(eslint@9.29.0)(typescript@5.8.3)
|
||||||
|
|
||||||
|
tests/ts:
|
||||||
|
dependencies:
|
||||||
|
flatbuffers:
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../..
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.25.5':
|
'@esbuild/aix-ppc64@0.25.5':
|
||||||
@@ -343,8 +349,8 @@ packages:
|
|||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
ajv@6.12.6:
|
ajv@6.14.0:
|
||||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==}
|
||||||
|
|
||||||
ansi-styles@4.3.0:
|
ansi-styles@4.3.0:
|
||||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||||
@@ -483,8 +489,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
|
resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
|
|
||||||
flatted@3.3.1:
|
flatted@3.4.2:
|
||||||
resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
|
resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==}
|
||||||
|
|
||||||
glob-parent@5.1.2:
|
glob-parent@5.1.2:
|
||||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||||
@@ -571,11 +577,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
|
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
|
||||||
engines: {node: '>=8.6'}
|
engines: {node: '>=8.6'}
|
||||||
|
|
||||||
minimatch@3.1.2:
|
minimatch@3.1.5:
|
||||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
|
||||||
|
|
||||||
minimatch@9.0.5:
|
minimatch@9.0.9:
|
||||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
|
||||||
engines: {node: '>=16 || 14 >=14.17'}
|
engines: {node: '>=16 || 14 >=14.17'}
|
||||||
|
|
||||||
ms@2.1.3:
|
ms@2.1.3:
|
||||||
@@ -793,7 +799,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@eslint/object-schema': 2.1.6
|
'@eslint/object-schema': 2.1.6
|
||||||
debug: 4.3.7
|
debug: 4.3.7
|
||||||
minimatch: 3.1.2
|
minimatch: 3.1.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@@ -809,14 +815,14 @@ snapshots:
|
|||||||
|
|
||||||
'@eslint/eslintrc@3.3.1':
|
'@eslint/eslintrc@3.3.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv: 6.12.6
|
ajv: 6.14.0
|
||||||
debug: 4.3.7
|
debug: 4.3.7
|
||||||
espree: 10.4.0
|
espree: 10.4.0
|
||||||
globals: 14.0.0
|
globals: 14.0.0
|
||||||
ignore: 5.3.2
|
ignore: 5.3.2
|
||||||
import-fresh: 3.3.0
|
import-fresh: 3.3.0
|
||||||
js-yaml: 4.1.1
|
js-yaml: 4.1.1
|
||||||
minimatch: 3.1.2
|
minimatch: 3.1.5
|
||||||
strip-json-comments: 3.1.1
|
strip-json-comments: 3.1.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
@@ -932,7 +938,7 @@ snapshots:
|
|||||||
debug: 4.3.7
|
debug: 4.3.7
|
||||||
fast-glob: 3.3.2
|
fast-glob: 3.3.2
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
minimatch: 9.0.5
|
minimatch: 9.0.9
|
||||||
semver: 7.6.3
|
semver: 7.6.3
|
||||||
ts-api-utils: 2.1.0(typescript@5.8.3)
|
ts-api-utils: 2.1.0(typescript@5.8.3)
|
||||||
typescript: 5.8.3
|
typescript: 5.8.3
|
||||||
@@ -961,7 +967,7 @@ snapshots:
|
|||||||
|
|
||||||
acorn@8.15.0: {}
|
acorn@8.15.0: {}
|
||||||
|
|
||||||
ajv@6.12.6:
|
ajv@6.14.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
fast-deep-equal: 3.1.3
|
fast-deep-equal: 3.1.3
|
||||||
fast-json-stable-stringify: 2.1.0
|
fast-json-stable-stringify: 2.1.0
|
||||||
@@ -1070,7 +1076,7 @@ snapshots:
|
|||||||
'@humanwhocodes/retry': 0.4.3
|
'@humanwhocodes/retry': 0.4.3
|
||||||
'@types/estree': 1.0.8
|
'@types/estree': 1.0.8
|
||||||
'@types/json-schema': 7.0.15
|
'@types/json-schema': 7.0.15
|
||||||
ajv: 6.12.6
|
ajv: 6.14.0
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
cross-spawn: 7.0.6
|
cross-spawn: 7.0.6
|
||||||
debug: 4.3.7
|
debug: 4.3.7
|
||||||
@@ -1089,7 +1095,7 @@ snapshots:
|
|||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
json-stable-stringify-without-jsonify: 1.0.1
|
json-stable-stringify-without-jsonify: 1.0.1
|
||||||
lodash.merge: 4.6.2
|
lodash.merge: 4.6.2
|
||||||
minimatch: 3.1.2
|
minimatch: 3.1.5
|
||||||
natural-compare: 1.4.0
|
natural-compare: 1.4.0
|
||||||
optionator: 0.9.4
|
optionator: 0.9.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@@ -1146,10 +1152,10 @@ snapshots:
|
|||||||
|
|
||||||
flat-cache@4.0.1:
|
flat-cache@4.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
flatted: 3.3.1
|
flatted: 3.4.2
|
||||||
keyv: 4.5.4
|
keyv: 4.5.4
|
||||||
|
|
||||||
flatted@3.3.1: {}
|
flatted@3.4.2: {}
|
||||||
|
|
||||||
glob-parent@5.1.2:
|
glob-parent@5.1.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1218,11 +1224,11 @@ snapshots:
|
|||||||
braces: 3.0.3
|
braces: 3.0.3
|
||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
|
|
||||||
minimatch@3.1.2:
|
minimatch@3.1.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion: 1.1.12
|
brace-expansion: 1.1.12
|
||||||
|
|
||||||
minimatch@9.0.5:
|
minimatch@9.0.9:
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion: 2.0.2
|
brace-expansion: 2.0.2
|
||||||
|
|
||||||
|
|||||||
2
pnpm-workspace.yaml
Normal file
2
pnpm-workspace.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
packages:
|
||||||
|
- tests/ts
|
||||||
@@ -422,7 +422,6 @@ class Builder(object):
|
|||||||
off2 = self.Offset() - off + N.UOffsetTFlags.bytewidth
|
off2 = self.Offset() - off + N.UOffsetTFlags.bytewidth
|
||||||
self.PlaceUOffsetT(off2)
|
self.PlaceUOffsetT(off2)
|
||||||
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
|
||||||
def StartVector(self, elemSize, numElems, alignment):
|
def StartVector(self, elemSize, numElems, alignment):
|
||||||
"""StartVector initializes bookkeeping for writing a new vector.
|
"""StartVector initializes bookkeeping for writing a new vector.
|
||||||
|
|
||||||
@@ -438,8 +437,6 @@ class Builder(object):
|
|||||||
self.Prep(alignment, elemSize * numElems) # In case alignment > int.
|
self.Prep(alignment, elemSize * numElems) # In case alignment > int.
|
||||||
return self.Offset()
|
return self.Offset()
|
||||||
|
|
||||||
## @endcond
|
|
||||||
|
|
||||||
def EndVector(self, numElems=None):
|
def EndVector(self, numElems=None):
|
||||||
"""EndVector writes data necessary to finish vector construction."""
|
"""EndVector writes data necessary to finish vector construction."""
|
||||||
|
|
||||||
@@ -556,6 +553,21 @@ class Builder(object):
|
|||||||
self.vectorNumElems = x.size
|
self.vectorNumElems = x.size
|
||||||
return self.EndVector()
|
return self.EndVector()
|
||||||
|
|
||||||
|
def CreateVectorOfTables(self, offsets):
|
||||||
|
"""CreateVectorOfTables writes a vector of offsets such as tables or strings.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
offsets: Iterable of offsets returned from previous builder operations.
|
||||||
|
Each element should be an integer compatible with UOffsetT.
|
||||||
|
"""
|
||||||
|
|
||||||
|
offsets = list(offsets)
|
||||||
|
self.StartVector(N.UOffsetTFlags.bytewidth, len(offsets),
|
||||||
|
N.UOffsetTFlags.bytewidth)
|
||||||
|
for off in reversed(offsets):
|
||||||
|
self.PrependUOffsetTRelative(off)
|
||||||
|
return self.EndVector()
|
||||||
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
## @cond FLATBUFFERS_INTERNAL
|
||||||
def assertNested(self):
|
def assertNested(self):
|
||||||
"""Check that we are in the process of building an object."""
|
"""Check that we are in the process of building an object."""
|
||||||
|
|||||||
@@ -155,6 +155,12 @@ def EnumStartValuesVector(builder, numElems):
|
|||||||
def StartValuesVector(builder, numElems):
|
def StartValuesVector(builder, numElems):
|
||||||
return EnumStartValuesVector(builder, numElems)
|
return EnumStartValuesVector(builder, numElems)
|
||||||
|
|
||||||
|
def EnumCreateValuesVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateValuesVector(builder, data):
|
||||||
|
return EnumCreateValuesVector(builder, data)
|
||||||
|
|
||||||
def EnumAddIsUnion(builder, isUnion):
|
def EnumAddIsUnion(builder, isUnion):
|
||||||
builder.PrependBoolSlot(2, isUnion, 0)
|
builder.PrependBoolSlot(2, isUnion, 0)
|
||||||
|
|
||||||
@@ -179,6 +185,12 @@ def EnumStartAttributesVector(builder, numElems):
|
|||||||
def StartAttributesVector(builder, numElems):
|
def StartAttributesVector(builder, numElems):
|
||||||
return EnumStartAttributesVector(builder, numElems)
|
return EnumStartAttributesVector(builder, numElems)
|
||||||
|
|
||||||
|
def EnumCreateAttributesVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateAttributesVector(builder, data):
|
||||||
|
return EnumCreateAttributesVector(builder, data)
|
||||||
|
|
||||||
def EnumAddDocumentation(builder, documentation):
|
def EnumAddDocumentation(builder, documentation):
|
||||||
builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
||||||
|
|
||||||
@@ -191,6 +203,12 @@ def EnumStartDocumentationVector(builder, numElems):
|
|||||||
def StartDocumentationVector(builder, numElems):
|
def StartDocumentationVector(builder, numElems):
|
||||||
return EnumStartDocumentationVector(builder, numElems)
|
return EnumStartDocumentationVector(builder, numElems)
|
||||||
|
|
||||||
|
def EnumCreateDocumentationVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateDocumentationVector(builder, data):
|
||||||
|
return EnumCreateDocumentationVector(builder, data)
|
||||||
|
|
||||||
def EnumAddDeclarationFile(builder, declarationFile):
|
def EnumAddDeclarationFile(builder, declarationFile):
|
||||||
builder.PrependUOffsetTRelativeSlot(6, flatbuffers.number_types.UOffsetTFlags.py_type(declarationFile), 0)
|
builder.PrependUOffsetTRelativeSlot(6, flatbuffers.number_types.UOffsetTFlags.py_type(declarationFile), 0)
|
||||||
|
|
||||||
|
|||||||
@@ -134,6 +134,12 @@ def EnumValStartDocumentationVector(builder, numElems):
|
|||||||
def StartDocumentationVector(builder, numElems):
|
def StartDocumentationVector(builder, numElems):
|
||||||
return EnumValStartDocumentationVector(builder, numElems)
|
return EnumValStartDocumentationVector(builder, numElems)
|
||||||
|
|
||||||
|
def EnumValCreateDocumentationVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateDocumentationVector(builder, data):
|
||||||
|
return EnumValCreateDocumentationVector(builder, data)
|
||||||
|
|
||||||
def EnumValAddAttributes(builder, attributes):
|
def EnumValAddAttributes(builder, attributes):
|
||||||
builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
|
builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
|
||||||
|
|
||||||
@@ -146,6 +152,12 @@ def EnumValStartAttributesVector(builder, numElems):
|
|||||||
def StartAttributesVector(builder, numElems):
|
def StartAttributesVector(builder, numElems):
|
||||||
return EnumValStartAttributesVector(builder, numElems)
|
return EnumValStartAttributesVector(builder, numElems)
|
||||||
|
|
||||||
|
def EnumValCreateAttributesVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateAttributesVector(builder, data):
|
||||||
|
return EnumValCreateAttributesVector(builder, data)
|
||||||
|
|
||||||
def EnumValEnd(builder):
|
def EnumValEnd(builder):
|
||||||
return builder.EndObject()
|
return builder.EndObject()
|
||||||
|
|
||||||
|
|||||||
@@ -235,6 +235,12 @@ def FieldStartAttributesVector(builder, numElems):
|
|||||||
def StartAttributesVector(builder, numElems):
|
def StartAttributesVector(builder, numElems):
|
||||||
return FieldStartAttributesVector(builder, numElems)
|
return FieldStartAttributesVector(builder, numElems)
|
||||||
|
|
||||||
|
def FieldCreateAttributesVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateAttributesVector(builder, data):
|
||||||
|
return FieldCreateAttributesVector(builder, data)
|
||||||
|
|
||||||
def FieldAddDocumentation(builder, documentation):
|
def FieldAddDocumentation(builder, documentation):
|
||||||
builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
builder.PrependUOffsetTRelativeSlot(10, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
||||||
|
|
||||||
@@ -247,6 +253,12 @@ def FieldStartDocumentationVector(builder, numElems):
|
|||||||
def StartDocumentationVector(builder, numElems):
|
def StartDocumentationVector(builder, numElems):
|
||||||
return FieldStartDocumentationVector(builder, numElems)
|
return FieldStartDocumentationVector(builder, numElems)
|
||||||
|
|
||||||
|
def FieldCreateDocumentationVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateDocumentationVector(builder, data):
|
||||||
|
return FieldCreateDocumentationVector(builder, data)
|
||||||
|
|
||||||
def FieldAddOptional(builder, optional):
|
def FieldAddOptional(builder, optional):
|
||||||
builder.PrependBoolSlot(11, optional, 0)
|
builder.PrependBoolSlot(11, optional, 0)
|
||||||
|
|
||||||
|
|||||||
@@ -158,6 +158,12 @@ def ObjectStartFieldsVector(builder, numElems):
|
|||||||
def StartFieldsVector(builder, numElems):
|
def StartFieldsVector(builder, numElems):
|
||||||
return ObjectStartFieldsVector(builder, numElems)
|
return ObjectStartFieldsVector(builder, numElems)
|
||||||
|
|
||||||
|
def ObjectCreateFieldsVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateFieldsVector(builder, data):
|
||||||
|
return ObjectCreateFieldsVector(builder, data)
|
||||||
|
|
||||||
def ObjectAddIsStruct(builder, isStruct):
|
def ObjectAddIsStruct(builder, isStruct):
|
||||||
builder.PrependBoolSlot(2, isStruct, 0)
|
builder.PrependBoolSlot(2, isStruct, 0)
|
||||||
|
|
||||||
@@ -188,6 +194,12 @@ def ObjectStartAttributesVector(builder, numElems):
|
|||||||
def StartAttributesVector(builder, numElems):
|
def StartAttributesVector(builder, numElems):
|
||||||
return ObjectStartAttributesVector(builder, numElems)
|
return ObjectStartAttributesVector(builder, numElems)
|
||||||
|
|
||||||
|
def ObjectCreateAttributesVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateAttributesVector(builder, data):
|
||||||
|
return ObjectCreateAttributesVector(builder, data)
|
||||||
|
|
||||||
def ObjectAddDocumentation(builder, documentation):
|
def ObjectAddDocumentation(builder, documentation):
|
||||||
builder.PrependUOffsetTRelativeSlot(6, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
builder.PrependUOffsetTRelativeSlot(6, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
||||||
|
|
||||||
@@ -200,6 +212,12 @@ def ObjectStartDocumentationVector(builder, numElems):
|
|||||||
def StartDocumentationVector(builder, numElems):
|
def StartDocumentationVector(builder, numElems):
|
||||||
return ObjectStartDocumentationVector(builder, numElems)
|
return ObjectStartDocumentationVector(builder, numElems)
|
||||||
|
|
||||||
|
def ObjectCreateDocumentationVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateDocumentationVector(builder, data):
|
||||||
|
return ObjectCreateDocumentationVector(builder, data)
|
||||||
|
|
||||||
def ObjectAddDeclarationFile(builder, declarationFile):
|
def ObjectAddDeclarationFile(builder, declarationFile):
|
||||||
builder.PrependUOffsetTRelativeSlot(7, flatbuffers.number_types.UOffsetTFlags.py_type(declarationFile), 0)
|
builder.PrependUOffsetTRelativeSlot(7, flatbuffers.number_types.UOffsetTFlags.py_type(declarationFile), 0)
|
||||||
|
|
||||||
|
|||||||
@@ -138,6 +138,12 @@ def RPCCallStartAttributesVector(builder, numElems):
|
|||||||
def StartAttributesVector(builder, numElems):
|
def StartAttributesVector(builder, numElems):
|
||||||
return RPCCallStartAttributesVector(builder, numElems)
|
return RPCCallStartAttributesVector(builder, numElems)
|
||||||
|
|
||||||
|
def RPCCallCreateAttributesVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateAttributesVector(builder, data):
|
||||||
|
return RPCCallCreateAttributesVector(builder, data)
|
||||||
|
|
||||||
def RPCCallAddDocumentation(builder, documentation):
|
def RPCCallAddDocumentation(builder, documentation):
|
||||||
builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
||||||
|
|
||||||
@@ -150,6 +156,12 @@ def RPCCallStartDocumentationVector(builder, numElems):
|
|||||||
def StartDocumentationVector(builder, numElems):
|
def StartDocumentationVector(builder, numElems):
|
||||||
return RPCCallStartDocumentationVector(builder, numElems)
|
return RPCCallStartDocumentationVector(builder, numElems)
|
||||||
|
|
||||||
|
def RPCCallCreateDocumentationVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateDocumentationVector(builder, data):
|
||||||
|
return RPCCallCreateDocumentationVector(builder, data)
|
||||||
|
|
||||||
def RPCCallEnd(builder):
|
def RPCCallEnd(builder):
|
||||||
return builder.EndObject()
|
return builder.EndObject()
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,12 @@ def SchemaStartObjectsVector(builder, numElems):
|
|||||||
def StartObjectsVector(builder, numElems):
|
def StartObjectsVector(builder, numElems):
|
||||||
return SchemaStartObjectsVector(builder, numElems)
|
return SchemaStartObjectsVector(builder, numElems)
|
||||||
|
|
||||||
|
def SchemaCreateObjectsVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateObjectsVector(builder, data):
|
||||||
|
return SchemaCreateObjectsVector(builder, data)
|
||||||
|
|
||||||
def SchemaAddEnums(builder, enums):
|
def SchemaAddEnums(builder, enums):
|
||||||
builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(enums), 0)
|
builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(enums), 0)
|
||||||
|
|
||||||
@@ -192,6 +198,12 @@ def SchemaStartEnumsVector(builder, numElems):
|
|||||||
def StartEnumsVector(builder, numElems):
|
def StartEnumsVector(builder, numElems):
|
||||||
return SchemaStartEnumsVector(builder, numElems)
|
return SchemaStartEnumsVector(builder, numElems)
|
||||||
|
|
||||||
|
def SchemaCreateEnumsVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateEnumsVector(builder, data):
|
||||||
|
return SchemaCreateEnumsVector(builder, data)
|
||||||
|
|
||||||
def SchemaAddFileIdent(builder, fileIdent):
|
def SchemaAddFileIdent(builder, fileIdent):
|
||||||
builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(fileIdent), 0)
|
builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(fileIdent), 0)
|
||||||
|
|
||||||
@@ -222,6 +234,12 @@ def SchemaStartServicesVector(builder, numElems):
|
|||||||
def StartServicesVector(builder, numElems):
|
def StartServicesVector(builder, numElems):
|
||||||
return SchemaStartServicesVector(builder, numElems)
|
return SchemaStartServicesVector(builder, numElems)
|
||||||
|
|
||||||
|
def SchemaCreateServicesVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateServicesVector(builder, data):
|
||||||
|
return SchemaCreateServicesVector(builder, data)
|
||||||
|
|
||||||
def SchemaAddAdvancedFeatures(builder, advancedFeatures):
|
def SchemaAddAdvancedFeatures(builder, advancedFeatures):
|
||||||
builder.PrependUint64Slot(6, advancedFeatures, 0)
|
builder.PrependUint64Slot(6, advancedFeatures, 0)
|
||||||
|
|
||||||
@@ -240,6 +258,12 @@ def SchemaStartFbsFilesVector(builder, numElems):
|
|||||||
def StartFbsFilesVector(builder, numElems):
|
def StartFbsFilesVector(builder, numElems):
|
||||||
return SchemaStartFbsFilesVector(builder, numElems)
|
return SchemaStartFbsFilesVector(builder, numElems)
|
||||||
|
|
||||||
|
def SchemaCreateFbsFilesVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateFbsFilesVector(builder, data):
|
||||||
|
return SchemaCreateFbsFilesVector(builder, data)
|
||||||
|
|
||||||
def SchemaEnd(builder):
|
def SchemaEnd(builder):
|
||||||
return builder.EndObject()
|
return builder.EndObject()
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,12 @@ def SchemaFileStartIncludedFilenamesVector(builder, numElems):
|
|||||||
def StartIncludedFilenamesVector(builder, numElems):
|
def StartIncludedFilenamesVector(builder, numElems):
|
||||||
return SchemaFileStartIncludedFilenamesVector(builder, numElems)
|
return SchemaFileStartIncludedFilenamesVector(builder, numElems)
|
||||||
|
|
||||||
|
def SchemaFileCreateIncludedFilenamesVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateIncludedFilenamesVector(builder, data):
|
||||||
|
return SchemaFileCreateIncludedFilenamesVector(builder, data)
|
||||||
|
|
||||||
def SchemaFileEnd(builder):
|
def SchemaFileEnd(builder):
|
||||||
return builder.EndObject()
|
return builder.EndObject()
|
||||||
|
|
||||||
|
|||||||
@@ -137,6 +137,12 @@ def ServiceStartCallsVector(builder, numElems):
|
|||||||
def StartCallsVector(builder, numElems):
|
def StartCallsVector(builder, numElems):
|
||||||
return ServiceStartCallsVector(builder, numElems)
|
return ServiceStartCallsVector(builder, numElems)
|
||||||
|
|
||||||
|
def ServiceCreateCallsVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateCallsVector(builder, data):
|
||||||
|
return ServiceCreateCallsVector(builder, data)
|
||||||
|
|
||||||
def ServiceAddAttributes(builder, attributes):
|
def ServiceAddAttributes(builder, attributes):
|
||||||
builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
|
builder.PrependUOffsetTRelativeSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(attributes), 0)
|
||||||
|
|
||||||
@@ -149,6 +155,12 @@ def ServiceStartAttributesVector(builder, numElems):
|
|||||||
def StartAttributesVector(builder, numElems):
|
def StartAttributesVector(builder, numElems):
|
||||||
return ServiceStartAttributesVector(builder, numElems)
|
return ServiceStartAttributesVector(builder, numElems)
|
||||||
|
|
||||||
|
def ServiceCreateAttributesVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateAttributesVector(builder, data):
|
||||||
|
return ServiceCreateAttributesVector(builder, data)
|
||||||
|
|
||||||
def ServiceAddDocumentation(builder, documentation):
|
def ServiceAddDocumentation(builder, documentation):
|
||||||
builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(documentation), 0)
|
||||||
|
|
||||||
@@ -161,6 +173,12 @@ def ServiceStartDocumentationVector(builder, numElems):
|
|||||||
def StartDocumentationVector(builder, numElems):
|
def StartDocumentationVector(builder, numElems):
|
||||||
return ServiceStartDocumentationVector(builder, numElems)
|
return ServiceStartDocumentationVector(builder, numElems)
|
||||||
|
|
||||||
|
def ServiceCreateDocumentationVector(builder, data):
|
||||||
|
return builder.CreateVectorOfTables(data)
|
||||||
|
|
||||||
|
def CreateDocumentationVector(builder, data):
|
||||||
|
return ServiceCreateDocumentationVector(builder, data)
|
||||||
|
|
||||||
def ServiceAddDeclarationFile(builder, declarationFile):
|
def ServiceAddDeclarationFile(builder, declarationFile):
|
||||||
builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(declarationFile), 0)
|
builder.PrependUOffsetTRelativeSlot(4, flatbuffers.number_types.UOffsetTFlags.py_type(declarationFile), 0)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,2 @@
|
|||||||
[bdist_wheel]
|
|
||||||
universal=1
|
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
license_files =
|
license_files = LICENSE
|
||||||
../LICENSE
|
|
||||||
|
|||||||
@@ -12,35 +12,54 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
import shutil
|
||||||
|
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
setup(
|
|
||||||
name='flatbuffers',
|
_THIS_DIR = Path(__file__).resolve().parent
|
||||||
version='25.12.19',
|
_ROOT_LICENSE = _THIS_DIR.parent / 'LICENSE'
|
||||||
license='Apache 2.0',
|
_LOCAL_LICENSE = _THIS_DIR / 'LICENSE'
|
||||||
author='Derek Bailey',
|
|
||||||
author_email='derekbailey@google.com',
|
|
||||||
url='https://google.github.io/flatbuffers/',
|
def _stage_license_file():
|
||||||
long_description=(
|
if _LOCAL_LICENSE.exists() or not _ROOT_LICENSE.exists():
|
||||||
'Python runtime library for use with the '
|
return False
|
||||||
'`Flatbuffers <https://google.github.io/flatbuffers/>`_ '
|
shutil.copyfile(_ROOT_LICENSE, _LOCAL_LICENSE)
|
||||||
'serialization format.'
|
return True
|
||||||
),
|
|
||||||
packages=['flatbuffers'],
|
_remove_staged_license = _stage_license_file()
|
||||||
include_package_data=True,
|
|
||||||
requires=[],
|
try:
|
||||||
description='The FlatBuffers serialization format for Python',
|
setup(
|
||||||
classifiers=[
|
name='flatbuffers',
|
||||||
'Intended Audience :: Developers',
|
version='25.12.19',
|
||||||
'License :: OSI Approved :: Apache Software License',
|
license='Apache 2.0',
|
||||||
'Operating System :: OS Independent',
|
author='Derek Bailey',
|
||||||
'Programming Language :: Python',
|
author_email='derekbailey@google.com',
|
||||||
'Programming Language :: Python :: 2',
|
url='https://google.github.io/flatbuffers/',
|
||||||
'Programming Language :: Python :: 3',
|
long_description=(
|
||||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
'Python runtime library for use with the '
|
||||||
],
|
'`Flatbuffers <https://google.github.io/flatbuffers/>`_ '
|
||||||
project_urls={
|
'serialization format.'
|
||||||
'Documentation': 'https://google.github.io/flatbuffers/',
|
),
|
||||||
'Source': 'https://github.com/google/flatbuffers',
|
packages=['flatbuffers'],
|
||||||
},
|
include_package_data=True,
|
||||||
)
|
requires=[],
|
||||||
|
description='The FlatBuffers serialization format for Python',
|
||||||
|
classifiers=[
|
||||||
|
'Intended Audience :: Developers',
|
||||||
|
'Operating System :: OS Independent',
|
||||||
|
'Programming Language :: Python',
|
||||||
|
'Programming Language :: Python :: 3',
|
||||||
|
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||||
|
],
|
||||||
|
project_urls={
|
||||||
|
'Documentation': 'https://google.github.io/flatbuffers/',
|
||||||
|
'Source': 'https://github.com/google/flatbuffers',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
if _remove_staged_license and _LOCAL_LICENSE.exists():
|
||||||
|
_LOCAL_LICENSE.unlink()
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ use core::marker::PhantomData;
|
|||||||
use core::ops::{Add, AddAssign, Deref, DerefMut, Index, IndexMut, Sub, SubAssign};
|
use core::ops::{Add, AddAssign, Deref, DerefMut, Index, IndexMut, Sub, SubAssign};
|
||||||
use core::ptr::write_bytes;
|
use core::ptr::write_bytes;
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::endian_scalar::emplace_scalar;
|
use crate::endian_scalar::emplace_scalar;
|
||||||
use crate::primitives::*;
|
use crate::primitives::*;
|
||||||
use crate::push::{Push, PushAlignment};
|
use crate::push::{Push, PushAlignment};
|
||||||
@@ -139,6 +142,9 @@ pub struct FlatBufferBuilder<'fbb, A: Allocator = DefaultAllocator> {
|
|||||||
|
|
||||||
min_align: usize,
|
min_align: usize,
|
||||||
force_defaults: bool,
|
force_defaults: bool,
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
strings_pool: HashMap<String, WIPOffset<&'fbb str>>,
|
||||||
|
#[cfg(not(feature = "std"))]
|
||||||
strings_pool: Vec<WIPOffset<&'fbb str>>,
|
strings_pool: Vec<WIPOffset<&'fbb str>>,
|
||||||
|
|
||||||
_phantom: PhantomData<&'fbb ()>,
|
_phantom: PhantomData<&'fbb ()>,
|
||||||
@@ -160,6 +166,60 @@ impl<'fbb> FlatBufferBuilder<'fbb, DefaultAllocator> {
|
|||||||
pub fn with_capacity(size: usize) -> Self {
|
pub fn with_capacity(size: usize) -> Self {
|
||||||
Self::from_vec(vec![0; size])
|
Self::from_vec(vec![0; size])
|
||||||
}
|
}
|
||||||
|
/// Create a FlatBufferBuilder that is ready for writing, with a
|
||||||
|
/// ready-to-use capacity of the provided size and preallocated internal vecs.
|
||||||
|
///
|
||||||
|
/// The maximum valid value for `size` is `FLATBUFFERS_MAX_BUFFER_SIZE`.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `size` - The initial capacity of the backing buffer in bytes.
|
||||||
|
/// * `field_locs_capacity` - Preallocated capacity for the field locations vec.
|
||||||
|
/// * `written_vtable_revpos_capacity` - Preallocated capacity for the written vtable reverse positions vec.
|
||||||
|
/// * `strings_pool_capacity` - Preallocated capacity for the shared strings pool vec.
|
||||||
|
pub fn with_internal_capacity(
|
||||||
|
size: usize,
|
||||||
|
field_locs_capacity: usize,
|
||||||
|
written_vtable_revpos_capacity: usize,
|
||||||
|
strings_pool_capacity: usize,
|
||||||
|
) -> Self {
|
||||||
|
Self::from_vec_with_internal_capacity(
|
||||||
|
vec![0; size],
|
||||||
|
field_locs_capacity,
|
||||||
|
written_vtable_revpos_capacity,
|
||||||
|
strings_pool_capacity,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/// Create a FlatBufferBuilder that is ready for writing, reusing
|
||||||
|
/// an existing vector and preallocated internal vecs.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `buffer` - An existing `Vec<u8>` to reuse as the backing buffer.
|
||||||
|
/// * `field_locs_capacity` - Preallocated capacity for the field locations vec.
|
||||||
|
/// * `written_vtable_revpos_capacity` - Preallocated capacity for the written vtable reverse positions vec.
|
||||||
|
/// * `strings_pool_capacity` - Preallocated capacity for the shared strings pool vec.
|
||||||
|
pub fn from_vec_with_internal_capacity(
|
||||||
|
buffer: Vec<u8>,
|
||||||
|
field_locs_capacity: usize,
|
||||||
|
written_vtable_revpos_capacity: usize,
|
||||||
|
strings_pool_capacity: usize,
|
||||||
|
) -> Self {
|
||||||
|
// we need to check the size here because we create the backing buffer
|
||||||
|
// directly, bypassing the typical way of using grow_allocator:
|
||||||
|
assert!(
|
||||||
|
buffer.len() <= FLATBUFFERS_MAX_BUFFER_SIZE,
|
||||||
|
"cannot initialize buffer bigger than 2 gigabytes"
|
||||||
|
);
|
||||||
|
let allocator = DefaultAllocator::from_vec(buffer);
|
||||||
|
Self::new_in_with_internal_capacity(
|
||||||
|
allocator,
|
||||||
|
field_locs_capacity,
|
||||||
|
written_vtable_revpos_capacity,
|
||||||
|
strings_pool_capacity,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a FlatBufferBuilder that is ready for writing, reusing
|
/// Create a FlatBufferBuilder that is ready for writing, reusing
|
||||||
/// an existing vector.
|
/// an existing vector.
|
||||||
pub fn from_vec(buffer: Vec<u8>) -> Self {
|
pub fn from_vec(buffer: Vec<u8>) -> Self {
|
||||||
@@ -197,12 +257,52 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
|
|
||||||
min_align: 0,
|
min_align: 0,
|
||||||
force_defaults: false,
|
force_defaults: false,
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
strings_pool: HashMap::new(),
|
||||||
|
#[cfg(not(feature = "std"))]
|
||||||
strings_pool: Vec::new(),
|
strings_pool: Vec::new(),
|
||||||
|
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a [`FlatBufferBuilder`] that is ready for writing with a custom [`Allocator`]
|
||||||
|
/// and preallocated internal vecs.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `allocator` - A custom [`Allocator`] to use as the backing buffer.
|
||||||
|
/// * `field_locs_capacity` - Preallocated capacity for the field locations vec.
|
||||||
|
/// * `written_vtable_revpos_capacity` - Preallocated capacity for the written vtable reverse positions vec.
|
||||||
|
/// * `strings_pool_capacity` - Preallocated capacity for the shared strings pool vec.
|
||||||
|
pub fn new_in_with_internal_capacity(
|
||||||
|
allocator: A,
|
||||||
|
field_locs_capacity: usize,
|
||||||
|
written_vtable_revpos_capacity: usize,
|
||||||
|
strings_pool_capacity: usize,
|
||||||
|
) -> Self {
|
||||||
|
let head = ReverseIndex::end();
|
||||||
|
FlatBufferBuilder {
|
||||||
|
allocator,
|
||||||
|
head,
|
||||||
|
|
||||||
|
field_locs: Vec::with_capacity(field_locs_capacity),
|
||||||
|
written_vtable_revpos: Vec::with_capacity(written_vtable_revpos_capacity),
|
||||||
|
|
||||||
|
nested: false,
|
||||||
|
finished: false,
|
||||||
|
|
||||||
|
min_align: 0,
|
||||||
|
force_defaults: false,
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
strings_pool: HashMap::with_capacity(strings_pool_capacity),
|
||||||
|
#[cfg(not(feature = "std"))]
|
||||||
|
strings_pool: Vec::with_capacity(strings_pool_capacity),
|
||||||
|
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Destroy the [`FlatBufferBuilder`], returning its [`Allocator`] and the index
|
/// Destroy the [`FlatBufferBuilder`], returning its [`Allocator`] and the index
|
||||||
/// into it that represents the start of valid data.
|
/// into it that represents the start of valid data.
|
||||||
pub fn collapse_in(self) -> (A, usize) {
|
pub fn collapse_in(self) -> (A, usize) {
|
||||||
@@ -223,7 +323,9 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
/// new object.
|
/// new object.
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
// memset only the part of the buffer that could be dirty:
|
// memset only the part of the buffer that could be dirty:
|
||||||
self.allocator[self.head.range_to_end()].iter_mut().for_each(|x| *x = 0);
|
self.allocator[self.head.range_to_end()]
|
||||||
|
.iter_mut()
|
||||||
|
.for_each(|x| *x = 0);
|
||||||
|
|
||||||
self.head = ReverseIndex::end();
|
self.head = ReverseIndex::end();
|
||||||
self.written_vtable_revpos.clear();
|
self.written_vtable_revpos.clear();
|
||||||
@@ -235,22 +337,43 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
self.strings_pool.clear();
|
self.strings_pool.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Push a Push'able value onto the front of the in-progress data.
|
/// Fallible version of [`push`](Self::push).
|
||||||
///
|
|
||||||
/// This function uses traits to provide a unified API for writing
|
|
||||||
/// scalars, tables, vectors, and WIPOffsets.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn push<P: Push>(&mut self, x: P) -> WIPOffset<P::Output> {
|
pub fn try_push<P: Push>(&mut self, x: P) -> Result<WIPOffset<P::Output>, A::Error> {
|
||||||
let sz = P::size();
|
let sz = P::size();
|
||||||
self.align(sz, P::alignment());
|
self.align(sz, P::alignment())?;
|
||||||
self.make_space(sz);
|
self.make_space(sz)?;
|
||||||
{
|
{
|
||||||
let (dst, rest) = self.allocator[self.head.range_to_end()].split_at_mut(sz);
|
let (dst, rest) = self.allocator[self.head.range_to_end()].split_at_mut(sz);
|
||||||
// Safety:
|
// Safety:
|
||||||
// Called make_space above
|
// Called make_space above
|
||||||
unsafe { x.push(dst, rest.len()) };
|
unsafe { x.push(dst, rest.len()) };
|
||||||
}
|
}
|
||||||
WIPOffset::new(self.used_space() as UOffsetT)
|
Ok(WIPOffset::new(self.used_space() as UOffsetT))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Push a Push'able value onto the front of the in-progress data.
|
||||||
|
///
|
||||||
|
/// This function uses traits to provide a unified API for writing
|
||||||
|
/// scalars, tables, vectors, and WIPOffsets.
|
||||||
|
#[inline]
|
||||||
|
pub fn push<P: Push>(&mut self, x: P) -> WIPOffset<P::Output> {
|
||||||
|
self.try_push(x).expect("Flatbuffer allocation failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fallible version of [`push_slot`](Self::push_slot).
|
||||||
|
#[inline]
|
||||||
|
pub fn try_push_slot<X: Push + PartialEq>(
|
||||||
|
&mut self,
|
||||||
|
slotoff: VOffsetT,
|
||||||
|
x: X,
|
||||||
|
default: X,
|
||||||
|
) -> Result<(), A::Error> {
|
||||||
|
self.assert_nested("push_slot");
|
||||||
|
if x != default || self.force_defaults {
|
||||||
|
self.try_push_slot_always(slotoff, x)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Push a Push'able value onto the front of the in-progress data, and
|
/// Push a Push'able value onto the front of the in-progress data, and
|
||||||
@@ -258,19 +381,29 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
/// the default, then this is a no-op.
|
/// the default, then this is a no-op.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn push_slot<X: Push + PartialEq>(&mut self, slotoff: VOffsetT, x: X, default: X) {
|
pub fn push_slot<X: Push + PartialEq>(&mut self, slotoff: VOffsetT, x: X, default: X) {
|
||||||
self.assert_nested("push_slot");
|
self.try_push_slot(slotoff, x, default)
|
||||||
if x != default || self.force_defaults {
|
.expect("Flatbuffer allocation failure")
|
||||||
self.push_slot_always(slotoff, x);
|
}
|
||||||
}
|
|
||||||
|
/// Fallible version of [`push_slot_always`](Self::push_slot_always).
|
||||||
|
#[inline]
|
||||||
|
pub fn try_push_slot_always<X: Push>(
|
||||||
|
&mut self,
|
||||||
|
slotoff: VOffsetT,
|
||||||
|
x: X,
|
||||||
|
) -> Result<(), A::Error> {
|
||||||
|
self.assert_nested("push_slot_always");
|
||||||
|
let off = self.try_push(x)?;
|
||||||
|
self.track_field(slotoff, off.value());
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Push a Push'able value onto the front of the in-progress data, and
|
/// Push a Push'able value onto the front of the in-progress data, and
|
||||||
/// store a reference to it in the in-progress vtable.
|
/// store a reference to it in the in-progress vtable.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn push_slot_always<X: Push>(&mut self, slotoff: VOffsetT, x: X) {
|
pub fn push_slot_always<X: Push>(&mut self, slotoff: VOffsetT, x: X) {
|
||||||
self.assert_nested("push_slot_always");
|
self.try_push_slot_always(slotoff, x)
|
||||||
let off = self.push(x);
|
.expect("Flatbuffer allocation failure")
|
||||||
self.track_field(slotoff, off.value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve the number of vtables that have been serialized into the
|
/// Retrieve the number of vtables that have been serialized into the
|
||||||
@@ -295,6 +428,22 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
WIPOffset::new(self.used_space() as UOffsetT)
|
WIPOffset::new(self.used_space() as UOffsetT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fallible version of [`end_table`](Self::end_table).
|
||||||
|
#[inline]
|
||||||
|
pub fn try_end_table(
|
||||||
|
&mut self,
|
||||||
|
off: WIPOffset<TableUnfinishedWIPOffset>,
|
||||||
|
) -> Result<WIPOffset<TableFinishedWIPOffset>, A::Error> {
|
||||||
|
self.assert_nested("end_table");
|
||||||
|
|
||||||
|
let o = self.write_vtable(off)?;
|
||||||
|
|
||||||
|
self.nested = false;
|
||||||
|
self.field_locs.clear();
|
||||||
|
|
||||||
|
Ok(WIPOffset::new(o.value()))
|
||||||
|
}
|
||||||
|
|
||||||
/// End a Table write.
|
/// End a Table write.
|
||||||
///
|
///
|
||||||
/// Asserts that the builder is in a nested state.
|
/// Asserts that the builder is in a nested state.
|
||||||
@@ -303,14 +452,19 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
off: WIPOffset<TableUnfinishedWIPOffset>,
|
off: WIPOffset<TableUnfinishedWIPOffset>,
|
||||||
) -> WIPOffset<TableFinishedWIPOffset> {
|
) -> WIPOffset<TableFinishedWIPOffset> {
|
||||||
self.assert_nested("end_table");
|
self.try_end_table(off)
|
||||||
|
.expect("Flatbuffer allocation failure")
|
||||||
|
}
|
||||||
|
|
||||||
let o = self.write_vtable(off);
|
/// Fallible version of [`start_vector`](Self::start_vector).
|
||||||
|
#[inline]
|
||||||
self.nested = false;
|
pub fn try_start_vector<T: Push>(&mut self, num_items: usize) -> Result<(), A::Error> {
|
||||||
self.field_locs.clear();
|
self.assert_not_nested(
|
||||||
|
"start_vector can not be called when a table or vector is under construction",
|
||||||
WIPOffset::new(o.value())
|
);
|
||||||
|
self.align(num_items * T::size(), T::alignment().max_of(SIZE_UOFFSET))?;
|
||||||
|
self.nested = true;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start a Vector write.
|
/// Start a Vector write.
|
||||||
@@ -322,11 +476,20 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
/// function will want to use `push` to add values.
|
/// function will want to use `push` to add values.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn start_vector<T: Push>(&mut self, num_items: usize) {
|
pub fn start_vector<T: Push>(&mut self, num_items: usize) {
|
||||||
self.assert_not_nested(
|
self.try_start_vector::<T>(num_items)
|
||||||
"start_vector can not be called when a table or vector is under construction",
|
.expect("Flatbuffer allocation failure")
|
||||||
);
|
}
|
||||||
self.nested = true;
|
|
||||||
self.align(num_items * T::size(), T::alignment().max_of(SIZE_UOFFSET));
|
/// Fallible version of [`end_vector`](Self::end_vector).
|
||||||
|
#[inline]
|
||||||
|
pub fn try_end_vector<T: Push>(
|
||||||
|
&mut self,
|
||||||
|
num_elems: usize,
|
||||||
|
) -> Result<WIPOffset<Vector<'fbb, T>>, A::Error> {
|
||||||
|
self.assert_nested("end_vector");
|
||||||
|
let o = self.try_push::<UOffsetT>(num_elems as UOffsetT)?;
|
||||||
|
self.nested = false;
|
||||||
|
Ok(WIPOffset::new(o.value()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// End a Vector write.
|
/// End a Vector write.
|
||||||
@@ -337,14 +500,54 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
/// Asserts that the builder is in a nested state.
|
/// Asserts that the builder is in a nested state.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn end_vector<T: Push>(&mut self, num_elems: usize) -> WIPOffset<Vector<'fbb, T>> {
|
pub fn end_vector<T: Push>(&mut self, num_elems: usize) -> WIPOffset<Vector<'fbb, T>> {
|
||||||
self.assert_nested("end_vector");
|
self.try_end_vector::<T>(num_elems)
|
||||||
self.nested = false;
|
.expect("Flatbuffer allocation failure")
|
||||||
let o = self.push::<UOffsetT>(num_elems as UOffsetT);
|
|
||||||
WIPOffset::new(o.value())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fallible version of [`create_shared_string`](Self::create_shared_string).
|
||||||
|
///
|
||||||
|
/// Uses a HashMap to track previously written strings, providing O(1)
|
||||||
|
/// amortized lookup and insertion.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
#[inline]
|
||||||
|
pub fn try_create_shared_string<'a: 'b, 'b>(
|
||||||
|
&'a mut self,
|
||||||
|
s: &'b str,
|
||||||
|
) -> Result<WIPOffset<&'fbb str>, A::Error> {
|
||||||
|
self.assert_not_nested(
|
||||||
|
"create_shared_string can not be called when a table or vector is under construction",
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(&offset) = self.strings_pool.get(s) {
|
||||||
|
return Ok(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
let address = WIPOffset::new(self.try_create_byte_string(s.as_bytes())?.value());
|
||||||
|
self.strings_pool.insert(s.to_owned(), address);
|
||||||
|
Ok(address)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a utf8 string, and de-duplicate if already created.
|
||||||
|
///
|
||||||
|
/// Uses a HashMap to track previously written strings, providing O(1)
|
||||||
|
/// amortized lookup and insertion.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn create_shared_string<'a: 'b, 'b>(&'a mut self, s: &'b str) -> WIPOffset<&'fbb str> {
|
pub fn create_shared_string<'a: 'b, 'b>(&'a mut self, s: &'b str) -> WIPOffset<&'fbb str> {
|
||||||
|
self.try_create_shared_string(s)
|
||||||
|
.expect("Flatbuffer allocation failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fallible version of [`create_shared_string`](Self::create_shared_string).
|
||||||
|
///
|
||||||
|
/// Uses a sorted Vec with binary search to track previously written
|
||||||
|
/// strings when in `no_std` mode.
|
||||||
|
#[cfg(not(feature = "std"))]
|
||||||
|
#[inline]
|
||||||
|
pub fn try_create_shared_string<'a: 'b, 'b>(
|
||||||
|
&'a mut self,
|
||||||
|
s: &'b str,
|
||||||
|
) -> Result<WIPOffset<&'fbb str>, A::Error> {
|
||||||
self.assert_not_nested(
|
self.assert_not_nested(
|
||||||
"create_shared_string can not be called when a table or vector is under construction",
|
"create_shared_string can not be called when a table or vector is under construction",
|
||||||
);
|
);
|
||||||
@@ -355,68 +558,95 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
|
|
||||||
let found = self.strings_pool.binary_search_by(|offset| {
|
let found = self.strings_pool.binary_search_by(|offset| {
|
||||||
let ptr = offset.value() as usize;
|
let ptr = offset.value() as usize;
|
||||||
// Gets The pointer to the size of the string
|
|
||||||
let str_memory = &buf[buf.len() - ptr..];
|
let str_memory = &buf[buf.len() - ptr..];
|
||||||
// Gets the size of the written string from buffer
|
let size = u32::from_le_bytes([
|
||||||
let size =
|
str_memory[0],
|
||||||
u32::from_le_bytes([str_memory[0], str_memory[1], str_memory[2], str_memory[3]])
|
str_memory[1],
|
||||||
as usize;
|
str_memory[2],
|
||||||
// Size of the string size
|
str_memory[3],
|
||||||
let string_size: usize = 4;
|
]) as usize;
|
||||||
// Fetches actual string bytes from index of string after string size
|
let stored = &str_memory[4..4 + size];
|
||||||
// to the size of string plus string size
|
stored.cmp(s.as_bytes())
|
||||||
let iter = str_memory[string_size..size + string_size].iter();
|
|
||||||
// Compares bytes of fetched string and current writable string
|
|
||||||
iter.cloned().cmp(s.bytes())
|
|
||||||
});
|
});
|
||||||
|
|
||||||
match found {
|
match found {
|
||||||
Ok(index) => self.strings_pool[index],
|
Ok(index) => Ok(self.strings_pool[index]),
|
||||||
Err(index) => {
|
Err(index) => {
|
||||||
let address = WIPOffset::new(self.create_byte_string(s.as_bytes()).value());
|
let address =
|
||||||
|
WIPOffset::new(self.try_create_byte_string(s.as_bytes())?.value());
|
||||||
self.strings_pool.insert(index, address);
|
self.strings_pool.insert(index, address);
|
||||||
address
|
Ok(address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a utf8 string, and de-duplicate if already created.
|
||||||
|
///
|
||||||
|
/// Uses a sorted Vec with binary search to track previously written
|
||||||
|
/// strings when in `no_std` mode.
|
||||||
|
#[cfg(not(feature = "std"))]
|
||||||
|
#[inline]
|
||||||
|
pub fn create_shared_string<'a: 'b, 'b>(&'a mut self, s: &'b str) -> WIPOffset<&'fbb str> {
|
||||||
|
self.try_create_shared_string(s)
|
||||||
|
.expect("Flatbuffer allocation failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fallible version of [`create_string`](Self::create_string).
|
||||||
|
#[inline]
|
||||||
|
pub fn try_create_string<'a: 'b, 'b>(
|
||||||
|
&'a mut self,
|
||||||
|
s: &'b str,
|
||||||
|
) -> Result<WIPOffset<&'fbb str>, A::Error> {
|
||||||
|
self.assert_not_nested(
|
||||||
|
"create_string can not be called when a table or vector is under construction",
|
||||||
|
);
|
||||||
|
Ok(WIPOffset::new(
|
||||||
|
self.try_create_byte_string(s.as_bytes())?.value(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a utf8 string.
|
/// Create a utf8 string.
|
||||||
///
|
///
|
||||||
/// The wire format represents this as a zero-terminated byte vector.
|
/// The wire format represents this as a zero-terminated byte vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn create_string<'a: 'b, 'b>(&'a mut self, s: &'b str) -> WIPOffset<&'fbb str> {
|
pub fn create_string<'a: 'b, 'b>(&'a mut self, s: &'b str) -> WIPOffset<&'fbb str> {
|
||||||
|
self.try_create_string(s)
|
||||||
|
.expect("Flatbuffer allocation failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fallible version of [`create_byte_string`](Self::create_byte_string).
|
||||||
|
#[inline]
|
||||||
|
pub fn try_create_byte_string(
|
||||||
|
&mut self,
|
||||||
|
data: &[u8],
|
||||||
|
) -> Result<WIPOffset<&'fbb [u8]>, A::Error> {
|
||||||
self.assert_not_nested(
|
self.assert_not_nested(
|
||||||
"create_string can not be called when a table or vector is under construction",
|
"create_byte_string can not be called when a table or vector is under construction",
|
||||||
);
|
);
|
||||||
WIPOffset::new(self.create_byte_string(s.as_bytes()).value())
|
self.align(data.len() + 1, PushAlignment::new(SIZE_UOFFSET))?;
|
||||||
|
self.try_push(0u8)?;
|
||||||
|
self.push_bytes_unprefixed(data)?;
|
||||||
|
self.try_push(data.len() as UOffsetT)?;
|
||||||
|
Ok(WIPOffset::new(self.used_space() as UOffsetT))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a zero-terminated byte vector.
|
/// Create a zero-terminated byte vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn create_byte_string(&mut self, data: &[u8]) -> WIPOffset<&'fbb [u8]> {
|
pub fn create_byte_string(&mut self, data: &[u8]) -> WIPOffset<&'fbb [u8]> {
|
||||||
self.assert_not_nested(
|
self.try_create_byte_string(data)
|
||||||
"create_byte_string can not be called when a table or vector is under construction",
|
.expect("Flatbuffer allocation failure")
|
||||||
);
|
|
||||||
self.align(data.len() + 1, PushAlignment::new(SIZE_UOFFSET));
|
|
||||||
self.push(0u8);
|
|
||||||
self.push_bytes_unprefixed(data);
|
|
||||||
self.push(data.len() as UOffsetT);
|
|
||||||
WIPOffset::new(self.used_space() as UOffsetT)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a vector of Push-able objects.
|
/// Fallible version of [`create_vector`](Self::create_vector).
|
||||||
///
|
|
||||||
/// Speed-sensitive users may wish to reduce memory usage by creating the
|
|
||||||
/// vector manually: use `start_vector`, `push`, and `end_vector`.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn create_vector<'a: 'b, 'b, T: Push + 'b>(
|
pub fn try_create_vector<'a: 'b, 'b, T: Push + 'b>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
items: &'b [T],
|
items: &'b [T],
|
||||||
) -> WIPOffset<Vector<'fbb, T::Output>> {
|
) -> Result<WIPOffset<Vector<'fbb, T::Output>>, A::Error> {
|
||||||
let elem_size = T::size();
|
let elem_size = T::size();
|
||||||
let slice_size = items.len() * elem_size;
|
let slice_size = items.len() * elem_size;
|
||||||
self.align(slice_size, T::alignment().max_of(SIZE_UOFFSET));
|
self.align(slice_size, T::alignment().max_of(SIZE_UOFFSET))?;
|
||||||
self.ensure_capacity(slice_size + UOffsetT::size());
|
self.ensure_capacity(slice_size + UOffsetT::size())?;
|
||||||
|
|
||||||
self.head -= slice_size;
|
self.head -= slice_size;
|
||||||
let mut written_len = self.head.distance_to_end();
|
let mut written_len = self.head.distance_to_end();
|
||||||
@@ -430,7 +660,38 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
unsafe { item.push(out, written_len) };
|
unsafe { item.push(out, written_len) };
|
||||||
}
|
}
|
||||||
|
|
||||||
WIPOffset::new(self.push::<UOffsetT>(items.len() as UOffsetT).value())
|
Ok(WIPOffset::new(
|
||||||
|
self.try_push::<UOffsetT>(items.len() as UOffsetT)?.value(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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 + 'b>(
|
||||||
|
&'a mut self,
|
||||||
|
items: &'b [T],
|
||||||
|
) -> WIPOffset<Vector<'fbb, T::Output>> {
|
||||||
|
self.try_create_vector(items)
|
||||||
|
.expect("Flatbuffer allocation failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fallible version of [`create_vector_from_iter`](Self::create_vector_from_iter).
|
||||||
|
#[inline]
|
||||||
|
pub fn try_create_vector_from_iter<T: Push>(
|
||||||
|
&mut self,
|
||||||
|
items: impl ExactSizeIterator<Item = T> + DoubleEndedIterator,
|
||||||
|
) -> Result<WIPOffset<Vector<'fbb, T::Output>>, A::Error> {
|
||||||
|
let elem_size = T::size();
|
||||||
|
self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET))?;
|
||||||
|
let mut actual = 0;
|
||||||
|
for item in items.rev() {
|
||||||
|
self.try_push(item)?;
|
||||||
|
actual += 1;
|
||||||
|
}
|
||||||
|
Ok(WIPOffset::new(self.try_push::<UOffsetT>(actual)?.value()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a vector of Push-able objects.
|
/// Create a vector of Push-able objects.
|
||||||
@@ -442,14 +703,8 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
items: impl ExactSizeIterator<Item = T> + DoubleEndedIterator,
|
items: impl ExactSizeIterator<Item = T> + DoubleEndedIterator,
|
||||||
) -> WIPOffset<Vector<'fbb, T::Output>> {
|
) -> WIPOffset<Vector<'fbb, T::Output>> {
|
||||||
let elem_size = T::size();
|
self.try_create_vector_from_iter(items)
|
||||||
self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET));
|
.expect("Flatbuffer allocation failure")
|
||||||
let mut actual = 0;
|
|
||||||
for item in items.rev() {
|
|
||||||
self.push(item);
|
|
||||||
actual += 1;
|
|
||||||
}
|
|
||||||
WIPOffset::new(self.push::<UOffsetT>(actual).value())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set whether default values are stored.
|
/// Set whether default values are stored.
|
||||||
@@ -512,13 +767,34 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
assert!(o != 0, "missing required field {}", assert_msg_name);
|
assert!(o != 0, "missing required field {}", assert_msg_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fallible version of [`finish_size_prefixed`](Self::finish_size_prefixed).
|
||||||
|
#[inline]
|
||||||
|
pub fn try_finish_size_prefixed<T>(
|
||||||
|
&mut self,
|
||||||
|
root: WIPOffset<T>,
|
||||||
|
file_identifier: Option<&str>,
|
||||||
|
) -> Result<(), A::Error> {
|
||||||
|
self.finish_with_opts(root, file_identifier, true)
|
||||||
|
}
|
||||||
|
|
||||||
/// Finalize the FlatBuffer by: aligning it, pushing an optional file
|
/// Finalize the FlatBuffer by: aligning it, pushing an optional file
|
||||||
/// identifier on to it, pushing a size prefix on to it, and marking the
|
/// identifier on to it, pushing a size prefix on to it, and marking the
|
||||||
/// internal state of the FlatBufferBuilder as `finished`. Afterwards,
|
/// internal state of the FlatBufferBuilder as `finished`. Afterwards,
|
||||||
/// users can call `finished_data` to get the resulting data.
|
/// users can call `finished_data` to get the resulting data.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn finish_size_prefixed<T>(&mut self, root: WIPOffset<T>, file_identifier: Option<&str>) {
|
pub fn finish_size_prefixed<T>(&mut self, root: WIPOffset<T>, file_identifier: Option<&str>) {
|
||||||
self.finish_with_opts(root, file_identifier, true);
|
self.try_finish_size_prefixed(root, file_identifier)
|
||||||
|
.expect("Flatbuffer allocation failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fallible version of [`finish`](Self::finish).
|
||||||
|
#[inline]
|
||||||
|
pub fn try_finish<T>(
|
||||||
|
&mut self,
|
||||||
|
root: WIPOffset<T>,
|
||||||
|
file_identifier: Option<&str>,
|
||||||
|
) -> Result<(), A::Error> {
|
||||||
|
self.finish_with_opts(root, file_identifier, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finalize the FlatBuffer by: aligning it, pushing an optional file
|
/// Finalize the FlatBuffer by: aligning it, pushing an optional file
|
||||||
@@ -527,7 +803,14 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
/// `finished_data` to get the resulting data.
|
/// `finished_data` to get the resulting data.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn finish<T>(&mut self, root: WIPOffset<T>, file_identifier: Option<&str>) {
|
pub fn finish<T>(&mut self, root: WIPOffset<T>, file_identifier: Option<&str>) {
|
||||||
self.finish_with_opts(root, file_identifier, false);
|
self.try_finish(root, file_identifier)
|
||||||
|
.expect("Flatbuffer allocation failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fallible version of [`finish_minimal`](Self::finish_minimal).
|
||||||
|
#[inline]
|
||||||
|
pub fn try_finish_minimal<T>(&mut self, root: WIPOffset<T>) -> Result<(), A::Error> {
|
||||||
|
self.finish_with_opts(root, None, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finalize the FlatBuffer by: aligning it and marking the internal state
|
/// Finalize the FlatBuffer by: aligning it and marking the internal state
|
||||||
@@ -535,7 +818,8 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
/// `finished_data` to get the resulting data.
|
/// `finished_data` to get the resulting data.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn finish_minimal<T>(&mut self, root: WIPOffset<T>) {
|
pub fn finish_minimal<T>(&mut self, root: WIPOffset<T>) {
|
||||||
self.finish_with_opts(root, None, false);
|
self.try_finish_minimal(root)
|
||||||
|
.expect("Flatbuffer allocation failure")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -553,13 +837,13 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
fn write_vtable(
|
fn write_vtable(
|
||||||
&mut self,
|
&mut self,
|
||||||
table_tail_revloc: WIPOffset<TableUnfinishedWIPOffset>,
|
table_tail_revloc: WIPOffset<TableUnfinishedWIPOffset>,
|
||||||
) -> WIPOffset<VTableWIPOffset> {
|
) -> Result<WIPOffset<VTableWIPOffset>, A::Error> {
|
||||||
self.assert_nested("write_vtable");
|
self.assert_nested("write_vtable");
|
||||||
|
|
||||||
// Write the vtable offset, which is the start of any Table.
|
// Write the vtable offset, which is the start of any Table.
|
||||||
// We fill its value later.
|
// We fill its value later.
|
||||||
let object_revloc_to_vtable: WIPOffset<VTableWIPOffset> =
|
let object_revloc_to_vtable: WIPOffset<VTableWIPOffset> =
|
||||||
WIPOffset::new(self.push::<UOffsetT>(0xF0F0_F0F0).value());
|
WIPOffset::new(self.try_push::<UOffsetT>(0xF0F0_F0F0)?.value());
|
||||||
|
|
||||||
// Layout of the data this function will create when a new vtable is
|
// Layout of the data this function will create when a new vtable is
|
||||||
// needed.
|
// needed.
|
||||||
@@ -602,7 +886,7 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
|
|
||||||
// fill the WIP vtable with zeros:
|
// fill the WIP vtable with zeros:
|
||||||
let vtable_byte_len = get_vtable_byte_len(&self.field_locs);
|
let vtable_byte_len = get_vtable_byte_len(&self.field_locs);
|
||||||
self.make_space(vtable_byte_len);
|
self.make_space(vtable_byte_len)?;
|
||||||
|
|
||||||
// compute the length of the table (not vtable!) in bytes:
|
// compute the length of the table (not vtable!) in bytes:
|
||||||
let table_object_size = object_revloc_to_vtable.value() - table_tail_revloc.value();
|
let table_object_size = object_revloc_to_vtable.value() - table_tail_revloc.value();
|
||||||
@@ -611,6 +895,8 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
// Write the VTable (we may delete it afterwards, if it is a duplicate):
|
// Write the VTable (we may delete it afterwards, if it is a duplicate):
|
||||||
let vt_start_pos = self.head;
|
let vt_start_pos = self.head;
|
||||||
let vt_end_pos = self.head + vtable_byte_len;
|
let vt_end_pos = self.head + vtable_byte_len;
|
||||||
|
// Zero out the vtable space - make_space only reserves but doesn't initialize
|
||||||
|
self.allocator[vt_start_pos.range_to(vt_end_pos)].fill(0);
|
||||||
{
|
{
|
||||||
// write the vtable header:
|
// write the vtable header:
|
||||||
let vtfw =
|
let vtfw =
|
||||||
@@ -625,13 +911,15 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let new_vt_bytes = &self.allocator[vt_start_pos.range_to(vt_end_pos)];
|
let new_vt_bytes = &self.allocator[vt_start_pos.range_to(vt_end_pos)];
|
||||||
let found = self.written_vtable_revpos.binary_search_by(|old_vtable_revpos: &UOffsetT| {
|
let found = self
|
||||||
let old_vtable_pos = self.allocator.len() - *old_vtable_revpos as usize;
|
.written_vtable_revpos
|
||||||
// Safety:
|
.binary_search_by(|old_vtable_revpos: &UOffsetT| {
|
||||||
// Already written vtables are valid by construction
|
let old_vtable_pos = self.allocator.len() - *old_vtable_revpos as usize;
|
||||||
let old_vtable = unsafe { VTable::init(&self.allocator, old_vtable_pos) };
|
// Safety:
|
||||||
new_vt_bytes.cmp(old_vtable.as_bytes())
|
// Already written vtables are valid by construction
|
||||||
});
|
let old_vtable = unsafe { VTable::init(&self.allocator, old_vtable_pos) };
|
||||||
|
new_vt_bytes.cmp(old_vtable.as_bytes())
|
||||||
|
});
|
||||||
let final_vtable_revpos = match found {
|
let final_vtable_revpos = match found {
|
||||||
Ok(i) => {
|
Ok(i) => {
|
||||||
// The new vtable is a duplicate so clear it.
|
// The new vtable is a duplicate so clear it.
|
||||||
@@ -669,17 +957,18 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
|
|
||||||
self.field_locs.clear();
|
self.field_locs.clear();
|
||||||
|
|
||||||
object_revloc_to_vtable
|
Ok(object_revloc_to_vtable)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only call this when you know it is safe to double the size of the buffer.
|
// Only call this when you know it is safe to double the size of the buffer.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn grow_allocator(&mut self) {
|
fn grow_allocator(&mut self) -> Result<(), A::Error> {
|
||||||
let starting_active_size = self.used_space();
|
let starting_active_size = self.used_space();
|
||||||
self.allocator.grow_downwards().expect("Flatbuffer allocation failure");
|
self.allocator.grow_downwards()?;
|
||||||
|
|
||||||
let ending_active_size = self.used_space();
|
let ending_active_size = self.used_space();
|
||||||
debug_assert_eq!(starting_active_size, ending_active_size);
|
debug_assert_eq!(starting_active_size, ending_active_size);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// with or without a size prefix changes how we load the data, so finish*
|
// with or without a size prefix changes how we load the data, so finish*
|
||||||
@@ -689,7 +978,7 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
root: WIPOffset<T>,
|
root: WIPOffset<T>,
|
||||||
file_identifier: Option<&str>,
|
file_identifier: Option<&str>,
|
||||||
size_prefixed: bool,
|
size_prefixed: bool,
|
||||||
) {
|
) -> Result<(), A::Error> {
|
||||||
self.assert_not_finished("buffer cannot be finished when it is already finished");
|
self.assert_not_finished("buffer cannot be finished when it is already finished");
|
||||||
self.assert_not_nested(
|
self.assert_not_nested(
|
||||||
"buffer cannot be finished when a table or vector is under construction",
|
"buffer cannot be finished when a table or vector is under construction",
|
||||||
@@ -702,34 +991,40 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
// for the size prefix:
|
// for the size prefix:
|
||||||
let b = if size_prefixed { SIZE_UOFFSET } else { 0 };
|
let b = if size_prefixed { SIZE_UOFFSET } else { 0 };
|
||||||
// for the file identifier (a string that is not zero-terminated):
|
// for the file identifier (a string that is not zero-terminated):
|
||||||
let c = if file_identifier.is_some() { FILE_IDENTIFIER_LENGTH } else { 0 };
|
let c = if file_identifier.is_some() {
|
||||||
|
FILE_IDENTIFIER_LENGTH
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
a + b + c
|
a + b + c
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
let ma = PushAlignment::new(self.min_align);
|
let ma = PushAlignment::new(self.min_align);
|
||||||
self.align(to_align, ma);
|
self.align(to_align, ma)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ident) = file_identifier {
|
if let Some(ident) = file_identifier {
|
||||||
debug_assert_eq!(ident.len(), FILE_IDENTIFIER_LENGTH);
|
debug_assert_eq!(ident.len(), FILE_IDENTIFIER_LENGTH);
|
||||||
self.push_bytes_unprefixed(ident.as_bytes());
|
self.push_bytes_unprefixed(ident.as_bytes())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.push(root);
|
self.try_push(root)?;
|
||||||
|
|
||||||
if size_prefixed {
|
if size_prefixed {
|
||||||
let sz = self.used_space() as UOffsetT;
|
let sz = self.used_space() as UOffsetT;
|
||||||
self.push::<UOffsetT>(sz);
|
self.try_push::<UOffsetT>(sz)?;
|
||||||
}
|
}
|
||||||
self.finished = true;
|
self.finished = true;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn align(&mut self, len: usize, alignment: PushAlignment) {
|
fn align(&mut self, len: usize, alignment: PushAlignment) -> Result<(), A::Error> {
|
||||||
self.track_min_align(alignment.value());
|
self.track_min_align(alignment.value());
|
||||||
let s = self.used_space() as usize;
|
let s = self.used_space() as usize;
|
||||||
self.make_space(padding_bytes(s + len, alignment.value()));
|
self.make_space(padding_bytes(s + len, alignment.value()))?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -738,31 +1033,34 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn push_bytes_unprefixed(&mut self, x: &[u8]) -> UOffsetT {
|
fn push_bytes_unprefixed(&mut self, x: &[u8]) -> Result<UOffsetT, A::Error> {
|
||||||
let n = self.make_space(x.len());
|
let n = self.make_space(x.len())?;
|
||||||
self.allocator[n.range_to(n + x.len())].copy_from_slice(x);
|
self.allocator[n.range_to(n + x.len())].copy_from_slice(x);
|
||||||
|
|
||||||
n.to_forward_index(&self.allocator) as UOffsetT
|
Ok(n.to_forward_index(&self.allocator) as UOffsetT)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn make_space(&mut self, want: usize) -> ReverseIndex {
|
fn make_space(&mut self, want: usize) -> Result<ReverseIndex, A::Error> {
|
||||||
self.ensure_capacity(want);
|
self.ensure_capacity(want)?;
|
||||||
self.head -= want;
|
self.head -= want;
|
||||||
self.head
|
Ok(self.head)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ensure_capacity(&mut self, want: usize) -> usize {
|
fn ensure_capacity(&mut self, want: usize) -> Result<usize, A::Error> {
|
||||||
if self.unused_ready_space() >= want {
|
if self.unused_ready_space() >= want {
|
||||||
return want;
|
return Ok(want);
|
||||||
}
|
}
|
||||||
assert!(want <= FLATBUFFERS_MAX_BUFFER_SIZE, "cannot grow buffer beyond 2 gigabytes");
|
assert!(
|
||||||
|
want <= FLATBUFFERS_MAX_BUFFER_SIZE,
|
||||||
|
"cannot grow buffer beyond 2 gigabytes"
|
||||||
|
);
|
||||||
|
|
||||||
while self.unused_ready_space() < want {
|
while self.unused_ready_space() < want {
|
||||||
self.grow_allocator();
|
self.grow_allocator()?;
|
||||||
}
|
}
|
||||||
want
|
Ok(want)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn unused_ready_space(&self) -> usize {
|
fn unused_ready_space(&self) -> usize {
|
||||||
@@ -929,6 +1227,33 @@ impl<T> IndexMut<ReverseIndexRange> for [T] {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
use std::alloc::{GlobalAlloc, Layout, System};
|
||||||
|
|
||||||
|
static ALLOC_COUNT: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
|
struct CountingAllocator;
|
||||||
|
|
||||||
|
unsafe impl GlobalAlloc for CountingAllocator {
|
||||||
|
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||||
|
ALLOC_COUNT.fetch_add(1, Ordering::Relaxed);
|
||||||
|
unsafe { System.alloc(layout) }
|
||||||
|
}
|
||||||
|
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||||
|
unsafe { System.dealloc(ptr, layout) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[global_allocator]
|
||||||
|
static GLOBAL: CountingAllocator = CountingAllocator;
|
||||||
|
|
||||||
|
fn reset_alloc_count() {
|
||||||
|
ALLOC_COUNT.store(0, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc_count() -> usize {
|
||||||
|
ALLOC_COUNT.load(Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reverse_index_test() {
|
fn reverse_index_test() {
|
||||||
@@ -938,4 +1263,150 @@ mod tests {
|
|||||||
assert_eq!(&buf[idx.range_to(idx + 1)], &[4]);
|
assert_eq!(&buf[idx.range_to(idx + 1)], &[4]);
|
||||||
assert_eq!(idx.to_forward_index(&buf), 4);
|
assert_eq!(idx.to_forward_index(&buf), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn with_internal_capacity_preallocates_vecs() {
|
||||||
|
let mut builder = FlatBufferBuilder::with_internal_capacity(64, 8, 16, 32);
|
||||||
|
|
||||||
|
assert!(builder.allocator.len() >= 64);
|
||||||
|
assert!(builder.field_locs.capacity() >= 8);
|
||||||
|
assert!(builder.written_vtable_revpos.capacity() >= 16);
|
||||||
|
assert!(builder.strings_pool.capacity() >= 32);
|
||||||
|
|
||||||
|
assert!(builder.field_locs.is_empty());
|
||||||
|
assert!(builder.written_vtable_revpos.is_empty());
|
||||||
|
assert!(builder.strings_pool.is_empty());
|
||||||
|
|
||||||
|
// Reset the allocation counter after builder construction
|
||||||
|
reset_alloc_count();
|
||||||
|
|
||||||
|
// Add a shared string and verify it lands in the pool
|
||||||
|
let s1 = builder.create_shared_string("hello");
|
||||||
|
assert_eq!(builder.strings_pool.len(), 1);
|
||||||
|
|
||||||
|
// Adding the same string again should reuse the pooled entry
|
||||||
|
let s2 = builder.create_shared_string("hello");
|
||||||
|
assert_eq!(builder.strings_pool.len(), 1);
|
||||||
|
assert_eq!(s1.value(), s2.value());
|
||||||
|
|
||||||
|
// A different string should add a new entry
|
||||||
|
let _s3 = builder.create_shared_string("world");
|
||||||
|
assert_eq!(builder.strings_pool.len(), 2);
|
||||||
|
|
||||||
|
// With sufficient preallocated capacity, no additional allocations
|
||||||
|
// should have occurred for the internal vecs during the operations above
|
||||||
|
let allocs = alloc_count();
|
||||||
|
assert_eq!(
|
||||||
|
allocs, 0,
|
||||||
|
"expected 0 allocations after builder construction, got {}",
|
||||||
|
allocs
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A test allocator that fails after a specified number of grow operations.
|
||||||
|
struct FailingAllocator {
|
||||||
|
inner: DefaultAllocator,
|
||||||
|
grows_remaining: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
struct AllocationError;
|
||||||
|
|
||||||
|
impl core::fmt::Display for AllocationError {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
write!(f, "allocation failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FailingAllocator {
|
||||||
|
fn new(initial_size: usize, max_grows: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: DefaultAllocator::from_vec(vec![0u8; initial_size]),
|
||||||
|
grows_remaining: max_grows,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for FailingAllocator {
|
||||||
|
type Target = [u8];
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for FailingAllocator {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Allocator for FailingAllocator {
|
||||||
|
type Error = AllocationError;
|
||||||
|
|
||||||
|
fn grow_downwards(&mut self) -> Result<(), Self::Error> {
|
||||||
|
if self.grows_remaining == 0 {
|
||||||
|
return Err(AllocationError);
|
||||||
|
}
|
||||||
|
self.grows_remaining -= 1;
|
||||||
|
// DefaultAllocator returns Infallible, so unwrap is safe
|
||||||
|
self.inner.grow_downwards().unwrap();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
self.inner.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_push_propagates_allocation_error() {
|
||||||
|
let allocator = FailingAllocator::new(1, 0);
|
||||||
|
let mut builder = FlatBufferBuilder::new_in(allocator);
|
||||||
|
|
||||||
|
let result = builder.try_push::<u64>(0x1234567890ABCDEF);
|
||||||
|
assert!(result.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_create_string_propagates_allocation_error() {
|
||||||
|
let allocator = FailingAllocator::new(1, 0);
|
||||||
|
let mut builder = FlatBufferBuilder::new_in(allocator);
|
||||||
|
|
||||||
|
let result = builder.try_create_string("hello world");
|
||||||
|
assert!(result.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_create_vector_propagates_allocation_error() {
|
||||||
|
let allocator = FailingAllocator::new(1, 0);
|
||||||
|
let mut builder = FlatBufferBuilder::new_in(allocator);
|
||||||
|
|
||||||
|
let result = builder.try_create_vector(&[1u32, 2, 3, 4, 5]);
|
||||||
|
assert!(result.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_methods_succeed_with_sufficient_capacity() {
|
||||||
|
let allocator = FailingAllocator::new(1, 10);
|
||||||
|
let mut builder = FlatBufferBuilder::new_in(allocator);
|
||||||
|
|
||||||
|
let result = builder.try_create_string("hello");
|
||||||
|
assert!(result.is_ok());
|
||||||
|
|
||||||
|
let result = builder.try_create_vector(&[1u32, 2, 3]);
|
||||||
|
assert!(result.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_finish_propagates_allocation_error() {
|
||||||
|
let allocator = FailingAllocator::new(1, 3);
|
||||||
|
let mut builder = FlatBufferBuilder::new_in(allocator);
|
||||||
|
|
||||||
|
let start = builder.start_table();
|
||||||
|
let table = builder
|
||||||
|
.try_end_table(start)
|
||||||
|
.expect("end_table should succeed with 3 grows");
|
||||||
|
let result = builder.try_finish_minimal(table);
|
||||||
|
assert!(result.is_err(), "finish should fail after grows exhausted");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,20 @@ impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
|
|||||||
key: K,
|
key: K,
|
||||||
f: fn(&<T as Follow<'a>>::Inner, &K) -> Ordering,
|
f: fn(&<T as Follow<'a>>::Inner, &K) -> Ordering,
|
||||||
) -> Option<T::Inner> {
|
) -> Option<T::Inner> {
|
||||||
|
self.lookup_index_by_key(key, f).map(|idx| self.get(idx))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Binary search by key, returning the index of the matching element.
|
||||||
|
///
|
||||||
|
/// This is similar to `lookup_by_key`, but returns the index of the found
|
||||||
|
/// element rather than the element itself. This is useful when you need
|
||||||
|
/// to reference elements by their position in the vector.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn lookup_index_by_key<K: Ord>(
|
||||||
|
&self,
|
||||||
|
key: K,
|
||||||
|
f: fn(&<T as Follow<'a>>::Inner, &K) -> Ordering,
|
||||||
|
) -> Option<usize> {
|
||||||
if self.is_empty() {
|
if self.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -118,7 +132,7 @@ impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
|
|||||||
let mid = (left + right) / 2;
|
let mid = (left + right) / 2;
|
||||||
let value = self.get(mid);
|
let value = self.get(mid);
|
||||||
match f(&value, &key) {
|
match f(&value, &key) {
|
||||||
Ordering::Equal => return Some(value),
|
Ordering::Equal => return Some(mid),
|
||||||
Ordering::Less => left = mid + 1,
|
Ordering::Less => left = mid + 1,
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
if mid == 0 {
|
if mid == 0 {
|
||||||
|
|||||||
@@ -492,8 +492,8 @@ impl<'ver, 'opts, 'buf> TableVerifier<'ver, 'opts, 'buf> {
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
_ => InvalidFlatbuffer::new_inconsistent_union(
|
_ => InvalidFlatbuffer::new_inconsistent_union(
|
||||||
key_field_name.into(),
|
|
||||||
val_field_name.into(),
|
val_field_name.into(),
|
||||||
|
key_field_name.into(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -421,6 +421,9 @@ impl<'a> Serializer for MapKeySerializer<'a> {
|
|||||||
type SerializeStruct = Impossible<(), Error>;
|
type SerializeStruct = Impossible<(), Error>;
|
||||||
type SerializeStructVariant = Impossible<(), Error>;
|
type SerializeStructVariant = Impossible<(), Error>;
|
||||||
|
|
||||||
|
fn is_human_readable(&self) -> bool {
|
||||||
|
self.0.is_human_readable()
|
||||||
|
}
|
||||||
fn serialize_bool(self, _value: bool) -> Result<(), Error> {
|
fn serialize_bool(self, _value: bool) -> Result<(), Error> {
|
||||||
key_must_be_a_string()
|
key_must_be_a_string()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -397,8 +397,8 @@ fn verify_union<'a, 'b, 'c>(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return InvalidFlatbuffer::new_inconsistent_union(
|
return InvalidFlatbuffer::new_inconsistent_union(
|
||||||
format!("{}_type", field.name()),
|
|
||||||
field.name().to_string(),
|
field.name().to_string(),
|
||||||
|
format!("{}_type", field.name()),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -328,6 +328,10 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
|||||||
const MyGame::Sample::Weapon *equipped_as_Weapon() const {
|
const MyGame::Sample::Weapon *equipped_as_Weapon() const {
|
||||||
return equipped_type() == MyGame::Sample::Equipment_Weapon ? static_cast<const MyGame::Sample::Weapon *>(equipped()) : nullptr;
|
return equipped_type() == MyGame::Sample::Equipment_Weapon ? static_cast<const MyGame::Sample::Weapon *>(equipped()) : nullptr;
|
||||||
}
|
}
|
||||||
|
template<typename T> T *mutable_equipped_as();
|
||||||
|
MyGame::Sample::Weapon *mutable_equipped_as_Weapon() {
|
||||||
|
return equipped_type() == MyGame::Sample::Equipment_Weapon ? static_cast<MyGame::Sample::Weapon *>(mutable_equipped()) : nullptr;
|
||||||
|
}
|
||||||
void *mutable_equipped() {
|
void *mutable_equipped() {
|
||||||
return GetPointer<void *>(VT_EQUIPPED);
|
return GetPointer<void *>(VT_EQUIPPED);
|
||||||
}
|
}
|
||||||
@@ -367,6 +371,10 @@ template<> inline const MyGame::Sample::Weapon *Monster::equipped_as<MyGame::Sam
|
|||||||
return equipped_as_Weapon();
|
return equipped_as_Weapon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<> inline MyGame::Sample::Weapon *Monster::mutable_equipped_as<MyGame::Sample::Weapon>() {
|
||||||
|
return mutable_equipped_as_Weapon();
|
||||||
|
}
|
||||||
|
|
||||||
struct MonsterBuilder {
|
struct MonsterBuilder {
|
||||||
typedef Monster Table;
|
typedef Monster Table;
|
||||||
::flatbuffers::FlatBufferBuilder &fbb_;
|
::flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
@@ -635,7 +643,7 @@ inline ::flatbuffers::Offset<Monster> Monster::Pack(::flatbuffers::FlatBufferBui
|
|||||||
auto _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name);
|
auto _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name);
|
||||||
auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
|
auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
|
||||||
auto _color = _o->color;
|
auto _color = _o->color;
|
||||||
auto _weapons = _o->weapons.size() ? _fbb.CreateVector<::flatbuffers::Offset<MyGame::Sample::Weapon>> (_o->weapons.size(), [](size_t i, _VectorArgs *__va) { return CreateWeapon(*__va->__fbb, __va->__o->weapons[i].get(), __va->__rehasher); }, &_va ) : 0;
|
auto _weapons = _o->weapons.size() ? _fbb.CreateVector<::flatbuffers::Offset<MyGame::Sample::Weapon>> (_o->weapons.size(), [](size_t i, _VectorArgs *__va) { return MyGame::Sample::CreateWeapon(*__va->__fbb, __va->__o->weapons[i].get(), __va->__rehasher); }, &_va ) : 0;
|
||||||
auto _equipped_type = _o->equipped.type;
|
auto _equipped_type = _o->equipped.type;
|
||||||
auto _equipped = _o->equipped.Pack(_fbb);
|
auto _equipped = _o->equipped.Pack(_fbb);
|
||||||
auto _path = _o->path.size() ? _fbb.CreateVectorOfStructs(_o->path) : 0;
|
auto _path = _o->path.size() ? _fbb.CreateVectorOfStructs(_o->path) : 0;
|
||||||
|
|||||||
@@ -113,12 +113,12 @@ public struct MyGame_Sample_Vec3: NativeStruct, FlatbuffersVectorInitializable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension MyGame_Sample_Vec3: Encodable {
|
extension MyGame_Sample_Vec3: Encodable {
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case x = "x"
|
case x = "x"
|
||||||
case y = "y"
|
case y = "y"
|
||||||
case z = "z"
|
case z = "z"
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
if x != 0.0 {
|
if x != 0.0 {
|
||||||
@@ -161,7 +161,7 @@ public struct MyGame_Sample_Vec3_Mutable: FlatBufferStruct, FlatbuffersVectorIni
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct MyGame_Sample_Monster: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Sample_Monster: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
@@ -170,51 +170,49 @@ public struct MyGame_Sample_Monster: FlatBufferTable, FlatbuffersVectorInitializ
|
|||||||
private init(_ t: Table) { _accessor = t }
|
private init(_ t: Table) { _accessor = t }
|
||||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||||
|
|
||||||
private enum VTOFFSET: VOffset {
|
private struct VT {
|
||||||
case pos = 4
|
static let pos: VOffset = 4
|
||||||
case mana = 6
|
static let mana: VOffset = 6
|
||||||
case hp = 8
|
static let hp: VOffset = 8
|
||||||
case name = 10
|
static let name: VOffset = 10
|
||||||
case inventory = 14
|
static let inventory: VOffset = 14
|
||||||
case color = 16
|
static let color: VOffset = 16
|
||||||
case weapons = 18
|
static let weapons: VOffset = 18
|
||||||
case equippedType = 20
|
static let equippedType: VOffset = 20
|
||||||
case equipped = 22
|
static let equipped: VOffset = 22
|
||||||
case path = 24
|
static let path: VOffset = 24
|
||||||
var v: Int32 { Int32(self.rawValue) }
|
|
||||||
var p: VOffset { self.rawValue }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var pos: MyGame_Sample_Vec3? { let o = _accessor.offset(VTOFFSET.pos.v); return o == 0 ? nil : _accessor.readBuffer(of: MyGame_Sample_Vec3.self, at: o) }
|
public var pos: MyGame_Sample_Vec3? { let o = _accessor.offset(VT.pos); return o == 0 ? nil : _accessor.readBuffer(of: MyGame_Sample_Vec3.self, at: o) }
|
||||||
public var mutablePos: MyGame_Sample_Vec3_Mutable? { let o = _accessor.offset(VTOFFSET.pos.v); return o == 0 ? nil : MyGame_Sample_Vec3_Mutable(_accessor.bb, o: o + _accessor.position) }
|
public var mutablePos: MyGame_Sample_Vec3_Mutable? { let o = _accessor.offset(VT.pos); return o == 0 ? nil : MyGame_Sample_Vec3_Mutable(_accessor.bb, o: o + _accessor.position) }
|
||||||
public var mana: Int16 { let o = _accessor.offset(VTOFFSET.mana.v); return o == 0 ? 150 : _accessor.readBuffer(of: Int16.self, at: o) }
|
public var mana: Int16 { let o = _accessor.offset(VT.mana); return o == 0 ? 150 : _accessor.readBuffer(of: Int16.self, at: o) }
|
||||||
@discardableResult public func mutate(mana: Int16) -> Bool {let o = _accessor.offset(VTOFFSET.mana.v); return _accessor.mutate(mana, index: o) }
|
@discardableResult public func mutate(mana: Int16) -> Bool {let o = _accessor.offset(VT.mana); return _accessor.mutate(mana, index: o) }
|
||||||
public var hp: Int16 { let o = _accessor.offset(VTOFFSET.hp.v); return o == 0 ? 100 : _accessor.readBuffer(of: Int16.self, at: o) }
|
public var hp: Int16 { let o = _accessor.offset(VT.hp); return o == 0 ? 100 : _accessor.readBuffer(of: Int16.self, at: o) }
|
||||||
@discardableResult public func mutate(hp: Int16) -> Bool {let o = _accessor.offset(VTOFFSET.hp.v); return _accessor.mutate(hp, index: o) }
|
@discardableResult public func mutate(hp: Int16) -> Bool {let o = _accessor.offset(VT.hp); return _accessor.mutate(hp, index: o) }
|
||||||
public var name: String? { let o = _accessor.offset(VTOFFSET.name.v); return o == 0 ? nil : _accessor.string(at: o) }
|
public var name: String? { let o = _accessor.offset(VT.name); return o == 0 ? nil : _accessor.string(at: o) }
|
||||||
public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: VTOFFSET.name.v) }
|
public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: VT.name) }
|
||||||
public var inventory: FlatbufferVector<UInt8> { return _accessor.vector(at: VTOFFSET.inventory.v, byteSize: 1) }
|
public var inventory: FlatbufferVector<UInt8> { return _accessor.vector(at: VT.inventory, byteSize: 1) }
|
||||||
public func mutate(inventory: UInt8, at index: Int32) -> Bool { let o = _accessor.offset(VTOFFSET.inventory.v); return _accessor.directMutate(inventory, index: _accessor.vector(at: o) + index * 1) }
|
public func mutate(inventory: UInt8, at index: Int32) -> Bool { let o = _accessor.offset(VT.inventory); return _accessor.directMutate(inventory, index: _accessor.vector(at: o) + index * 1) }
|
||||||
public func withUnsafePointerToInventory<T>(_ body: (UnsafeRawBufferPointer, Int) throws -> T) rethrows -> T? { return try _accessor.withUnsafePointerToSlice(at: VTOFFSET.inventory.v, body: body) }
|
public func withUnsafePointerToInventory<T>(_ body: (UnsafeRawBufferPointer, Int) throws -> T) rethrows -> T? { return try _accessor.withUnsafePointerToSlice(at: VT.inventory, body: body) }
|
||||||
public var color: MyGame_Sample_Color { let o = _accessor.offset(VTOFFSET.color.v); return o == 0 ? .blue : MyGame_Sample_Color(rawValue: _accessor.readBuffer(of: Int8.self, at: o)) ?? .blue }
|
public var color: MyGame_Sample_Color { let o = _accessor.offset(VT.color); return o == 0 ? .blue : MyGame_Sample_Color(rawValue: _accessor.readBuffer(of: Int8.self, at: o)) ?? .blue }
|
||||||
@discardableResult public func mutate(color: MyGame_Sample_Color) -> Bool {let o = _accessor.offset(VTOFFSET.color.v); return _accessor.mutate(color.rawValue, index: o) }
|
@discardableResult public func mutate(color: MyGame_Sample_Color) -> Bool {let o = _accessor.offset(VT.color); return _accessor.mutate(color.rawValue, index: o) }
|
||||||
public var weapons: FlatbufferVector<MyGame_Sample_Weapon> { return _accessor.vector(at: VTOFFSET.weapons.v, byteSize: 4) }
|
public var weapons: FlatbufferVector<MyGame_Sample_Weapon> { return _accessor.vector(at: VT.weapons, byteSize: 4) }
|
||||||
public var equippedType: MyGame_Sample_Equipment { let o = _accessor.offset(VTOFFSET.equippedType.v); return o == 0 ? .none_ : MyGame_Sample_Equipment(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .none_ }
|
public var equippedType: MyGame_Sample_Equipment { let o = _accessor.offset(VT.equippedType); return o == 0 ? .none_ : MyGame_Sample_Equipment(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .none_ }
|
||||||
public func equipped<T: FlatbuffersInitializable>(type: T.Type) -> T? { let o = _accessor.offset(VTOFFSET.equipped.v); return o == 0 ? nil : _accessor.union(o) }
|
public func equipped<T: FlatbuffersInitializable>(type: T.Type) -> T? { let o = _accessor.offset(VT.equipped); return o == 0 ? nil : _accessor.union(o) }
|
||||||
public var path: FlatbufferVector<MyGame_Sample_Vec3> { return _accessor.vector(at: VTOFFSET.path.v, byteSize: 12) }
|
public var path: FlatbufferVector<MyGame_Sample_Vec3> { return _accessor.vector(at: VT.path, byteSize: 12) }
|
||||||
public var mutablePath: FlatbufferVector<MyGame_Sample_Vec3_Mutable> { return _accessor.vector(at: VTOFFSET.path.v, byteSize: 12) }
|
public var mutablePath: FlatbufferVector<MyGame_Sample_Vec3_Mutable> { return _accessor.vector(at: VT.path, byteSize: 12) }
|
||||||
public func withUnsafePointerToPath<T>(_ body: (UnsafeRawBufferPointer, Int) throws -> T) rethrows -> T? { return try _accessor.withUnsafePointerToSlice(at: VTOFFSET.path.v, body: body) }
|
public func withUnsafePointerToPath<T>(_ body: (UnsafeRawBufferPointer, Int) throws -> T) rethrows -> T? { return try _accessor.withUnsafePointerToSlice(at: VT.path, body: body) }
|
||||||
public static func startMonster(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 11) }
|
public static func startMonster(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 11) }
|
||||||
public static func add(pos: MyGame_Sample_Vec3?, _ fbb: inout FlatBufferBuilder) { guard let pos = pos else { return }; fbb.create(struct: pos, position: VTOFFSET.pos.p) }
|
public static func add(pos: MyGame_Sample_Vec3?, _ fbb: inout FlatBufferBuilder) { guard let pos = pos else { return }; fbb.create(struct: pos, position: VT.pos) }
|
||||||
public static func add(mana: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: mana, def: 150, at: VTOFFSET.mana.p) }
|
public static func add(mana: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: mana, def: 150, at: VT.mana) }
|
||||||
public static func add(hp: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: hp, def: 100, at: VTOFFSET.hp.p) }
|
public static func add(hp: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: hp, def: 100, at: VT.hp) }
|
||||||
public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VTOFFSET.name.p) }
|
public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VT.name) }
|
||||||
public static func addVectorOf(inventory: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: inventory, at: VTOFFSET.inventory.p) }
|
public static func addVectorOf(inventory: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: inventory, at: VT.inventory) }
|
||||||
public static func add(color: MyGame_Sample_Color, _ fbb: inout FlatBufferBuilder) { fbb.add(element: color.rawValue, def: 2, at: VTOFFSET.color.p) }
|
public static func add(color: MyGame_Sample_Color, _ fbb: inout FlatBufferBuilder) { fbb.add(element: color.rawValue, def: 2, at: VT.color) }
|
||||||
public static func addVectorOf(weapons: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: weapons, at: VTOFFSET.weapons.p) }
|
public static func addVectorOf(weapons: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: weapons, at: VT.weapons) }
|
||||||
public static func add(equippedType: MyGame_Sample_Equipment, _ fbb: inout FlatBufferBuilder) { fbb.add(element: equippedType.rawValue, def: 0, at: VTOFFSET.equippedType.p) }
|
public static func add(equippedType: MyGame_Sample_Equipment, _ fbb: inout FlatBufferBuilder) { fbb.add(element: equippedType.rawValue, def: 0, at: VT.equippedType) }
|
||||||
public static func add(equipped: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: equipped, at: VTOFFSET.equipped.p) }
|
public static func add(equipped: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: equipped, at: VT.equipped) }
|
||||||
public static func addVectorOf(path: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: path, at: VTOFFSET.path.p) }
|
public static func addVectorOf(path: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: path, at: VT.path) }
|
||||||
public static func startVectorOfPath(_ size: Int, in builder: inout FlatBufferBuilder) {
|
public static func startVectorOfPath(_ size: Int, in builder: inout FlatBufferBuilder) {
|
||||||
builder.startVector(size * MemoryLayout<MyGame_Sample_Vec3>.size, elementSize: MemoryLayout<MyGame_Sample_Vec3>.alignment)
|
builder.startVector(size * MemoryLayout<MyGame_Sample_Vec3>.size, elementSize: MemoryLayout<MyGame_Sample_Vec3>.alignment)
|
||||||
}
|
}
|
||||||
@@ -293,14 +291,14 @@ public struct MyGame_Sample_Monster: FlatBufferTable, FlatbuffersVectorInitializ
|
|||||||
|
|
||||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||||
var _v = try verifier.visitTable(at: position)
|
var _v = try verifier.visitTable(at: position)
|
||||||
try _v.visit(field: VTOFFSET.pos.p, fieldName: "pos", required: false, type: MyGame_Sample_Vec3.self)
|
try _v.visit(field: VT.pos, fieldName: "pos", required: false, type: MyGame_Sample_Vec3.self)
|
||||||
try _v.visit(field: VTOFFSET.mana.p, fieldName: "mana", required: false, type: Int16.self)
|
try _v.visit(field: VT.mana, fieldName: "mana", required: false, type: Int16.self)
|
||||||
try _v.visit(field: VTOFFSET.hp.p, fieldName: "hp", required: false, type: Int16.self)
|
try _v.visit(field: VT.hp, fieldName: "hp", required: false, type: Int16.self)
|
||||||
try _v.visit(field: VTOFFSET.name.p, fieldName: "name", required: false, type: ForwardOffset<String>.self)
|
try _v.visit(field: VT.name, fieldName: "name", required: false, type: ForwardOffset<String>.self)
|
||||||
try _v.visit(field: VTOFFSET.inventory.p, fieldName: "inventory", required: false, type: ForwardOffset<Vector<UInt8, UInt8>>.self)
|
try _v.visit(field: VT.inventory, fieldName: "inventory", required: false, type: ForwardOffset<Vector<UInt8, UInt8>>.self)
|
||||||
try _v.visit(field: VTOFFSET.color.p, fieldName: "color", required: false, type: MyGame_Sample_Color.self)
|
try _v.visit(field: VT.color, fieldName: "color", required: false, type: MyGame_Sample_Color.self)
|
||||||
try _v.visit(field: VTOFFSET.weapons.p, fieldName: "weapons", required: false, type: ForwardOffset<Vector<ForwardOffset<MyGame_Sample_Weapon>, MyGame_Sample_Weapon>>.self)
|
try _v.visit(field: VT.weapons, fieldName: "weapons", required: false, type: ForwardOffset<Vector<ForwardOffset<MyGame_Sample_Weapon>, MyGame_Sample_Weapon>>.self)
|
||||||
try _v.visit(unionKey: VTOFFSET.equippedType.p, unionField: VTOFFSET.equipped.p, unionKeyName: "equippedType", fieldName: "equipped", required: false, completion: { (verifier, key: MyGame_Sample_Equipment, pos) in
|
try _v.visit(unionKey: VT.equippedType, unionField: VT.equipped, unionKeyName: "equippedType", fieldName: "equipped", required: false, completion: { (verifier, key: MyGame_Sample_Equipment, pos) in
|
||||||
switch key {
|
switch key {
|
||||||
case .none_:
|
case .none_:
|
||||||
break // NOTE - SWIFT doesnt support none
|
break // NOTE - SWIFT doesnt support none
|
||||||
@@ -308,13 +306,12 @@ public struct MyGame_Sample_Monster: FlatBufferTable, FlatbuffersVectorInitializ
|
|||||||
try ForwardOffset<MyGame_Sample_Weapon>.verify(&verifier, at: pos, of: MyGame_Sample_Weapon.self)
|
try ForwardOffset<MyGame_Sample_Weapon>.verify(&verifier, at: pos, of: MyGame_Sample_Weapon.self)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
try _v.visit(field: VTOFFSET.path.p, fieldName: "path", required: false, type: ForwardOffset<Vector<MyGame_Sample_Vec3, MyGame_Sample_Vec3>>.self)
|
try _v.visit(field: VT.path, fieldName: "path", required: false, type: ForwardOffset<Vector<MyGame_Sample_Vec3, MyGame_Sample_Vec3>>.self)
|
||||||
_v.finish()
|
_v.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MyGame_Sample_Monster: Encodable {
|
extension MyGame_Sample_Monster: Encodable {
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case pos = "pos"
|
case pos = "pos"
|
||||||
case mana = "mana"
|
case mana = "mana"
|
||||||
@@ -327,6 +324,7 @@ extension MyGame_Sample_Monster: Encodable {
|
|||||||
case equipped = "equipped"
|
case equipped = "equipped"
|
||||||
case path = "path"
|
case path = "path"
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encodeIfPresent(pos, forKey: .pos)
|
try container.encodeIfPresent(pos, forKey: .pos)
|
||||||
@@ -402,7 +400,7 @@ public class MyGame_Sample_MonsterT: NativeObject {
|
|||||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Sample_Monster.self) }
|
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Sample_Monster.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct MyGame_Sample_Weapon: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Sample_Weapon: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
@@ -411,20 +409,18 @@ public struct MyGame_Sample_Weapon: FlatBufferTable, FlatbuffersVectorInitializa
|
|||||||
private init(_ t: Table) { _accessor = t }
|
private init(_ t: Table) { _accessor = t }
|
||||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||||
|
|
||||||
private enum VTOFFSET: VOffset {
|
private struct VT {
|
||||||
case name = 4
|
static let name: VOffset = 4
|
||||||
case damage = 6
|
static let damage: VOffset = 6
|
||||||
var v: Int32 { Int32(self.rawValue) }
|
|
||||||
var p: VOffset { self.rawValue }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var name: String? { let o = _accessor.offset(VTOFFSET.name.v); return o == 0 ? nil : _accessor.string(at: o) }
|
public var name: String? { let o = _accessor.offset(VT.name); return o == 0 ? nil : _accessor.string(at: o) }
|
||||||
public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: VTOFFSET.name.v) }
|
public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: VT.name) }
|
||||||
public var damage: Int16 { let o = _accessor.offset(VTOFFSET.damage.v); return o == 0 ? 0 : _accessor.readBuffer(of: Int16.self, at: o) }
|
public var damage: Int16 { let o = _accessor.offset(VT.damage); return o == 0 ? 0 : _accessor.readBuffer(of: Int16.self, at: o) }
|
||||||
@discardableResult public func mutate(damage: Int16) -> Bool {let o = _accessor.offset(VTOFFSET.damage.v); return _accessor.mutate(damage, index: o) }
|
@discardableResult public func mutate(damage: Int16) -> Bool {let o = _accessor.offset(VT.damage); return _accessor.mutate(damage, index: o) }
|
||||||
public static func startWeapon(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 2) }
|
public static func startWeapon(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 2) }
|
||||||
public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VTOFFSET.name.p) }
|
public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VT.name) }
|
||||||
public static func add(damage: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: damage, def: 0, at: VTOFFSET.damage.p) }
|
public static func add(damage: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: damage, def: 0, at: VT.damage) }
|
||||||
public static func endWeapon(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
|
public static func endWeapon(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
|
||||||
public static func createWeapon(
|
public static func createWeapon(
|
||||||
_ fbb: inout FlatBufferBuilder,
|
_ fbb: inout FlatBufferBuilder,
|
||||||
@@ -461,18 +457,18 @@ public struct MyGame_Sample_Weapon: FlatBufferTable, FlatbuffersVectorInitializa
|
|||||||
|
|
||||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||||
var _v = try verifier.visitTable(at: position)
|
var _v = try verifier.visitTable(at: position)
|
||||||
try _v.visit(field: VTOFFSET.name.p, fieldName: "name", required: false, type: ForwardOffset<String>.self)
|
try _v.visit(field: VT.name, fieldName: "name", required: false, type: ForwardOffset<String>.self)
|
||||||
try _v.visit(field: VTOFFSET.damage.p, fieldName: "damage", required: false, type: Int16.self)
|
try _v.visit(field: VT.damage, fieldName: "damage", required: false, type: Int16.self)
|
||||||
_v.finish()
|
_v.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MyGame_Sample_Weapon: Encodable {
|
extension MyGame_Sample_Weapon: Encodable {
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case name = "name"
|
case name = "name"
|
||||||
case damage = "damage"
|
case damage = "damage"
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encodeIfPresent(name, forKey: .name)
|
try container.encodeIfPresent(name, forKey: .name)
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
// Automatically generated by the Flatbuffers compiler. Do not modify.
|
// Automatically generated by the Flatbuffers compiler. Do not modify.
|
||||||
// @generated
|
// @generated
|
||||||
pub mod my_game {
|
pub mod my_game {
|
||||||
use super::*;
|
|
||||||
pub mod sample {
|
|
||||||
use super::*;
|
use super::*;
|
||||||
mod color_generated;
|
pub mod sample {
|
||||||
pub use self::color_generated::*;
|
use super::*;
|
||||||
mod equipment_generated;
|
mod color_generated;
|
||||||
pub use self::equipment_generated::*;
|
pub use self::color_generated::*;
|
||||||
mod vec_3_generated;
|
mod equipment_generated;
|
||||||
pub use self::vec_3_generated::*;
|
pub use self::equipment_generated::*;
|
||||||
mod monster_generated;
|
mod vec_3_generated;
|
||||||
pub use self::monster_generated::*;
|
pub use self::vec_3_generated::*;
|
||||||
mod weapon_generated;
|
mod monster_generated;
|
||||||
pub use self::weapon_generated::*;
|
pub use self::monster_generated::*;
|
||||||
} // sample
|
mod weapon_generated;
|
||||||
|
pub use self::weapon_generated::*;
|
||||||
|
} // sample
|
||||||
} // my_game
|
} // my_game
|
||||||
|
|||||||
@@ -2,64 +2,73 @@
|
|||||||
// @generated
|
// @generated
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||||
pub const ENUM_MIN_COLOR: i8 = 0;
|
pub const ENUM_MIN_COLOR: i8 = 0;
|
||||||
|
|
||||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||||
pub const ENUM_MAX_COLOR: i8 = 2;
|
pub const ENUM_MAX_COLOR: i8 = 2;
|
||||||
|
|
||||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub const ENUM_VALUES_COLOR: [Color; 3] = [
|
pub const ENUM_VALUES_COLOR: [Color; 3] = [
|
||||||
Color::Red,
|
Color::Red,
|
||||||
Color::Green,
|
Color::Green,
|
||||||
Color::Blue,
|
Color::Blue,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Color(pub i8);
|
pub struct Color(pub i8);
|
||||||
|
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
impl Color {
|
impl Color {
|
||||||
pub const Red: Self = Self(0);
|
pub const Red: Self = Self(0);
|
||||||
pub const Green: Self = Self(1);
|
pub const Green: Self = Self(1);
|
||||||
pub const Blue: Self = Self(2);
|
pub const Blue: Self = Self(2);
|
||||||
|
|
||||||
pub const ENUM_MIN: i8 = 0;
|
pub const ENUM_MIN: i8 = 0;
|
||||||
pub const ENUM_MAX: i8 = 2;
|
pub const ENUM_MAX: i8 = 2;
|
||||||
pub const ENUM_VALUES: &'static [Self] = &[
|
pub const ENUM_VALUES: &'static [Self] = &[
|
||||||
Self::Red,
|
Self::Red,
|
||||||
Self::Green,
|
Self::Green,
|
||||||
Self::Blue,
|
Self::Blue,
|
||||||
];
|
];
|
||||||
/// Returns the variant's name or "" if unknown.
|
|
||||||
pub fn variant_name(self) -> Option<&'static str> {
|
/// Returns the variant's name or "" if unknown.
|
||||||
match self {
|
pub fn variant_name(self) -> Option<&'static str> {
|
||||||
Self::Red => Some("Red"),
|
match self {
|
||||||
Self::Green => Some("Green"),
|
Self::Red => Some("Red"),
|
||||||
Self::Blue => Some("Blue"),
|
Self::Green => Some("Green"),
|
||||||
_ => None,
|
Self::Blue => Some("Blue"),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::core::fmt::Debug for Color {
|
impl ::core::fmt::Debug for Color {
|
||||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||||
if let Some(name) = self.variant_name() {
|
if let Some(name) = self.variant_name() {
|
||||||
f.write_str(name)
|
f.write_str(name)
|
||||||
} else {
|
} else {
|
||||||
f.write_fmt(format_args!("<UNKNOWN {:?}>", self.0))
|
f.write_fmt(format_args!("<UNKNOWN {:?}>", self.0))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ::flatbuffers::Follow<'a> for Color {
|
impl<'a> ::flatbuffers::Follow<'a> for Color {
|
||||||
type Inner = Self;
|
type Inner = Self;
|
||||||
#[inline]
|
|
||||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
#[inline]
|
||||||
let b = unsafe { ::flatbuffers::read_scalar_at::<i8>(buf, loc) };
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
Self(b)
|
let b = unsafe { ::flatbuffers::read_scalar_at::<i8>(buf, loc) };
|
||||||
}
|
Self(b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::flatbuffers::Push for Color {
|
impl ::flatbuffers::Push for Color {
|
||||||
type Output = Color;
|
type Output = Color;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||||
unsafe { ::flatbuffers::emplace_scalar::<i8>(dst, self.0) };
|
unsafe { ::flatbuffers::emplace_scalar::<i8>(dst, self.0) };
|
||||||
@@ -67,26 +76,28 @@ impl ::flatbuffers::Push for Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ::flatbuffers::EndianScalar for Color {
|
impl ::flatbuffers::EndianScalar for Color {
|
||||||
type Scalar = i8;
|
type Scalar = i8;
|
||||||
#[inline]
|
|
||||||
fn to_little_endian(self) -> i8 {
|
#[inline]
|
||||||
self.0.to_le()
|
fn to_little_endian(self) -> i8 {
|
||||||
}
|
self.0.to_le()
|
||||||
#[inline]
|
}
|
||||||
#[allow(clippy::wrong_self_convention)]
|
|
||||||
fn from_little_endian(v: i8) -> Self {
|
#[inline]
|
||||||
let b = i8::from_le(v);
|
#[allow(clippy::wrong_self_convention)]
|
||||||
Self(b)
|
fn from_little_endian(v: i8) -> Self {
|
||||||
}
|
let b = i8::from_le(v);
|
||||||
|
Self(b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ::flatbuffers::Verifiable for Color {
|
impl<'a> ::flatbuffers::Verifiable for Color {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn run_verifier(
|
fn run_verifier(
|
||||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||||
i8::run_verifier(v, pos)
|
i8::run_verifier(v, pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::flatbuffers::SimpleToVerifyInSlice for Color {}
|
impl ::flatbuffers::SimpleToVerifyInSlice for Color {}
|
||||||
|
|||||||
@@ -2,60 +2,69 @@
|
|||||||
// @generated
|
// @generated
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||||
pub const ENUM_MIN_EQUIPMENT: u8 = 0;
|
pub const ENUM_MIN_EQUIPMENT: u8 = 0;
|
||||||
|
|
||||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||||
pub const ENUM_MAX_EQUIPMENT: u8 = 1;
|
pub const ENUM_MAX_EQUIPMENT: u8 = 1;
|
||||||
|
|
||||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub const ENUM_VALUES_EQUIPMENT: [Equipment; 2] = [
|
pub const ENUM_VALUES_EQUIPMENT: [Equipment; 2] = [
|
||||||
Equipment::NONE,
|
Equipment::NONE,
|
||||||
Equipment::Weapon,
|
Equipment::Weapon,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Equipment(pub u8);
|
pub struct Equipment(pub u8);
|
||||||
|
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
impl Equipment {
|
impl Equipment {
|
||||||
pub const NONE: Self = Self(0);
|
pub const NONE: Self = Self(0);
|
||||||
pub const Weapon: Self = Self(1);
|
pub const Weapon: Self = Self(1);
|
||||||
|
|
||||||
pub const ENUM_MIN: u8 = 0;
|
pub const ENUM_MIN: u8 = 0;
|
||||||
pub const ENUM_MAX: u8 = 1;
|
pub const ENUM_MAX: u8 = 1;
|
||||||
pub const ENUM_VALUES: &'static [Self] = &[
|
pub const ENUM_VALUES: &'static [Self] = &[
|
||||||
Self::NONE,
|
Self::NONE,
|
||||||
Self::Weapon,
|
Self::Weapon,
|
||||||
];
|
];
|
||||||
/// Returns the variant's name or "" if unknown.
|
|
||||||
pub fn variant_name(self) -> Option<&'static str> {
|
/// Returns the variant's name or "" if unknown.
|
||||||
match self {
|
pub fn variant_name(self) -> Option<&'static str> {
|
||||||
Self::NONE => Some("NONE"),
|
match self {
|
||||||
Self::Weapon => Some("Weapon"),
|
Self::NONE => Some("NONE"),
|
||||||
_ => None,
|
Self::Weapon => Some("Weapon"),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::core::fmt::Debug for Equipment {
|
impl ::core::fmt::Debug for Equipment {
|
||||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||||
if let Some(name) = self.variant_name() {
|
if let Some(name) = self.variant_name() {
|
||||||
f.write_str(name)
|
f.write_str(name)
|
||||||
} else {
|
} else {
|
||||||
f.write_fmt(format_args!("<UNKNOWN {:?}>", self.0))
|
f.write_fmt(format_args!("<UNKNOWN {:?}>", self.0))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ::flatbuffers::Follow<'a> for Equipment {
|
impl<'a> ::flatbuffers::Follow<'a> for Equipment {
|
||||||
type Inner = Self;
|
type Inner = Self;
|
||||||
#[inline]
|
|
||||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
#[inline]
|
||||||
let b = unsafe { ::flatbuffers::read_scalar_at::<u8>(buf, loc) };
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
Self(b)
|
let b = unsafe { ::flatbuffers::read_scalar_at::<u8>(buf, loc) };
|
||||||
}
|
Self(b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::flatbuffers::Push for Equipment {
|
impl ::flatbuffers::Push for Equipment {
|
||||||
type Output = Equipment;
|
type Output = Equipment;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||||
unsafe { ::flatbuffers::emplace_scalar::<u8>(dst, self.0) };
|
unsafe { ::flatbuffers::emplace_scalar::<u8>(dst, self.0) };
|
||||||
@@ -63,75 +72,85 @@ impl ::flatbuffers::Push for Equipment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ::flatbuffers::EndianScalar for Equipment {
|
impl ::flatbuffers::EndianScalar for Equipment {
|
||||||
type Scalar = u8;
|
type Scalar = u8;
|
||||||
#[inline]
|
|
||||||
fn to_little_endian(self) -> u8 {
|
#[inline]
|
||||||
self.0.to_le()
|
fn to_little_endian(self) -> u8 {
|
||||||
}
|
self.0.to_le()
|
||||||
#[inline]
|
}
|
||||||
#[allow(clippy::wrong_self_convention)]
|
|
||||||
fn from_little_endian(v: u8) -> Self {
|
#[inline]
|
||||||
let b = u8::from_le(v);
|
#[allow(clippy::wrong_self_convention)]
|
||||||
Self(b)
|
fn from_little_endian(v: u8) -> Self {
|
||||||
}
|
let b = u8::from_le(v);
|
||||||
|
Self(b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ::flatbuffers::Verifiable for Equipment {
|
impl<'a> ::flatbuffers::Verifiable for Equipment {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn run_verifier(
|
fn run_verifier(
|
||||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||||
u8::run_verifier(v, pos)
|
u8::run_verifier(v, pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::flatbuffers::SimpleToVerifyInSlice for Equipment {}
|
impl ::flatbuffers::SimpleToVerifyInSlice for Equipment {}
|
||||||
|
|
||||||
pub struct EquipmentUnionTableOffset {}
|
pub struct EquipmentUnionTableOffset {}
|
||||||
|
|
||||||
#[allow(clippy::upper_case_acronyms)]
|
#[allow(clippy::upper_case_acronyms)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum EquipmentT {
|
pub enum EquipmentT {
|
||||||
NONE,
|
NONE,
|
||||||
Weapon(alloc::boxed::Box<WeaponT>),
|
Weapon(alloc::boxed::Box<WeaponT>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EquipmentT {
|
impl Default for EquipmentT {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::NONE
|
Self::NONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EquipmentT {
|
impl EquipmentT {
|
||||||
pub fn equipment_type(&self) -> Equipment {
|
pub fn equipment_type(&self) -> Equipment {
|
||||||
match self {
|
match self {
|
||||||
Self::NONE => Equipment::NONE,
|
Self::NONE => Equipment::NONE,
|
||||||
Self::Weapon(_) => Equipment::Weapon,
|
Self::Weapon(_) => Equipment::Weapon,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
pub fn pack<'b, A: ::flatbuffers::Allocator + 'b>(&self, fbb: &mut ::flatbuffers::FlatBufferBuilder<'b, A>) -> Option<::flatbuffers::WIPOffset<::flatbuffers::UnionWIPOffset>> {
|
pub fn pack<'b, A: ::flatbuffers::Allocator + 'b>(&self, fbb: &mut ::flatbuffers::FlatBufferBuilder<'b, A>) -> Option<::flatbuffers::WIPOffset<::flatbuffers::UnionWIPOffset>> {
|
||||||
match self {
|
match self {
|
||||||
Self::NONE => None,
|
Self::NONE => None,
|
||||||
Self::Weapon(v) => Some(v.pack(fbb).as_union_value()),
|
Self::Weapon(v) => Some(v.pack(fbb).as_union_value()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/// If the union variant matches, return the owned WeaponT, setting the union to NONE.
|
/// If the union variant matches, return the owned WeaponT, setting the union to NONE.
|
||||||
pub fn take_weapon(&mut self) -> Option<alloc::boxed::Box<WeaponT>> {
|
pub fn take_weapon(&mut self) -> Option<alloc::boxed::Box<WeaponT>> {
|
||||||
if let Self::Weapon(_) = self {
|
if let Self::Weapon(_) = self {
|
||||||
let v = ::core::mem::replace(self, Self::NONE);
|
let v = ::core::mem::replace(self, Self::NONE);
|
||||||
if let Self::Weapon(w) = v {
|
if let Self::Weapon(w) = v {
|
||||||
Some(w)
|
Some(w)
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the union variant matches, return a reference to the WeaponT.
|
||||||
|
pub fn as_weapon(&self) -> Option<&WeaponT> {
|
||||||
|
if let Self::Weapon(v) = self { Some(v.as_ref()) } else { None }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the union variant matches, return a mutable reference to the WeaponT.
|
||||||
|
pub fn as_weapon_mut(&mut self) -> Option<&mut WeaponT> {
|
||||||
|
if let Self::Weapon(v) = self { Some(v.as_mut()) } else { None }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/// If the union variant matches, return a reference to the WeaponT.
|
|
||||||
pub fn as_weapon(&self) -> Option<&WeaponT> {
|
|
||||||
if let Self::Weapon(v) = self { Some(v.as_ref()) } else { None }
|
|
||||||
}
|
|
||||||
/// If the union variant matches, return a mutable reference to the WeaponT.
|
|
||||||
pub fn as_weapon_mut(&mut self) -> Option<&mut WeaponT> {
|
|
||||||
if let Self::Weapon(v) = self { Some(v.as_mut()) } else { None }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,212 +2,225 @@
|
|||||||
// @generated
|
// @generated
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use super::*;
|
use super::*;
|
||||||
pub enum MonsterOffset {}
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
|
||||||
|
|
||||||
|
pub enum MonsterOffset {}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub struct Monster<'a> {
|
pub struct Monster<'a> {
|
||||||
pub _tab: ::flatbuffers::Table<'a>,
|
pub _tab: ::flatbuffers::Table<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ::flatbuffers::Follow<'a> for Monster<'a> {
|
impl<'a> ::flatbuffers::Follow<'a> for Monster<'a> {
|
||||||
type Inner = Monster<'a>;
|
type Inner = Monster<'a>;
|
||||||
#[inline]
|
|
||||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
#[inline]
|
||||||
Self { _tab: unsafe { ::flatbuffers::Table::new(buf, loc) } }
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
}
|
Self { _tab: unsafe { ::flatbuffers::Table::new(buf, loc) } }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Monster<'a> {
|
impl<'a> Monster<'a> {
|
||||||
pub const VT_POS: ::flatbuffers::VOffsetT = 4;
|
pub const VT_POS: ::flatbuffers::VOffsetT = 4;
|
||||||
pub const VT_MANA: ::flatbuffers::VOffsetT = 6;
|
pub const VT_MANA: ::flatbuffers::VOffsetT = 6;
|
||||||
pub const VT_HP: ::flatbuffers::VOffsetT = 8;
|
pub const VT_HP: ::flatbuffers::VOffsetT = 8;
|
||||||
pub const VT_NAME: ::flatbuffers::VOffsetT = 10;
|
pub const VT_NAME: ::flatbuffers::VOffsetT = 10;
|
||||||
pub const VT_INVENTORY: ::flatbuffers::VOffsetT = 14;
|
pub const VT_INVENTORY: ::flatbuffers::VOffsetT = 14;
|
||||||
pub const VT_COLOR: ::flatbuffers::VOffsetT = 16;
|
pub const VT_COLOR: ::flatbuffers::VOffsetT = 16;
|
||||||
pub const VT_WEAPONS: ::flatbuffers::VOffsetT = 18;
|
pub const VT_WEAPONS: ::flatbuffers::VOffsetT = 18;
|
||||||
pub const VT_EQUIPPED_TYPE: ::flatbuffers::VOffsetT = 20;
|
pub const VT_EQUIPPED_TYPE: ::flatbuffers::VOffsetT = 20;
|
||||||
pub const VT_EQUIPPED: ::flatbuffers::VOffsetT = 22;
|
pub const VT_EQUIPPED: ::flatbuffers::VOffsetT = 22;
|
||||||
pub const VT_PATH: ::flatbuffers::VOffsetT = 24;
|
pub const VT_PATH: ::flatbuffers::VOffsetT = 24;
|
||||||
|
|
||||||
pub const fn get_fully_qualified_name() -> &'static str {
|
pub const fn get_fully_qualified_name() -> &'static str {
|
||||||
"MyGame.Sample.Monster"
|
"MyGame.Sample.Monster"
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub unsafe fn init_from_table(table: ::flatbuffers::Table<'a>) -> Self {
|
|
||||||
Monster { _tab: table }
|
|
||||||
}
|
|
||||||
#[allow(unused_mut)]
|
|
||||||
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: ::flatbuffers::Allocator + 'bldr>(
|
|
||||||
_fbb: &'mut_bldr mut ::flatbuffers::FlatBufferBuilder<'bldr, A>,
|
|
||||||
args: &'args MonsterArgs<'args>
|
|
||||||
) -> ::flatbuffers::WIPOffset<Monster<'bldr>> {
|
|
||||||
let mut builder = MonsterBuilder::new(_fbb);
|
|
||||||
if let Some(x) = args.path { builder.add_path(x); }
|
|
||||||
if let Some(x) = args.equipped { builder.add_equipped(x); }
|
|
||||||
if let Some(x) = args.weapons { builder.add_weapons(x); }
|
|
||||||
if let Some(x) = args.inventory { builder.add_inventory(x); }
|
|
||||||
if let Some(x) = args.name { builder.add_name(x); }
|
|
||||||
if let Some(x) = args.pos { builder.add_pos(x); }
|
|
||||||
builder.add_hp(args.hp);
|
|
||||||
builder.add_mana(args.mana);
|
|
||||||
builder.add_equipped_type(args.equipped_type);
|
|
||||||
builder.add_color(args.color);
|
|
||||||
builder.finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unpack(&self) -> MonsterT {
|
|
||||||
let pos = self.pos().map(|x| {
|
|
||||||
x.unpack()
|
|
||||||
});
|
|
||||||
let mana = self.mana();
|
|
||||||
let hp = self.hp();
|
|
||||||
let name = self.name().map(|x| {
|
|
||||||
alloc::string::ToString::to_string(x)
|
|
||||||
});
|
|
||||||
let inventory = self.inventory().map(|x| {
|
|
||||||
x.into_iter().collect()
|
|
||||||
});
|
|
||||||
let color = self.color();
|
|
||||||
let weapons = self.weapons().map(|x| {
|
|
||||||
x.iter().map(|t| t.unpack()).collect()
|
|
||||||
});
|
|
||||||
let equipped = match self.equipped_type() {
|
|
||||||
Equipment::NONE => EquipmentT::NONE,
|
|
||||||
Equipment::Weapon => EquipmentT::Weapon(alloc::boxed::Box::new(
|
|
||||||
self.equipped_as_weapon()
|
|
||||||
.expect("Invalid union table, expected `Equipment::Weapon`.")
|
|
||||||
.unpack()
|
|
||||||
)),
|
|
||||||
_ => EquipmentT::NONE,
|
|
||||||
};
|
|
||||||
let path = self.path().map(|x| {
|
|
||||||
x.iter().map(|t| t.unpack()).collect()
|
|
||||||
});
|
|
||||||
MonsterT {
|
|
||||||
pos,
|
|
||||||
mana,
|
|
||||||
hp,
|
|
||||||
name,
|
|
||||||
inventory,
|
|
||||||
color,
|
|
||||||
weapons,
|
|
||||||
equipped,
|
|
||||||
path,
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn pos(&self) -> Option<&'a Vec3> {
|
pub unsafe fn init_from_table(table: ::flatbuffers::Table<'a>) -> Self {
|
||||||
// Safety:
|
Monster { _tab: table }
|
||||||
// Created from valid Table for this object
|
|
||||||
// which contains a valid value in this slot
|
|
||||||
unsafe { self._tab.get::<Vec3>(Monster::VT_POS, None)}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn mana(&self) -> i16 {
|
|
||||||
// Safety:
|
|
||||||
// Created from valid Table for this object
|
|
||||||
// which contains a valid value in this slot
|
|
||||||
unsafe { self._tab.get::<i16>(Monster::VT_MANA, Some(150)).unwrap()}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn hp(&self) -> i16 {
|
|
||||||
// Safety:
|
|
||||||
// Created from valid Table for this object
|
|
||||||
// which contains a valid value in this slot
|
|
||||||
unsafe { self._tab.get::<i16>(Monster::VT_HP, Some(100)).unwrap()}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn name(&self) -> Option<&'a str> {
|
|
||||||
// Safety:
|
|
||||||
// Created from valid Table for this object
|
|
||||||
// which contains a valid value in this slot
|
|
||||||
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<&str>>(Monster::VT_NAME, None)}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn inventory(&self) -> Option<::flatbuffers::Vector<'a, u8>> {
|
|
||||||
// Safety:
|
|
||||||
// Created from valid Table for this object
|
|
||||||
// which contains a valid value in this slot
|
|
||||||
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'a, u8>>>(Monster::VT_INVENTORY, None)}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn color(&self) -> Color {
|
|
||||||
// Safety:
|
|
||||||
// Created from valid Table for this object
|
|
||||||
// which contains a valid value in this slot
|
|
||||||
unsafe { self._tab.get::<Color>(Monster::VT_COLOR, Some(Color::Blue)).unwrap()}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn weapons(&self) -> Option<::flatbuffers::Vector<'a, ::flatbuffers::ForwardsUOffset<Weapon<'a>>>> {
|
|
||||||
// Safety:
|
|
||||||
// Created from valid Table for this object
|
|
||||||
// which contains a valid value in this slot
|
|
||||||
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'a, ::flatbuffers::ForwardsUOffset<Weapon>>>>(Monster::VT_WEAPONS, None)}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn equipped_type(&self) -> Equipment {
|
|
||||||
// Safety:
|
|
||||||
// Created from valid Table for this object
|
|
||||||
// which contains a valid value in this slot
|
|
||||||
unsafe { self._tab.get::<Equipment>(Monster::VT_EQUIPPED_TYPE, Some(Equipment::NONE)).unwrap()}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn equipped(&self) -> Option<::flatbuffers::Table<'a>> {
|
|
||||||
// Safety:
|
|
||||||
// Created from valid Table for this object
|
|
||||||
// which contains a valid value in this slot
|
|
||||||
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<::flatbuffers::Table<'a>>>(Monster::VT_EQUIPPED, None)}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn path(&self) -> Option<::flatbuffers::Vector<'a, Vec3>> {
|
|
||||||
// Safety:
|
|
||||||
// Created from valid Table for this object
|
|
||||||
// which contains a valid value in this slot
|
|
||||||
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'a, Vec3>>>(Monster::VT_PATH, None)}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub fn equipped_as_weapon(&self) -> Option<Weapon<'a>> {
|
|
||||||
if self.equipped_type() == Equipment::Weapon {
|
|
||||||
self.equipped().map(|t| {
|
|
||||||
// Safety:
|
|
||||||
// Created from a valid Table for this object
|
|
||||||
// Which contains a valid union in this slot
|
|
||||||
unsafe { Weapon::init_from_table(t) }
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: ::flatbuffers::Allocator + 'bldr>(
|
||||||
|
_fbb: &'mut_bldr mut ::flatbuffers::FlatBufferBuilder<'bldr, A>,
|
||||||
|
args: &'args MonsterArgs<'args>
|
||||||
|
) -> ::flatbuffers::WIPOffset<Monster<'bldr>> {
|
||||||
|
let mut builder = MonsterBuilder::new(_fbb);
|
||||||
|
if let Some(x) = args.path { builder.add_path(x); }
|
||||||
|
if let Some(x) = args.equipped { builder.add_equipped(x); }
|
||||||
|
if let Some(x) = args.weapons { builder.add_weapons(x); }
|
||||||
|
if let Some(x) = args.inventory { builder.add_inventory(x); }
|
||||||
|
if let Some(x) = args.name { builder.add_name(x); }
|
||||||
|
if let Some(x) = args.pos { builder.add_pos(x); }
|
||||||
|
builder.add_hp(args.hp);
|
||||||
|
builder.add_mana(args.mana);
|
||||||
|
builder.add_equipped_type(args.equipped_type);
|
||||||
|
builder.add_color(args.color);
|
||||||
|
builder.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unpack(&self) -> MonsterT {
|
||||||
|
let pos = self.pos().map(|x| {
|
||||||
|
x.unpack()
|
||||||
|
});
|
||||||
|
let mana = self.mana();
|
||||||
|
let hp = self.hp();
|
||||||
|
let name = self.name().map(|x| {
|
||||||
|
alloc::string::ToString::to_string(x)
|
||||||
|
});
|
||||||
|
let inventory = self.inventory().map(|x| {
|
||||||
|
x.into_iter().collect()
|
||||||
|
});
|
||||||
|
let color = self.color();
|
||||||
|
let weapons = self.weapons().map(|x| {
|
||||||
|
x.iter().map(|t| t.unpack()).collect()
|
||||||
|
});
|
||||||
|
let equipped = match self.equipped_type() {
|
||||||
|
Equipment::NONE => EquipmentT::NONE,
|
||||||
|
Equipment::Weapon => EquipmentT::Weapon(alloc::boxed::Box::new(
|
||||||
|
self.equipped_as_weapon()
|
||||||
|
.expect("Invalid union table, expected `Equipment::Weapon`.")
|
||||||
|
.unpack()
|
||||||
|
)),
|
||||||
|
_ => EquipmentT::NONE,
|
||||||
|
};
|
||||||
|
let path = self.path().map(|x| {
|
||||||
|
x.iter().map(|t| t.unpack()).collect()
|
||||||
|
});
|
||||||
|
MonsterT {
|
||||||
|
pos,
|
||||||
|
mana,
|
||||||
|
hp,
|
||||||
|
name,
|
||||||
|
inventory,
|
||||||
|
color,
|
||||||
|
weapons,
|
||||||
|
equipped,
|
||||||
|
path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn pos(&self) -> Option<&'a Vec3> {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<Vec3>(Monster::VT_POS, None)}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn mana(&self) -> i16 {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<i16>(Monster::VT_MANA, Some(150)).unwrap()}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn hp(&self) -> i16 {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<i16>(Monster::VT_HP, Some(100)).unwrap()}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn name(&self) -> Option<&'a str> {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<&str>>(Monster::VT_NAME, None)}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn inventory(&self) -> Option<::flatbuffers::Vector<'a, u8>> {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'a, u8>>>(Monster::VT_INVENTORY, None)}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn color(&self) -> Color {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<Color>(Monster::VT_COLOR, Some(Color::Blue)).unwrap()}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn weapons(&self) -> Option<::flatbuffers::Vector<'a, ::flatbuffers::ForwardsUOffset<Weapon<'a>>>> {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'a, ::flatbuffers::ForwardsUOffset<Weapon>>>>(Monster::VT_WEAPONS, None)}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn equipped_type(&self) -> Equipment {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<Equipment>(Monster::VT_EQUIPPED_TYPE, Some(Equipment::NONE)).unwrap()}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn equipped(&self) -> Option<::flatbuffers::Table<'a>> {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<::flatbuffers::Table<'a>>>(Monster::VT_EQUIPPED, None)}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn path(&self) -> Option<::flatbuffers::Vector<'a, Vec3>> {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'a, Vec3>>>(Monster::VT_PATH, None)}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
pub fn equipped_as_weapon(&self) -> Option<Weapon<'a>> {
|
||||||
|
if self.equipped_type() == Equipment::Weapon {
|
||||||
|
self.equipped().map(|t| {
|
||||||
|
// Safety:
|
||||||
|
// Created from a valid Table for this object
|
||||||
|
// Which contains a valid union in this slot
|
||||||
|
unsafe { Weapon::init_from_table(t) }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::flatbuffers::Verifiable for Monster<'_> {
|
impl ::flatbuffers::Verifiable for Monster<'_> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn run_verifier(
|
fn run_verifier(
|
||||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||||
v.visit_table(pos)?
|
v.visit_table(pos)?
|
||||||
.visit_field::<Vec3>("pos", Self::VT_POS, false)?
|
.visit_field::<Vec3>("pos", Self::VT_POS, false)?
|
||||||
.visit_field::<i16>("mana", Self::VT_MANA, false)?
|
.visit_field::<i16>("mana", Self::VT_MANA, false)?
|
||||||
.visit_field::<i16>("hp", Self::VT_HP, false)?
|
.visit_field::<i16>("hp", Self::VT_HP, false)?
|
||||||
.visit_field::<::flatbuffers::ForwardsUOffset<&str>>("name", Self::VT_NAME, false)?
|
.visit_field::<::flatbuffers::ForwardsUOffset<&str>>("name", Self::VT_NAME, false)?
|
||||||
.visit_field::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'_, u8>>>("inventory", Self::VT_INVENTORY, false)?
|
.visit_field::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'_, u8>>>("inventory", Self::VT_INVENTORY, false)?
|
||||||
.visit_field::<Color>("color", Self::VT_COLOR, false)?
|
.visit_field::<Color>("color", Self::VT_COLOR, false)?
|
||||||
.visit_field::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'_, ::flatbuffers::ForwardsUOffset<Weapon>>>>("weapons", Self::VT_WEAPONS, false)?
|
.visit_field::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'_, ::flatbuffers::ForwardsUOffset<Weapon>>>>("weapons", Self::VT_WEAPONS, false)?
|
||||||
.visit_union::<Equipment, _>("equipped_type", Self::VT_EQUIPPED_TYPE, "equipped", Self::VT_EQUIPPED, false, |key, v, pos| {
|
.visit_union::<Equipment, _>("equipped_type", Self::VT_EQUIPPED_TYPE, "equipped", Self::VT_EQUIPPED, false, |key, v, pos| {
|
||||||
match key {
|
match key {
|
||||||
Equipment::Weapon => v.verify_union_variant::<::flatbuffers::ForwardsUOffset<Weapon>>("Equipment::Weapon", pos),
|
Equipment::Weapon => v.verify_union_variant::<::flatbuffers::ForwardsUOffset<Weapon>>("Equipment::Weapon", pos),
|
||||||
_ => Ok(()),
|
_ => Ok(()),
|
||||||
}
|
}
|
||||||
})?
|
})?
|
||||||
.visit_field::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'_, Vec3>>>("path", Self::VT_PATH, false)?
|
.visit_field::<::flatbuffers::ForwardsUOffset<::flatbuffers::Vector<'_, Vec3>>>("path", Self::VT_PATH, false)?
|
||||||
.finish();
|
.finish();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MonsterArgs<'a> {
|
pub struct MonsterArgs<'a> {
|
||||||
pub pos: Option<&'a Vec3>,
|
pub pos: Option<&'a Vec3>,
|
||||||
pub mana: i16,
|
pub mana: i16,
|
||||||
@@ -220,246 +233,273 @@ pub struct MonsterArgs<'a> {
|
|||||||
pub equipped: Option<::flatbuffers::WIPOffset<::flatbuffers::UnionWIPOffset>>,
|
pub equipped: Option<::flatbuffers::WIPOffset<::flatbuffers::UnionWIPOffset>>,
|
||||||
pub path: Option<::flatbuffers::WIPOffset<::flatbuffers::Vector<'a, Vec3>>>,
|
pub path: Option<::flatbuffers::WIPOffset<::flatbuffers::Vector<'a, Vec3>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Default for MonsterArgs<'a> {
|
impl<'a> Default for MonsterArgs<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
MonsterArgs {
|
MonsterArgs {
|
||||||
pos: None,
|
pos: None,
|
||||||
mana: 150,
|
mana: 150,
|
||||||
hp: 100,
|
hp: 100,
|
||||||
name: None,
|
name: None,
|
||||||
inventory: None,
|
inventory: None,
|
||||||
color: Color::Blue,
|
color: Color::Blue,
|
||||||
weapons: None,
|
weapons: None,
|
||||||
equipped_type: Equipment::NONE,
|
equipped_type: Equipment::NONE,
|
||||||
equipped: None,
|
equipped: None,
|
||||||
path: None,
|
path: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MonsterBuilder<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> {
|
pub struct MonsterBuilder<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> {
|
||||||
fbb_: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
fbb_: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
||||||
start_: ::flatbuffers::WIPOffset<::flatbuffers::TableUnfinishedWIPOffset>,
|
start_: ::flatbuffers::WIPOffset<::flatbuffers::TableUnfinishedWIPOffset>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> MonsterBuilder<'a, 'b, A> {
|
impl<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> MonsterBuilder<'a, 'b, A> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn add_pos(&mut self, pos: &Vec3) {
|
pub fn add_pos(&mut self, pos: &Vec3) {
|
||||||
self.fbb_.push_slot_always::<&Vec3>(Monster::VT_POS, pos);
|
self.fbb_.push_slot_always::<&Vec3>(Monster::VT_POS, pos);
|
||||||
}
|
}
|
||||||
#[inline]
|
|
||||||
pub fn add_mana(&mut self, mana: i16) {
|
#[inline]
|
||||||
self.fbb_.push_slot::<i16>(Monster::VT_MANA, mana, 150);
|
pub fn add_mana(&mut self, mana: i16) {
|
||||||
}
|
self.fbb_.push_slot::<i16>(Monster::VT_MANA, mana, 150);
|
||||||
#[inline]
|
}
|
||||||
pub fn add_hp(&mut self, hp: i16) {
|
|
||||||
self.fbb_.push_slot::<i16>(Monster::VT_HP, hp, 100);
|
#[inline]
|
||||||
}
|
pub fn add_hp(&mut self, hp: i16) {
|
||||||
#[inline]
|
self.fbb_.push_slot::<i16>(Monster::VT_HP, hp, 100);
|
||||||
pub fn add_name(&mut self, name: ::flatbuffers::WIPOffset<&'b str>) {
|
}
|
||||||
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Monster::VT_NAME, name);
|
|
||||||
}
|
#[inline]
|
||||||
#[inline]
|
pub fn add_name(&mut self, name: ::flatbuffers::WIPOffset<&'b str>) {
|
||||||
pub fn add_inventory(&mut self, inventory: ::flatbuffers::WIPOffset<::flatbuffers::Vector<'b , u8>>) {
|
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Monster::VT_NAME, name);
|
||||||
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Monster::VT_INVENTORY, inventory);
|
}
|
||||||
}
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn add_color(&mut self, color: Color) {
|
pub fn add_inventory(&mut self, inventory: ::flatbuffers::WIPOffset<::flatbuffers::Vector<'b , u8>>) {
|
||||||
self.fbb_.push_slot::<Color>(Monster::VT_COLOR, color, Color::Blue);
|
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Monster::VT_INVENTORY, inventory);
|
||||||
}
|
}
|
||||||
#[inline]
|
|
||||||
pub fn add_weapons(&mut self, weapons: ::flatbuffers::WIPOffset<::flatbuffers::Vector<'b , ::flatbuffers::ForwardsUOffset<Weapon<'b >>>>) {
|
#[inline]
|
||||||
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Monster::VT_WEAPONS, weapons);
|
pub fn add_color(&mut self, color: Color) {
|
||||||
}
|
self.fbb_.push_slot::<Color>(Monster::VT_COLOR, color, Color::Blue);
|
||||||
#[inline]
|
}
|
||||||
pub fn add_equipped_type(&mut self, equipped_type: Equipment) {
|
|
||||||
self.fbb_.push_slot::<Equipment>(Monster::VT_EQUIPPED_TYPE, equipped_type, Equipment::NONE);
|
#[inline]
|
||||||
}
|
pub fn add_weapons(&mut self, weapons: ::flatbuffers::WIPOffset<::flatbuffers::Vector<'b , ::flatbuffers::ForwardsUOffset<Weapon<'b >>>>) {
|
||||||
#[inline]
|
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Monster::VT_WEAPONS, weapons);
|
||||||
pub fn add_equipped(&mut self, equipped: ::flatbuffers::WIPOffset<::flatbuffers::UnionWIPOffset>) {
|
}
|
||||||
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Monster::VT_EQUIPPED, equipped);
|
|
||||||
}
|
#[inline]
|
||||||
#[inline]
|
pub fn add_equipped_type(&mut self, equipped_type: Equipment) {
|
||||||
pub fn add_path(&mut self, path: ::flatbuffers::WIPOffset<::flatbuffers::Vector<'b , Vec3>>) {
|
self.fbb_.push_slot::<Equipment>(Monster::VT_EQUIPPED_TYPE, equipped_type, Equipment::NONE);
|
||||||
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Monster::VT_PATH, path);
|
}
|
||||||
}
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(_fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>) -> MonsterBuilder<'a, 'b, A> {
|
pub fn add_equipped(&mut self, equipped: ::flatbuffers::WIPOffset<::flatbuffers::UnionWIPOffset>) {
|
||||||
let start = _fbb.start_table();
|
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Monster::VT_EQUIPPED, equipped);
|
||||||
MonsterBuilder {
|
}
|
||||||
fbb_: _fbb,
|
|
||||||
start_: start,
|
#[inline]
|
||||||
|
pub fn add_path(&mut self, path: ::flatbuffers::WIPOffset<::flatbuffers::Vector<'b , Vec3>>) {
|
||||||
|
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Monster::VT_PATH, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn new(_fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>) -> MonsterBuilder<'a, 'b, A> {
|
||||||
|
let start = _fbb.start_table();
|
||||||
|
MonsterBuilder {
|
||||||
|
fbb_: _fbb,
|
||||||
|
start_: start,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn finish(self) -> ::flatbuffers::WIPOffset<Monster<'a>> {
|
||||||
|
let o = self.fbb_.end_table(self.start_);
|
||||||
|
::flatbuffers::WIPOffset::new(o.value())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn finish(self) -> ::flatbuffers::WIPOffset<Monster<'a>> {
|
|
||||||
let o = self.fbb_.end_table(self.start_);
|
|
||||||
::flatbuffers::WIPOffset::new(o.value())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::core::fmt::Debug for Monster<'_> {
|
impl ::core::fmt::Debug for Monster<'_> {
|
||||||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
||||||
let mut ds = f.debug_struct("Monster");
|
let mut ds = f.debug_struct("Monster");
|
||||||
ds.field("pos", &self.pos());
|
ds.field("pos", &self.pos());
|
||||||
ds.field("mana", &self.mana());
|
ds.field("mana", &self.mana());
|
||||||
ds.field("hp", &self.hp());
|
ds.field("hp", &self.hp());
|
||||||
ds.field("name", &self.name());
|
ds.field("name", &self.name());
|
||||||
ds.field("inventory", &self.inventory());
|
ds.field("inventory", &self.inventory());
|
||||||
ds.field("color", &self.color());
|
ds.field("color", &self.color());
|
||||||
ds.field("weapons", &self.weapons());
|
ds.field("weapons", &self.weapons());
|
||||||
ds.field("equipped_type", &self.equipped_type());
|
ds.field("equipped_type", &self.equipped_type());
|
||||||
match self.equipped_type() {
|
match self.equipped_type() {
|
||||||
Equipment::Weapon => {
|
Equipment::Weapon => {
|
||||||
if let Some(x) = self.equipped_as_weapon() {
|
if let Some(x) = self.equipped_as_weapon() {
|
||||||
ds.field("equipped", &x)
|
ds.field("equipped", &x)
|
||||||
} else {
|
} else {
|
||||||
ds.field("equipped", &"InvalidFlatbuffer: Union discriminant does not match value.")
|
ds.field("equipped", &"InvalidFlatbuffer: Union discriminant does not match value.")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
let x: Option<()> = None;
|
let x: Option<()> = None;
|
||||||
ds.field("equipped", &x)
|
ds.field("equipped", &x)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
ds.field("path", &self.path());
|
ds.field("path", &self.path());
|
||||||
ds.finish()
|
ds.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct MonsterT {
|
pub struct MonsterT {
|
||||||
pub pos: Option<Vec3T>,
|
pub pos: Option<Vec3T>,
|
||||||
pub mana: i16,
|
pub mana: i16,
|
||||||
pub hp: i16,
|
pub hp: i16,
|
||||||
pub name: Option<alloc::string::String>,
|
pub name: Option<alloc::string::String>,
|
||||||
pub inventory: Option<alloc::vec::Vec<u8>>,
|
pub inventory: Option<alloc::vec::Vec<u8>>,
|
||||||
pub color: Color,
|
pub color: Color,
|
||||||
pub weapons: Option<alloc::vec::Vec<WeaponT>>,
|
pub weapons: Option<alloc::vec::Vec<WeaponT>>,
|
||||||
pub equipped: EquipmentT,
|
pub equipped: EquipmentT,
|
||||||
pub path: Option<alloc::vec::Vec<Vec3T>>,
|
pub path: Option<alloc::vec::Vec<Vec3T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MonsterT {
|
impl Default for MonsterT {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
pos: None,
|
pos: None,
|
||||||
mana: 150,
|
mana: 150,
|
||||||
hp: 100,
|
hp: 100,
|
||||||
name: None,
|
name: None,
|
||||||
inventory: None,
|
inventory: None,
|
||||||
color: Color::Blue,
|
color: Color::Blue,
|
||||||
weapons: None,
|
weapons: None,
|
||||||
equipped: EquipmentT::NONE,
|
equipped: EquipmentT::NONE,
|
||||||
path: None,
|
path: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MonsterT {
|
impl MonsterT {
|
||||||
pub fn pack<'b, A: ::flatbuffers::Allocator + 'b>(
|
pub fn pack<'b, A: ::flatbuffers::Allocator + 'b>(
|
||||||
&self,
|
&self,
|
||||||
_fbb: &mut ::flatbuffers::FlatBufferBuilder<'b, A>
|
_fbb: &mut ::flatbuffers::FlatBufferBuilder<'b, A>
|
||||||
) -> ::flatbuffers::WIPOffset<Monster<'b>> {
|
) -> ::flatbuffers::WIPOffset<Monster<'b>> {
|
||||||
let pos_tmp = self.pos.as_ref().map(|x| x.pack());
|
let pos_tmp = self.pos.as_ref().map(|x| x.pack());
|
||||||
let pos = pos_tmp.as_ref();
|
let pos = pos_tmp.as_ref();
|
||||||
let mana = self.mana;
|
let mana = self.mana;
|
||||||
let hp = self.hp;
|
let hp = self.hp;
|
||||||
let name = self.name.as_ref().map(|x|{
|
let name = self.name.as_ref().map(|x|{
|
||||||
_fbb.create_string(x)
|
_fbb.create_string(x)
|
||||||
});
|
});
|
||||||
let inventory = self.inventory.as_ref().map(|x|{
|
let inventory = self.inventory.as_ref().map(|x|{
|
||||||
_fbb.create_vector(x)
|
_fbb.create_vector(x)
|
||||||
});
|
});
|
||||||
let color = self.color;
|
let color = self.color;
|
||||||
let weapons = self.weapons.as_ref().map(|x|{
|
let weapons = self.weapons.as_ref().map(|x|{
|
||||||
let w: alloc::vec::Vec<_> = x.iter().map(|t| t.pack(_fbb)).collect();_fbb.create_vector(&w)
|
let w: alloc::vec::Vec<_> = x.iter().map(|t| t.pack(_fbb)).collect();_fbb.create_vector(&w)
|
||||||
});
|
});
|
||||||
let equipped_type = self.equipped.equipment_type();
|
let equipped_type = self.equipped.equipment_type();
|
||||||
let equipped = self.equipped.pack(_fbb);
|
let equipped = self.equipped.pack(_fbb);
|
||||||
let path = self.path.as_ref().map(|x|{
|
let path = self.path.as_ref().map(|x|{
|
||||||
let w: alloc::vec::Vec<_> = x.iter().map(|t| t.pack()).collect();_fbb.create_vector(&w)
|
let w: alloc::vec::Vec<_> = x.iter().map(|t| t.pack()).collect();_fbb.create_vector(&w)
|
||||||
});
|
});
|
||||||
Monster::create(_fbb, &MonsterArgs{
|
Monster::create(_fbb, &MonsterArgs{
|
||||||
pos,
|
pos,
|
||||||
mana,
|
mana,
|
||||||
hp,
|
hp,
|
||||||
name,
|
name,
|
||||||
inventory,
|
inventory,
|
||||||
color,
|
color,
|
||||||
weapons,
|
weapons,
|
||||||
equipped_type,
|
equipped_type,
|
||||||
equipped,
|
equipped,
|
||||||
path,
|
path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
|
||||||
/// Verifies that a buffer of bytes contains a `Monster`
|
/// Verifies that a buffer of bytes contains a `Monster`
|
||||||
/// and returns it.
|
/// and returns it.
|
||||||
/// Note that verification is still experimental and may not
|
/// Note that verification is still experimental and may not
|
||||||
/// catch every error, or be maximally performant. For the
|
/// catch every error, or be maximally performant. For the
|
||||||
/// previous, unchecked, behavior use
|
/// previous, unchecked, behavior use
|
||||||
/// `root_as_monster_unchecked`.
|
/// `root_as_monster_unchecked`.
|
||||||
pub fn root_as_monster(buf: &[u8]) -> Result<Monster<'_>, ::flatbuffers::InvalidFlatbuffer> {
|
|
||||||
::flatbuffers::root::<Monster>(buf)
|
|
||||||
}
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn root_as_monster(buf: &[u8]) -> Result<Monster<'_>, ::flatbuffers::InvalidFlatbuffer> {
|
||||||
|
::flatbuffers::root::<Monster>(buf)
|
||||||
|
}
|
||||||
|
|
||||||
/// Verifies that a buffer of bytes contains a size prefixed
|
/// Verifies that a buffer of bytes contains a size prefixed
|
||||||
/// `Monster` and returns it.
|
/// `Monster` and returns it.
|
||||||
/// Note that verification is still experimental and may not
|
/// Note that verification is still experimental and may not
|
||||||
/// catch every error, or be maximally performant. For the
|
/// catch every error, or be maximally performant. For the
|
||||||
/// previous, unchecked, behavior use
|
/// previous, unchecked, behavior use
|
||||||
/// `size_prefixed_root_as_monster_unchecked`.
|
/// `size_prefixed_root_as_monster_unchecked`.
|
||||||
pub fn size_prefixed_root_as_monster(buf: &[u8]) -> Result<Monster<'_>, ::flatbuffers::InvalidFlatbuffer> {
|
|
||||||
::flatbuffers::size_prefixed_root::<Monster>(buf)
|
|
||||||
}
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn size_prefixed_root_as_monster(buf: &[u8]) -> Result<Monster<'_>, ::flatbuffers::InvalidFlatbuffer> {
|
||||||
|
::flatbuffers::size_prefixed_root::<Monster>(buf)
|
||||||
|
}
|
||||||
|
|
||||||
/// Verifies, with the given options, that a buffer of bytes
|
/// Verifies, with the given options, that a buffer of bytes
|
||||||
/// contains a `Monster` and returns it.
|
/// contains a `Monster` and returns it.
|
||||||
/// Note that verification is still experimental and may not
|
/// Note that verification is still experimental and may not
|
||||||
/// catch every error, or be maximally performant. For the
|
/// catch every error, or be maximally performant. For the
|
||||||
/// previous, unchecked, behavior use
|
/// previous, unchecked, behavior use
|
||||||
/// `root_as_monster_unchecked`.
|
/// `root_as_monster_unchecked`.
|
||||||
pub fn root_as_monster_with_opts<'b, 'o>(
|
|
||||||
opts: &'o ::flatbuffers::VerifierOptions,
|
|
||||||
buf: &'b [u8],
|
|
||||||
) -> Result<Monster<'b>, ::flatbuffers::InvalidFlatbuffer> {
|
|
||||||
::flatbuffers::root_with_opts::<Monster<'b>>(opts, buf)
|
|
||||||
}
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn root_as_monster_with_opts<'b, 'o>(
|
||||||
|
opts: &'o ::flatbuffers::VerifierOptions,
|
||||||
|
buf: &'b [u8],
|
||||||
|
) -> Result<Monster<'b>, ::flatbuffers::InvalidFlatbuffer> {
|
||||||
|
::flatbuffers::root_with_opts::<Monster<'b>>(opts, buf)
|
||||||
|
}
|
||||||
|
|
||||||
/// Verifies, with the given verifier options, that a buffer of
|
/// Verifies, with the given verifier options, that a buffer of
|
||||||
/// bytes contains a size prefixed `Monster` and returns
|
/// bytes contains a size prefixed `Monster` and returns
|
||||||
/// it. Note that verification is still experimental and may not
|
/// it. Note that verification is still experimental and may not
|
||||||
/// catch every error, or be maximally performant. For the
|
/// catch every error, or be maximally performant. For the
|
||||||
/// previous, unchecked, behavior use
|
/// previous, unchecked, behavior use
|
||||||
/// `root_as_monster_unchecked`.
|
/// `root_as_monster_unchecked`.
|
||||||
pub fn size_prefixed_root_as_monster_with_opts<'b, 'o>(
|
|
||||||
opts: &'o ::flatbuffers::VerifierOptions,
|
|
||||||
buf: &'b [u8],
|
|
||||||
) -> Result<Monster<'b>, ::flatbuffers::InvalidFlatbuffer> {
|
|
||||||
::flatbuffers::size_prefixed_root_with_opts::<Monster<'b>>(opts, buf)
|
|
||||||
}
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub fn size_prefixed_root_as_monster_with_opts<'b, 'o>(
|
||||||
|
opts: &'o ::flatbuffers::VerifierOptions,
|
||||||
|
buf: &'b [u8],
|
||||||
|
) -> Result<Monster<'b>, ::flatbuffers::InvalidFlatbuffer> {
|
||||||
|
::flatbuffers::size_prefixed_root_with_opts::<Monster<'b>>(opts, buf)
|
||||||
|
}
|
||||||
|
|
||||||
/// Assumes, without verification, that a buffer of bytes contains a Monster and returns it.
|
/// Assumes, without verification, that a buffer of bytes contains a Monster and returns it.
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// Callers must trust the given bytes do indeed contain a valid `Monster`.
|
/// Callers must trust the given bytes do indeed contain a valid `Monster`.
|
||||||
pub unsafe fn root_as_monster_unchecked(buf: &[u8]) -> Monster<'_> {
|
|
||||||
unsafe { ::flatbuffers::root_unchecked::<Monster>(buf) }
|
|
||||||
}
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
pub unsafe fn root_as_monster_unchecked(buf: &[u8]) -> Monster<'_> {
|
||||||
|
unsafe { ::flatbuffers::root_unchecked::<Monster>(buf) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Assumes, without verification, that a buffer of bytes contains a size prefixed Monster and returns it.
|
/// Assumes, without verification, that a buffer of bytes contains a size prefixed Monster and returns it.
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// Callers must trust the given bytes do indeed contain a valid size prefixed `Monster`.
|
/// Callers must trust the given bytes do indeed contain a valid size prefixed `Monster`.
|
||||||
pub unsafe fn size_prefixed_root_as_monster_unchecked(buf: &[u8]) -> Monster<'_> {
|
|
||||||
unsafe { ::flatbuffers::size_prefixed_root_unchecked::<Monster>(buf) }
|
|
||||||
}
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn finish_monster_buffer<'a, 'b, A: ::flatbuffers::Allocator + 'a>(
|
pub unsafe fn size_prefixed_root_as_monster_unchecked(buf: &[u8]) -> Monster<'_> {
|
||||||
fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
unsafe { ::flatbuffers::size_prefixed_root_unchecked::<Monster>(buf) }
|
||||||
root: ::flatbuffers::WIPOffset<Monster<'a>>) {
|
|
||||||
fbb.finish(root, None);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn finish_size_prefixed_monster_buffer<'a, 'b, A: ::flatbuffers::Allocator + 'a>(fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>, root: ::flatbuffers::WIPOffset<Monster<'a>>) {
|
pub fn finish_monster_buffer<'a, 'b, A: ::flatbuffers::Allocator + 'a>(
|
||||||
fbb.finish_size_prefixed(root, None);
|
fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
||||||
|
root: ::flatbuffers::WIPOffset<Monster<'a>>
|
||||||
|
) {
|
||||||
|
fbb.finish(root, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn finish_size_prefixed_monster_buffer<'a, 'b, A: ::flatbuffers::Allocator + 'a>(
|
||||||
|
fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
||||||
|
root: ::flatbuffers::WIPOffset<Monster<'a>>
|
||||||
|
) {
|
||||||
|
fbb.finish_size_prefixed(root, None);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,47 +2,57 @@
|
|||||||
// @generated
|
// @generated
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
// struct Vec3, aligned to 4
|
// struct Vec3, aligned to 4
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub struct Vec3(pub [u8; 12]);
|
pub struct Vec3(pub [u8; 12]);
|
||||||
impl Default for Vec3 {
|
|
||||||
fn default() -> Self {
|
impl Default for Vec3 {
|
||||||
Self([0; 12])
|
fn default() -> Self {
|
||||||
}
|
Self([0; 12])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::core::fmt::Debug for Vec3 {
|
impl ::core::fmt::Debug for Vec3 {
|
||||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||||
f.debug_struct("Vec3")
|
f.debug_struct("Vec3")
|
||||||
.field("x", &self.x())
|
.field("x", &self.x())
|
||||||
.field("y", &self.y())
|
.field("y", &self.y())
|
||||||
.field("z", &self.z())
|
.field("z", &self.z())
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::flatbuffers::SimpleToVerifyInSlice for Vec3 {}
|
impl ::flatbuffers::SimpleToVerifyInSlice for Vec3 {}
|
||||||
|
|
||||||
impl<'a> ::flatbuffers::Follow<'a> for Vec3 {
|
impl<'a> ::flatbuffers::Follow<'a> for Vec3 {
|
||||||
type Inner = &'a Vec3;
|
type Inner = &'a Vec3;
|
||||||
#[inline]
|
|
||||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
#[inline]
|
||||||
unsafe { <&'a Vec3>::follow(buf, loc) }
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
}
|
unsafe { <&'a Vec3>::follow(buf, loc) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ::flatbuffers::Follow<'a> for &'a Vec3 {
|
impl<'a> ::flatbuffers::Follow<'a> for &'a Vec3 {
|
||||||
type Inner = &'a Vec3;
|
type Inner = &'a Vec3;
|
||||||
#[inline]
|
|
||||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
#[inline]
|
||||||
unsafe { ::flatbuffers::follow_cast_ref::<Vec3>(buf, loc) }
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
}
|
unsafe { ::flatbuffers::follow_cast_ref::<Vec3>(buf, loc) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b> ::flatbuffers::Push for Vec3 {
|
impl<'b> ::flatbuffers::Push for Vec3 {
|
||||||
type Output = Vec3;
|
type Output = Vec3;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||||
let src = unsafe { ::core::slice::from_raw_parts(self as *const Vec3 as *const u8, <Self as ::flatbuffers::Push>::size()) };
|
let src = unsafe { ::core::slice::from_raw_parts(self as *const Vec3 as *const u8, <Self as ::flatbuffers::Push>::size()) };
|
||||||
dst.copy_from_slice(src);
|
dst.copy_from_slice(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn alignment() -> ::flatbuffers::PushAlignment {
|
fn alignment() -> ::flatbuffers::PushAlignment {
|
||||||
::flatbuffers::PushAlignment::new(4)
|
::flatbuffers::PushAlignment::new(4)
|
||||||
@@ -50,141 +60,150 @@ impl<'b> ::flatbuffers::Push for Vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ::flatbuffers::Verifiable for Vec3 {
|
impl<'a> ::flatbuffers::Verifiable for Vec3 {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn run_verifier(
|
fn run_verifier(
|
||||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||||
v.in_buffer::<Self>(pos)
|
v.in_buffer::<Self>(pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Vec3 {
|
impl<'a> Vec3 {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
x: f32,
|
x: f32,
|
||||||
y: f32,
|
y: f32,
|
||||||
z: f32,
|
z: f32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut s = Self([0; 12]);
|
let mut s = Self([0; 12]);
|
||||||
s.set_x(x);
|
s.set_x(x);
|
||||||
s.set_y(y);
|
s.set_y(y);
|
||||||
s.set_z(z);
|
s.set_z(z);
|
||||||
s
|
s
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn get_fully_qualified_name() -> &'static str {
|
|
||||||
"MyGame.Sample.Vec3"
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn x(&self) -> f32 {
|
|
||||||
let mut mem = ::core::mem::MaybeUninit::<<f32 as ::flatbuffers::EndianScalar>::Scalar>::uninit();
|
|
||||||
// Safety:
|
|
||||||
// Created from a valid Table for this object
|
|
||||||
// Which contains a valid value in this slot
|
|
||||||
::flatbuffers::EndianScalar::from_little_endian(unsafe {
|
|
||||||
::core::ptr::copy_nonoverlapping(
|
|
||||||
self.0[0..].as_ptr(),
|
|
||||||
mem.as_mut_ptr() as *mut u8,
|
|
||||||
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
|
||||||
);
|
|
||||||
mem.assume_init()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_x(&mut self, x: f32) {
|
|
||||||
let x_le = ::flatbuffers::EndianScalar::to_little_endian(x);
|
|
||||||
// Safety:
|
|
||||||
// Created from a valid Table for this object
|
|
||||||
// Which contains a valid value in this slot
|
|
||||||
unsafe {
|
|
||||||
::core::ptr::copy_nonoverlapping(
|
|
||||||
&x_le as *const _ as *const u8,
|
|
||||||
self.0[0..].as_mut_ptr(),
|
|
||||||
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn y(&self) -> f32 {
|
pub const fn get_fully_qualified_name() -> &'static str {
|
||||||
let mut mem = ::core::mem::MaybeUninit::<<f32 as ::flatbuffers::EndianScalar>::Scalar>::uninit();
|
"MyGame.Sample.Vec3"
|
||||||
// Safety:
|
|
||||||
// Created from a valid Table for this object
|
|
||||||
// Which contains a valid value in this slot
|
|
||||||
::flatbuffers::EndianScalar::from_little_endian(unsafe {
|
|
||||||
::core::ptr::copy_nonoverlapping(
|
|
||||||
self.0[4..].as_ptr(),
|
|
||||||
mem.as_mut_ptr() as *mut u8,
|
|
||||||
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
|
||||||
);
|
|
||||||
mem.assume_init()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_y(&mut self, x: f32) {
|
|
||||||
let x_le = ::flatbuffers::EndianScalar::to_little_endian(x);
|
|
||||||
// Safety:
|
|
||||||
// Created from a valid Table for this object
|
|
||||||
// Which contains a valid value in this slot
|
|
||||||
unsafe {
|
|
||||||
::core::ptr::copy_nonoverlapping(
|
|
||||||
&x_le as *const _ as *const u8,
|
|
||||||
self.0[4..].as_mut_ptr(),
|
|
||||||
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn z(&self) -> f32 {
|
pub fn x(&self) -> f32 {
|
||||||
let mut mem = ::core::mem::MaybeUninit::<<f32 as ::flatbuffers::EndianScalar>::Scalar>::uninit();
|
let mut mem = ::core::mem::MaybeUninit::<<f32 as ::flatbuffers::EndianScalar>::Scalar>::uninit();
|
||||||
// Safety:
|
// Safety:
|
||||||
// Created from a valid Table for this object
|
// Created from a valid Table for this object
|
||||||
// Which contains a valid value in this slot
|
// Which contains a valid value in this slot
|
||||||
::flatbuffers::EndianScalar::from_little_endian(unsafe {
|
::flatbuffers::EndianScalar::from_little_endian(unsafe {
|
||||||
::core::ptr::copy_nonoverlapping(
|
::core::ptr::copy_nonoverlapping(
|
||||||
self.0[8..].as_ptr(),
|
self.0[0..].as_ptr(),
|
||||||
mem.as_mut_ptr() as *mut u8,
|
mem.as_mut_ptr() as *mut u8,
|
||||||
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||||
);
|
);
|
||||||
mem.assume_init()
|
mem.assume_init()
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_z(&mut self, x: f32) {
|
|
||||||
let x_le = ::flatbuffers::EndianScalar::to_little_endian(x);
|
|
||||||
// Safety:
|
|
||||||
// Created from a valid Table for this object
|
|
||||||
// Which contains a valid value in this slot
|
|
||||||
unsafe {
|
|
||||||
::core::ptr::copy_nonoverlapping(
|
|
||||||
&x_le as *const _ as *const u8,
|
|
||||||
self.0[8..].as_mut_ptr(),
|
|
||||||
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unpack(&self) -> Vec3T {
|
pub fn set_x(&mut self, x: f32) {
|
||||||
Vec3T {
|
let x_le = ::flatbuffers::EndianScalar::to_little_endian(x);
|
||||||
x: self.x(),
|
// Safety:
|
||||||
y: self.y(),
|
// Created from a valid Table for this object
|
||||||
z: self.z(),
|
// Which contains a valid value in this slot
|
||||||
|
unsafe {
|
||||||
|
::core::ptr::copy_nonoverlapping(
|
||||||
|
&x_le as *const _ as *const u8,
|
||||||
|
self.0[0..].as_mut_ptr(),
|
||||||
|
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn y(&self) -> f32 {
|
||||||
|
let mut mem = ::core::mem::MaybeUninit::<<f32 as ::flatbuffers::EndianScalar>::Scalar>::uninit();
|
||||||
|
// Safety:
|
||||||
|
// Created from a valid Table for this object
|
||||||
|
// Which contains a valid value in this slot
|
||||||
|
::flatbuffers::EndianScalar::from_little_endian(unsafe {
|
||||||
|
::core::ptr::copy_nonoverlapping(
|
||||||
|
self.0[4..].as_ptr(),
|
||||||
|
mem.as_mut_ptr() as *mut u8,
|
||||||
|
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||||
|
);
|
||||||
|
mem.assume_init()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_y(&mut self, x: f32) {
|
||||||
|
let x_le = ::flatbuffers::EndianScalar::to_little_endian(x);
|
||||||
|
// Safety:
|
||||||
|
// Created from a valid Table for this object
|
||||||
|
// Which contains a valid value in this slot
|
||||||
|
unsafe {
|
||||||
|
::core::ptr::copy_nonoverlapping(
|
||||||
|
&x_le as *const _ as *const u8,
|
||||||
|
self.0[4..].as_mut_ptr(),
|
||||||
|
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn z(&self) -> f32 {
|
||||||
|
let mut mem = ::core::mem::MaybeUninit::<<f32 as ::flatbuffers::EndianScalar>::Scalar>::uninit();
|
||||||
|
// Safety:
|
||||||
|
// Created from a valid Table for this object
|
||||||
|
// Which contains a valid value in this slot
|
||||||
|
::flatbuffers::EndianScalar::from_little_endian(unsafe {
|
||||||
|
::core::ptr::copy_nonoverlapping(
|
||||||
|
self.0[8..].as_ptr(),
|
||||||
|
mem.as_mut_ptr() as *mut u8,
|
||||||
|
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||||
|
);
|
||||||
|
mem.assume_init()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_z(&mut self, x: f32) {
|
||||||
|
let x_le = ::flatbuffers::EndianScalar::to_little_endian(x);
|
||||||
|
// Safety:
|
||||||
|
// Created from a valid Table for this object
|
||||||
|
// Which contains a valid value in this slot
|
||||||
|
unsafe {
|
||||||
|
::core::ptr::copy_nonoverlapping(
|
||||||
|
&x_le as *const _ as *const u8,
|
||||||
|
self.0[8..].as_mut_ptr(),
|
||||||
|
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unpack(&self) -> Vec3T {
|
||||||
|
Vec3T {
|
||||||
|
x: self.x(),
|
||||||
|
y: self.y(),
|
||||||
|
z: self.z(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Vec3T {
|
pub struct Vec3T {
|
||||||
pub x: f32,
|
pub x: f32,
|
||||||
pub y: f32,
|
pub y: f32,
|
||||||
pub z: f32,
|
pub z: f32,
|
||||||
}
|
}
|
||||||
impl Vec3T {
|
impl Default for Vec3T {
|
||||||
pub fn pack(&self) -> Vec3 {
|
fn default() -> Self {
|
||||||
Vec3::new(
|
Self {
|
||||||
self.x,
|
x: 0.0,
|
||||||
self.y,
|
y: 0.0,
|
||||||
self.z,
|
z: 0.0,
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Vec3T {
|
||||||
|
pub fn pack(&self) -> Vec3 {
|
||||||
|
Vec3::new(
|
||||||
|
self.x,
|
||||||
|
self.y,
|
||||||
|
self.z,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,159 +2,172 @@
|
|||||||
// @generated
|
// @generated
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use super::*;
|
use super::*;
|
||||||
pub enum WeaponOffset {}
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
|
||||||
|
|
||||||
|
pub enum WeaponOffset {}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub struct Weapon<'a> {
|
pub struct Weapon<'a> {
|
||||||
pub _tab: ::flatbuffers::Table<'a>,
|
pub _tab: ::flatbuffers::Table<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ::flatbuffers::Follow<'a> for Weapon<'a> {
|
impl<'a> ::flatbuffers::Follow<'a> for Weapon<'a> {
|
||||||
type Inner = Weapon<'a>;
|
type Inner = Weapon<'a>;
|
||||||
#[inline]
|
|
||||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
#[inline]
|
||||||
Self { _tab: unsafe { ::flatbuffers::Table::new(buf, loc) } }
|
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||||
}
|
Self { _tab: unsafe { ::flatbuffers::Table::new(buf, loc) } }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Weapon<'a> {
|
impl<'a> Weapon<'a> {
|
||||||
pub const VT_NAME: ::flatbuffers::VOffsetT = 4;
|
pub const VT_NAME: ::flatbuffers::VOffsetT = 4;
|
||||||
pub const VT_DAMAGE: ::flatbuffers::VOffsetT = 6;
|
pub const VT_DAMAGE: ::flatbuffers::VOffsetT = 6;
|
||||||
|
|
||||||
pub const fn get_fully_qualified_name() -> &'static str {
|
pub const fn get_fully_qualified_name() -> &'static str {
|
||||||
"MyGame.Sample.Weapon"
|
"MyGame.Sample.Weapon"
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub unsafe fn init_from_table(table: ::flatbuffers::Table<'a>) -> Self {
|
|
||||||
Weapon { _tab: table }
|
|
||||||
}
|
|
||||||
#[allow(unused_mut)]
|
|
||||||
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: ::flatbuffers::Allocator + 'bldr>(
|
|
||||||
_fbb: &'mut_bldr mut ::flatbuffers::FlatBufferBuilder<'bldr, A>,
|
|
||||||
args: &'args WeaponArgs<'args>
|
|
||||||
) -> ::flatbuffers::WIPOffset<Weapon<'bldr>> {
|
|
||||||
let mut builder = WeaponBuilder::new(_fbb);
|
|
||||||
if let Some(x) = args.name { builder.add_name(x); }
|
|
||||||
builder.add_damage(args.damage);
|
|
||||||
builder.finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unpack(&self) -> WeaponT {
|
|
||||||
let name = self.name().map(|x| {
|
|
||||||
alloc::string::ToString::to_string(x)
|
|
||||||
});
|
|
||||||
let damage = self.damage();
|
|
||||||
WeaponT {
|
|
||||||
name,
|
|
||||||
damage,
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn name(&self) -> Option<&'a str> {
|
pub unsafe fn init_from_table(table: ::flatbuffers::Table<'a>) -> Self {
|
||||||
// Safety:
|
Weapon { _tab: table }
|
||||||
// Created from valid Table for this object
|
}
|
||||||
// which contains a valid value in this slot
|
|
||||||
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<&str>>(Weapon::VT_NAME, None)}
|
#[allow(unused_mut)]
|
||||||
}
|
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: ::flatbuffers::Allocator + 'bldr>(
|
||||||
#[inline]
|
_fbb: &'mut_bldr mut ::flatbuffers::FlatBufferBuilder<'bldr, A>,
|
||||||
pub fn damage(&self) -> i16 {
|
args: &'args WeaponArgs<'args>
|
||||||
// Safety:
|
) -> ::flatbuffers::WIPOffset<Weapon<'bldr>> {
|
||||||
// Created from valid Table for this object
|
let mut builder = WeaponBuilder::new(_fbb);
|
||||||
// which contains a valid value in this slot
|
if let Some(x) = args.name { builder.add_name(x); }
|
||||||
unsafe { self._tab.get::<i16>(Weapon::VT_DAMAGE, Some(0)).unwrap()}
|
builder.add_damage(args.damage);
|
||||||
}
|
builder.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unpack(&self) -> WeaponT {
|
||||||
|
let name = self.name().map(|x| {
|
||||||
|
alloc::string::ToString::to_string(x)
|
||||||
|
});
|
||||||
|
let damage = self.damage();
|
||||||
|
WeaponT {
|
||||||
|
name,
|
||||||
|
damage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn name(&self) -> Option<&'a str> {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<::flatbuffers::ForwardsUOffset<&str>>(Weapon::VT_NAME, None)}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn damage(&self) -> i16 {
|
||||||
|
// Safety:
|
||||||
|
// Created from valid Table for this object
|
||||||
|
// which contains a valid value in this slot
|
||||||
|
unsafe { self._tab.get::<i16>(Weapon::VT_DAMAGE, Some(0)).unwrap()}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::flatbuffers::Verifiable for Weapon<'_> {
|
impl ::flatbuffers::Verifiable for Weapon<'_> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn run_verifier(
|
fn run_verifier(
|
||||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||||
v.visit_table(pos)?
|
v.visit_table(pos)?
|
||||||
.visit_field::<::flatbuffers::ForwardsUOffset<&str>>("name", Self::VT_NAME, false)?
|
.visit_field::<::flatbuffers::ForwardsUOffset<&str>>("name", Self::VT_NAME, false)?
|
||||||
.visit_field::<i16>("damage", Self::VT_DAMAGE, false)?
|
.visit_field::<i16>("damage", Self::VT_DAMAGE, false)?
|
||||||
.finish();
|
.finish();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WeaponArgs<'a> {
|
pub struct WeaponArgs<'a> {
|
||||||
pub name: Option<::flatbuffers::WIPOffset<&'a str>>,
|
pub name: Option<::flatbuffers::WIPOffset<&'a str>>,
|
||||||
pub damage: i16,
|
pub damage: i16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Default for WeaponArgs<'a> {
|
impl<'a> Default for WeaponArgs<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
WeaponArgs {
|
WeaponArgs {
|
||||||
name: None,
|
name: None,
|
||||||
damage: 0,
|
damage: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WeaponBuilder<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> {
|
pub struct WeaponBuilder<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> {
|
||||||
fbb_: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
fbb_: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
||||||
start_: ::flatbuffers::WIPOffset<::flatbuffers::TableUnfinishedWIPOffset>,
|
start_: ::flatbuffers::WIPOffset<::flatbuffers::TableUnfinishedWIPOffset>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> WeaponBuilder<'a, 'b, A> {
|
impl<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> WeaponBuilder<'a, 'b, A> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn add_name(&mut self, name: ::flatbuffers::WIPOffset<&'b str>) {
|
pub fn add_name(&mut self, name: ::flatbuffers::WIPOffset<&'b str>) {
|
||||||
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Weapon::VT_NAME, name);
|
self.fbb_.push_slot_always::<::flatbuffers::WIPOffset<_>>(Weapon::VT_NAME, name);
|
||||||
}
|
}
|
||||||
#[inline]
|
|
||||||
pub fn add_damage(&mut self, damage: i16) {
|
#[inline]
|
||||||
self.fbb_.push_slot::<i16>(Weapon::VT_DAMAGE, damage, 0);
|
pub fn add_damage(&mut self, damage: i16) {
|
||||||
}
|
self.fbb_.push_slot::<i16>(Weapon::VT_DAMAGE, damage, 0);
|
||||||
#[inline]
|
}
|
||||||
pub fn new(_fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>) -> WeaponBuilder<'a, 'b, A> {
|
|
||||||
let start = _fbb.start_table();
|
#[inline]
|
||||||
WeaponBuilder {
|
pub fn new(_fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>) -> WeaponBuilder<'a, 'b, A> {
|
||||||
fbb_: _fbb,
|
let start = _fbb.start_table();
|
||||||
start_: start,
|
WeaponBuilder {
|
||||||
|
fbb_: _fbb,
|
||||||
|
start_: start,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn finish(self) -> ::flatbuffers::WIPOffset<Weapon<'a>> {
|
||||||
|
let o = self.fbb_.end_table(self.start_);
|
||||||
|
::flatbuffers::WIPOffset::new(o.value())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn finish(self) -> ::flatbuffers::WIPOffset<Weapon<'a>> {
|
|
||||||
let o = self.fbb_.end_table(self.start_);
|
|
||||||
::flatbuffers::WIPOffset::new(o.value())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::core::fmt::Debug for Weapon<'_> {
|
impl ::core::fmt::Debug for Weapon<'_> {
|
||||||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
||||||
let mut ds = f.debug_struct("Weapon");
|
let mut ds = f.debug_struct("Weapon");
|
||||||
ds.field("name", &self.name());
|
ds.field("name", &self.name());
|
||||||
ds.field("damage", &self.damage());
|
ds.field("damage", &self.damage());
|
||||||
ds.finish()
|
ds.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct WeaponT {
|
pub struct WeaponT {
|
||||||
pub name: Option<alloc::string::String>,
|
pub name: Option<alloc::string::String>,
|
||||||
pub damage: i16,
|
pub damage: i16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WeaponT {
|
impl Default for WeaponT {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: None,
|
name: None,
|
||||||
damage: 0,
|
damage: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WeaponT {
|
impl WeaponT {
|
||||||
pub fn pack<'b, A: ::flatbuffers::Allocator + 'b>(
|
pub fn pack<'b, A: ::flatbuffers::Allocator + 'b>(
|
||||||
&self,
|
&self,
|
||||||
_fbb: &mut ::flatbuffers::FlatBufferBuilder<'b, A>
|
_fbb: &mut ::flatbuffers::FlatBufferBuilder<'b, A>
|
||||||
) -> ::flatbuffers::WIPOffset<Weapon<'b>> {
|
) -> ::flatbuffers::WIPOffset<Weapon<'b>> {
|
||||||
let name = self.name.as_ref().map(|x|{
|
let name = self.name.as_ref().map(|x|{
|
||||||
_fbb.create_string(x)
|
_fbb.create_string(x)
|
||||||
});
|
});
|
||||||
let damage = self.damage;
|
let damage = self.damage;
|
||||||
Weapon::create(_fbb, &WeaponArgs{
|
Weapon::create(_fbb, &WeaponArgs{
|
||||||
name,
|
name,
|
||||||
damage,
|
damage,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ result = subprocess.run(
|
|||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
print(
|
print(
|
||||||
"\n"
|
"\n"
|
||||||
"ERROR: *********************************************************\n"
|
"ERROR: **********************************************************\n"
|
||||||
"ERROR: * The following differences were found after building. *\n"
|
"ERROR: * The following differences were found after building. *\n"
|
||||||
"ERROR: * Perhaps there is a difference in the flags for the. *\n"
|
"ERROR: * Perhaps there is a difference in the flags for the. *\n"
|
||||||
"ERROR: * CMakeLists.txt vs the script/generate_code.py script? *\n"
|
"ERROR: * CMakeLists.txt vs the scripts/generate_code.py script? *\n"
|
||||||
"ERROR: *********************************************************\n"
|
"ERROR: **********************************************************\n"
|
||||||
)
|
)
|
||||||
subprocess.run(["git", "diff", "--binary", "--exit-code"], cwd=root_path)
|
subprocess.run(["git", "diff", "--binary", "--exit-code"], cwd=root_path)
|
||||||
sys.exit(result.returncode)
|
sys.exit(result.returncode)
|
||||||
@@ -55,11 +55,11 @@ result = subprocess.run(
|
|||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
print(
|
print(
|
||||||
"\n"
|
"\n"
|
||||||
"ERROR: ********************************************************\n"
|
"ERROR: *********************************************************\n"
|
||||||
"ERROR: * The following differences were found after running *\n"
|
"ERROR: * The following differences were found after running *\n"
|
||||||
"ERROR: * the script/generate_code.py script. Maybe you forgot *\n"
|
"ERROR: * the scripts/generate_code.py script. Maybe you forgot *\n"
|
||||||
"ERROR: * to run it after making changes in a generator? *\n"
|
"ERROR: * to run it after making changes in a generator? *\n"
|
||||||
"ERROR: ********************************************************\n"
|
"ERROR: *********************************************************\n"
|
||||||
)
|
)
|
||||||
subprocess.run(["git", "diff", "--binary", "--exit-code"], cwd=root_path)
|
subprocess.run(["git", "diff", "--binary", "--exit-code"], cwd=root_path)
|
||||||
sys.exit(result.returncode)
|
sys.exit(result.returncode)
|
||||||
|
|||||||
@@ -85,6 +85,11 @@ RUST_OPTS = BASE_OPTS + [
|
|||||||
"--gen-name-strings",
|
"--gen-name-strings",
|
||||||
"--rust-module-root-file",
|
"--rust-module-root-file",
|
||||||
]
|
]
|
||||||
|
RUST_STANDALONE_OPTS = BASE_OPTS + [
|
||||||
|
"--rust",
|
||||||
|
"--gen-all",
|
||||||
|
"--gen-name-strings",
|
||||||
|
]
|
||||||
RUST_SERIALIZE_OPTS = BASE_OPTS + [
|
RUST_SERIALIZE_OPTS = BASE_OPTS + [
|
||||||
"--rust",
|
"--rust",
|
||||||
"--gen-all",
|
"--gen-all",
|
||||||
@@ -288,6 +293,12 @@ flatc(
|
|||||||
schema="include_test/include_test1.fbs",
|
schema="include_test/include_test1.fbs",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
flatc(
|
||||||
|
RUST_STANDALONE_OPTS,
|
||||||
|
include="include_test",
|
||||||
|
schema="include_test/include_test1.fbs",
|
||||||
|
)
|
||||||
|
|
||||||
flatc(
|
flatc(
|
||||||
RUST_OPTS,
|
RUST_OPTS,
|
||||||
prefix="include_test2",
|
prefix="include_test2",
|
||||||
@@ -295,6 +306,12 @@ flatc(
|
|||||||
schema="include_test/sub/include_test2.fbs",
|
schema="include_test/sub/include_test2.fbs",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
flatc(
|
||||||
|
RUST_STANDALONE_OPTS,
|
||||||
|
include="include_test",
|
||||||
|
schema="include_test/sub/include_test2.fbs",
|
||||||
|
)
|
||||||
|
|
||||||
flatc(
|
flatc(
|
||||||
BINARY_OPTS + ["--bfbs-filenames", str(tests_path)],
|
BINARY_OPTS + ["--bfbs-filenames", str(tests_path)],
|
||||||
include="include_test",
|
include="include_test",
|
||||||
@@ -377,6 +394,11 @@ flatc(
|
|||||||
schema="native_inline_table_test.fbs",
|
schema="native_inline_table_test.fbs",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
flatc(
|
||||||
|
["--cpp", "--gen-compare", "--gen-mutable", "--gen-object-api", "--reflect-names"],
|
||||||
|
schema="cross_namespace_pack_test.fbs",
|
||||||
|
)
|
||||||
|
|
||||||
flatc(
|
flatc(
|
||||||
RUST_OPTS,
|
RUST_OPTS,
|
||||||
prefix="arrays_test",
|
prefix="arrays_test",
|
||||||
@@ -400,6 +422,11 @@ flatc(
|
|||||||
schema="nested_union_test.fbs",
|
schema="nested_union_test.fbs",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
flatc(
|
||||||
|
["--python", "--gen-object-api"],
|
||||||
|
schema="union_name_test.fbs",
|
||||||
|
)
|
||||||
|
|
||||||
flatc(
|
flatc(
|
||||||
NO_INCL_OPTS + CPP_OPTS,
|
NO_INCL_OPTS + CPP_OPTS,
|
||||||
schema="default_vectors_strings_test.fbs",
|
schema="default_vectors_strings_test.fbs",
|
||||||
@@ -500,6 +527,13 @@ flatc(
|
|||||||
cwd=swift_code_gen,
|
cwd=swift_code_gen,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
flatc(
|
||||||
|
SWIFT_OPTS_CODE_GEN + BASE_OPTS,
|
||||||
|
schema="empty_vtable.fbs",
|
||||||
|
cwd=swift_code_gen,
|
||||||
|
prefix="../../Tests/Flatbuffers/",
|
||||||
|
)
|
||||||
|
|
||||||
# Swift Wasm Tests
|
# Swift Wasm Tests
|
||||||
swift_Wasm_prefix = "swift/Wasm.tests/Tests/FlatBuffers.Test.Swift.WasmTests"
|
swift_Wasm_prefix = "swift/Wasm.tests/Tests/FlatBuffers.Test.Swift.WasmTests"
|
||||||
flatc(
|
flatc(
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from util import flatc, root_path
|
|||||||
grpc_examples_path = Path(root_path, "grpc/examples")
|
grpc_examples_path = Path(root_path, "grpc/examples")
|
||||||
|
|
||||||
greeter_schema = str(Path(grpc_examples_path, "greeter.fbs"))
|
greeter_schema = str(Path(grpc_examples_path, "greeter.fbs"))
|
||||||
|
greeter_schema_v2 = str(Path(grpc_examples_path, "greeter_v2.fbs"))
|
||||||
|
|
||||||
COMMON_ARGS = [
|
COMMON_ARGS = [
|
||||||
"--grpc",
|
"--grpc",
|
||||||
@@ -54,8 +55,8 @@ def GenerateGRPCExamples():
|
|||||||
"--swift",
|
"--swift",
|
||||||
"--gen-json-emit",
|
"--gen-json-emit",
|
||||||
],
|
],
|
||||||
schema=greeter_schema,
|
schema=greeter_schema_v2,
|
||||||
cwd=Path(grpc_examples_path, "swift/Greeter/Sources/Model"),
|
cwd=Path(grpc_examples_path, "swift/Greeter/Sources/Models"),
|
||||||
)
|
)
|
||||||
|
|
||||||
flatc(
|
flatc(
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ Namer::Config LuaDefaultConfig() {
|
|||||||
/*object_suffix=*/"",
|
/*object_suffix=*/"",
|
||||||
/*keyword_prefix=*/"",
|
/*keyword_prefix=*/"",
|
||||||
/*keyword_suffix=*/"_",
|
/*keyword_suffix=*/"_",
|
||||||
|
/*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
|
||||||
/*filenames=*/Case::kKeep,
|
/*filenames=*/Case::kKeep,
|
||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
@@ -194,6 +195,13 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
code += "\n";
|
code += "\n";
|
||||||
|
|
||||||
if (object == root_object) {
|
if (object == root_object) {
|
||||||
|
// emit file identifier if present
|
||||||
|
const auto ident = schema_->file_ident();
|
||||||
|
if (ident && ident->size() == 4) {
|
||||||
|
code += "local FileIdentifier = \"" + ident->str() + "\"\n";
|
||||||
|
code += "\n";
|
||||||
|
}
|
||||||
|
|
||||||
code += "function " + object_name + ".GetRootAs" + object_name +
|
code += "function " + object_name + ".GetRootAs" + object_name +
|
||||||
"(buf, offset)\n";
|
"(buf, offset)\n";
|
||||||
code += " if type(buf) == \"string\" then\n";
|
code += " if type(buf) == \"string\" then\n";
|
||||||
@@ -454,6 +462,34 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
code += " return builder:EndObject()\n";
|
code += " return builder:EndObject()\n";
|
||||||
code += "end\n";
|
code += "end\n";
|
||||||
code += "\n";
|
code += "\n";
|
||||||
|
|
||||||
|
if (object == root_object) {
|
||||||
|
code += "function " + object_name + ".Finish" + object_name +
|
||||||
|
"Buffer(builder, offset)\n";
|
||||||
|
// emit file identifier if present
|
||||||
|
const auto ident = schema_->file_ident();
|
||||||
|
if (ident && ident->size() == 4) {
|
||||||
|
code += " builder:FinishWithIdentifier(offset, FileIdentifier)\n";
|
||||||
|
} else {
|
||||||
|
code += " builder:Finish(offset)\n";
|
||||||
|
}
|
||||||
|
code += "end\n";
|
||||||
|
code += "\n";
|
||||||
|
|
||||||
|
// size prefixed option
|
||||||
|
code += "function " + object_name + ".FinishSizePrefixed" +
|
||||||
|
object_name + "Buffer(builder, offset)\n";
|
||||||
|
// emit file identifier if present
|
||||||
|
if (ident && ident->size() == 4) {
|
||||||
|
code +=
|
||||||
|
" builder:FinishSizePrefixedWithIdentifier(offset, "
|
||||||
|
"FileIdentifier)\n";
|
||||||
|
} else {
|
||||||
|
code += " builder:FinishSizePrefixed(offset)\n";
|
||||||
|
}
|
||||||
|
code += "end\n";
|
||||||
|
code += "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitCodeBlock(code, object_name, ns, object->declaration_file()->str());
|
EmitCodeBlock(code, object_name, ns, object->declaration_file()->str());
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ Namer::Config NimDefaultConfig() {
|
|||||||
/*object_suffix=*/"T",
|
/*object_suffix=*/"T",
|
||||||
/*keyword_prefix=*/"",
|
/*keyword_prefix=*/"",
|
||||||
/*keyword_suffix=*/"_",
|
/*keyword_suffix=*/"_",
|
||||||
|
/*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
|
||||||
/*filenames=*/Case::kKeep,
|
/*filenames=*/Case::kKeep,
|
||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
|
|||||||
@@ -126,9 +126,7 @@ static BinarySection GenerateMissingSection(const uint64_t offset,
|
|||||||
std::map<uint64_t, BinarySection> BinaryAnnotator::Annotate() {
|
std::map<uint64_t, BinarySection> BinaryAnnotator::Annotate() {
|
||||||
if (bfbs_ != nullptr && bfbs_length_ != 0) {
|
if (bfbs_ != nullptr && bfbs_length_ != 0) {
|
||||||
flatbuffers::Verifier verifier(bfbs_, static_cast<size_t>(bfbs_length_));
|
flatbuffers::Verifier verifier(bfbs_, static_cast<size_t>(bfbs_length_));
|
||||||
if ((is_size_prefixed_ &&
|
if (!reflection::VerifySchemaBuffer(verifier)) {
|
||||||
!reflection::VerifySizePrefixedSchemaBuffer(verifier)) ||
|
|
||||||
!reflection::VerifySchemaBuffer(verifier)) {
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -265,6 +265,9 @@ const static FlatCOption flatc_options[] = {
|
|||||||
{"", "python-gen-numpy", "", "Whether to generate numpy helpers."},
|
{"", "python-gen-numpy", "", "Whether to generate numpy helpers."},
|
||||||
{"", "ts-omit-entrypoint", "",
|
{"", "ts-omit-entrypoint", "",
|
||||||
"Omit emission of namespace entrypoint file"},
|
"Omit emission of namespace entrypoint file"},
|
||||||
|
{"", "ts-undefined-for-optionals", "",
|
||||||
|
"Whether to generate undefined values instead of null values for missing "
|
||||||
|
"optional keys"},
|
||||||
{"", "file-names-only", "",
|
{"", "file-names-only", "",
|
||||||
"Print out generated file names without writing to the files"},
|
"Print out generated file names without writing to the files"},
|
||||||
{"", "grpc-filename-suffix", "SUFFIX",
|
{"", "grpc-filename-suffix", "SUFFIX",
|
||||||
@@ -710,6 +713,8 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
|
|||||||
opts.python_gen_numpy = false;
|
opts.python_gen_numpy = false;
|
||||||
} else if (arg == "--ts-omit-entrypoint") {
|
} else if (arg == "--ts-omit-entrypoint") {
|
||||||
opts.ts_omit_entrypoint = true;
|
opts.ts_omit_entrypoint = true;
|
||||||
|
} else if (arg == "--ts-undefined-for-optionals") {
|
||||||
|
opts.ts_undefined_for_optionals = true;
|
||||||
} else if (arg == "--annotate-sparse-vectors") {
|
} else if (arg == "--annotate-sparse-vectors") {
|
||||||
options.annotate_include_vector_contents = false;
|
options.annotate_include_vector_contents = false;
|
||||||
} else if (arg == "--annotate") {
|
} else if (arg == "--annotate") {
|
||||||
@@ -922,6 +927,9 @@ std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions& options,
|
|||||||
auto err = parser->ConformTo(conform_parser);
|
auto err = parser->ConformTo(conform_parser);
|
||||||
if (!err.empty()) Error("schemas don\'t conform: " + err, false);
|
if (!err.empty()) Error("schemas don\'t conform: " + err, false);
|
||||||
}
|
}
|
||||||
|
if (parser->HasCircularStructDependency()) {
|
||||||
|
Error("schema has circular struct dependencies: " + filename, false);
|
||||||
|
}
|
||||||
if (options.schema_binary || opts.binary_schema_gen_embed) {
|
if (options.schema_binary || opts.binary_schema_gen_embed) {
|
||||||
parser->Serialize();
|
parser->Serialize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2685,14 +2685,18 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_ += " }";
|
code_ += " }";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenTableUnionAsGetters(const FieldDef& field) {
|
void GenTableUnionAsGetters(const FieldDef& field, bool is_mutable) {
|
||||||
const auto& type = field.value.type;
|
const auto& type = field.value.type;
|
||||||
auto u = type.enum_def;
|
auto u = type.enum_def;
|
||||||
|
|
||||||
|
code_.SetValue("MUTABLE_EXT", is_mutable ? "" : " const");
|
||||||
|
code_.SetValue("MUTABLE", is_mutable ? "mutable_" : "");
|
||||||
|
|
||||||
if (!type.enum_def->uses_multiple_type_instances)
|
if (!type.enum_def->uses_multiple_type_instances)
|
||||||
code_ +=
|
code_ +=
|
||||||
" template<typename T> "
|
" template<typename T>"
|
||||||
"const T *{{NULLABLE_EXT}}{{FIELD_NAME}}_as() const;";
|
"{{MUTABLE_EXT}} T *{{MUTABLE}}{{NULLABLE_EXT}}{{FIELD_NAME}}_as()"
|
||||||
|
"{{MUTABLE_EXT}};";
|
||||||
|
|
||||||
for (auto u_it = u->Vals().begin(); u_it != u->Vals().end(); ++u_it) {
|
for (auto u_it = u->Vals().begin(); u_it != u->Vals().end(); ++u_it) {
|
||||||
auto& ev = **u_it;
|
auto& ev = **u_it;
|
||||||
@@ -2706,15 +2710,19 @@ class CppGenerator : public BaseGenerator {
|
|||||||
EscapeKeyword(Name(field) + UnionTypeFieldSuffix()));
|
EscapeKeyword(Name(field) + UnionTypeFieldSuffix()));
|
||||||
code_.SetValue("U_ELEMENT_TYPE", WrapInNameSpace(u->defined_namespace,
|
code_.SetValue("U_ELEMENT_TYPE", WrapInNameSpace(u->defined_namespace,
|
||||||
GetEnumValUse(*u, ev)));
|
GetEnumValUse(*u, ev)));
|
||||||
code_.SetValue("U_FIELD_TYPE", "const " + full_struct_name + " *");
|
code_.SetValue("U_FIELD_TYPE",
|
||||||
|
(is_mutable ? "" : "const ") + full_struct_name + " *");
|
||||||
code_.SetValue("U_FIELD_NAME", Name(field) + "_as_" + Name(ev));
|
code_.SetValue("U_FIELD_NAME", Name(field) + "_as_" + Name(ev));
|
||||||
code_.SetValue("U_NULLABLE", NullableExtension());
|
code_.SetValue("U_NULLABLE", NullableExtension());
|
||||||
|
|
||||||
// `const Type *union_name_asType() const` accessor.
|
// `const Type *union_name_asType() const` accessor.
|
||||||
code_ += " {{U_FIELD_TYPE}}{{U_NULLABLE}}{{U_FIELD_NAME}}() const {";
|
// and `Type *mutable_union_name_asType()` accessor.
|
||||||
|
code_ +=
|
||||||
|
" {{U_FIELD_TYPE}}{{U_NULLABLE}}{{MUTABLE}}{{U_FIELD_NAME}}()"
|
||||||
|
"{{MUTABLE_EXT}} {";
|
||||||
code_ +=
|
code_ +=
|
||||||
" return {{U_GET_TYPE}}() == {{U_ELEMENT_TYPE}} ? "
|
" return {{U_GET_TYPE}}() == {{U_ELEMENT_TYPE}} ? "
|
||||||
"static_cast<{{U_FIELD_TYPE}}>({{FIELD_NAME}}()) "
|
"static_cast<{{U_FIELD_TYPE}}>({{MUTABLE}}{{FIELD_NAME}}()) "
|
||||||
": nullptr;";
|
": nullptr;";
|
||||||
code_ += " }";
|
code_ += " }";
|
||||||
}
|
}
|
||||||
@@ -2755,7 +2763,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, call));
|
code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, call));
|
||||||
code_.SetValue("NULLABLE_EXT", NullableExtension());
|
code_.SetValue("NULLABLE_EXT", NullableExtension());
|
||||||
code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}() const {";
|
code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}() const {";
|
||||||
if (IsVector(type) && field.value.constant == "[]") {
|
if (IsVector(type) && field.value.constant == "[]") {
|
||||||
const auto& vec_type = type.VectorType();
|
const auto& vec_type = type.VectorType();
|
||||||
const std::string vtype_wire = GenTypeWire(
|
const std::string vtype_wire = GenTypeWire(
|
||||||
vec_type, "", VectorElementUserFacing(vec_type), field.offset64);
|
vec_type, "", VectorElementUserFacing(vec_type), field.offset64);
|
||||||
@@ -2771,15 +2779,17 @@ class CppGenerator : public BaseGenerator {
|
|||||||
get_call += ">(" + offset_str + ");";
|
get_call += ">(" + offset_str + ");";
|
||||||
code_ += get_call;
|
code_ += get_call;
|
||||||
} else if (IsString(type) && field.value.constant != "0") {
|
} else if (IsString(type) && field.value.constant != "0") {
|
||||||
// TODO: Add logic to always convert the string to a valid C++ string
|
std::string escaped;
|
||||||
// literal by handling string escapes.
|
flatbuffers::EscapeString(field.value.constant.c_str(),
|
||||||
|
field.value.constant.length(), &escaped,
|
||||||
|
true, false);
|
||||||
code_ += " auto* ptr = {{FIELD_VALUE}};";
|
code_ += " auto* ptr = {{FIELD_VALUE}};";
|
||||||
code_ += " if (ptr) return ptr;";
|
code_ += " if (ptr) return ptr;";
|
||||||
code_ += " static const struct { uint32_t len; const char s[" +
|
code_ += " static const struct { uint32_t len; const char s[" +
|
||||||
NumToString(field.value.constant.length() + 1) +
|
NumToString(field.value.constant.length() + 1) +
|
||||||
"]; } bfbs_string = { " +
|
"]; } bfbs_string = { " +
|
||||||
NumToString(field.value.constant.length()) + ", \"" +
|
NumToString(field.value.constant.length()) + ", " +
|
||||||
field.value.constant + "\" };";
|
escaped + " };";
|
||||||
code_ +=
|
code_ +=
|
||||||
" return reinterpret_cast<const ::flatbuffers::String "
|
" return reinterpret_cast<const ::flatbuffers::String "
|
||||||
" *>(&bfbs_string);";
|
" *>(&bfbs_string);";
|
||||||
@@ -2799,7 +2809,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type.base_type == BASE_TYPE_UNION) {
|
if (type.base_type == BASE_TYPE_UNION) {
|
||||||
GenTableUnionAsGetters(field);
|
GenTableUnionAsGetters(field, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2974,6 +2984,11 @@ class CppGenerator : public BaseGenerator {
|
|||||||
auto wire_type = GenTypeGet(type, " ", "", postptr.c_str(), true);
|
auto wire_type = GenTypeGet(type, " ", "", postptr.c_str(), true);
|
||||||
code_.SetValue("FIELD_TYPE", wire_type);
|
code_.SetValue("FIELD_TYPE", wire_type);
|
||||||
|
|
||||||
|
// mutable union accessors
|
||||||
|
if (type.base_type == BASE_TYPE_UNION) {
|
||||||
|
GenTableUnionAsGetters(field, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (IsVector(type) && field.value.constant == "[]") {
|
if (IsVector(type) && field.value.constant == "[]") {
|
||||||
const auto& vec_type = type.VectorType();
|
const auto& vec_type = type.VectorType();
|
||||||
const std::string vtype_wire = GenTypeWire(
|
const std::string vtype_wire = GenTypeWire(
|
||||||
@@ -3185,6 +3200,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_.SetValue("U_FIELD_NAME", Name(*field) + "_as_" + Name(ev));
|
code_.SetValue("U_FIELD_NAME", Name(*field) + "_as_" + Name(ev));
|
||||||
|
|
||||||
// `template<> const T *union_name_as<T>() const` accessor.
|
// `template<> const T *union_name_as<T>() const` accessor.
|
||||||
|
// and `template<> T *mutable_union_name_as<T>()` accessor.
|
||||||
code_ +=
|
code_ +=
|
||||||
"template<> "
|
"template<> "
|
||||||
"inline {{U_FIELD_TYPE}}{{STRUCT_NAME}}::{{FIELD_NAME}}_as"
|
"inline {{U_FIELD_TYPE}}{{STRUCT_NAME}}::{{FIELD_NAME}}_as"
|
||||||
@@ -3192,6 +3208,20 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_ += " return {{U_FIELD_NAME}}();";
|
code_ += " return {{U_FIELD_NAME}}();";
|
||||||
code_ += "}";
|
code_ += "}";
|
||||||
code_ += "";
|
code_ += "";
|
||||||
|
|
||||||
|
if (opts_.mutable_buffer) {
|
||||||
|
code_.SetValue("U_FIELD_TYPE", full_struct_name + " *");
|
||||||
|
code_.SetValue("U_FIELD_NAME",
|
||||||
|
"mutable_" + Name(*field) + "_as_" + Name(ev));
|
||||||
|
code_ +=
|
||||||
|
"template<> "
|
||||||
|
"inline {{U_FIELD_TYPE}}"
|
||||||
|
"{{STRUCT_NAME}}::mutable_{{FIELD_NAME}}_as"
|
||||||
|
"<{{U_ELEMENT_NAME}}>() {";
|
||||||
|
code_ += " return {{U_FIELD_NAME}}();";
|
||||||
|
code_ += "}";
|
||||||
|
code_ += "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3389,11 +3419,15 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_.SetValue("CREATE_STRING", "CreateSharedString");
|
code_.SetValue("CREATE_STRING", "CreateSharedString");
|
||||||
}
|
}
|
||||||
if (field->value.constant != "0") {
|
if (field->value.constant != "0") {
|
||||||
|
std::string escaped;
|
||||||
|
flatbuffers::EscapeString(field->value.constant.c_str(),
|
||||||
|
field->value.constant.length(), &escaped,
|
||||||
|
true, false);
|
||||||
code_ +=
|
code_ +=
|
||||||
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
|
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
|
||||||
"_fbb.{{CREATE_STRING}}({{FIELD_NAME}}) : "
|
"_fbb.{{CREATE_STRING}}({{FIELD_NAME}}) : "
|
||||||
"_fbb.{{CREATE_STRING}}(\"" +
|
"_fbb.{{CREATE_STRING}}(" +
|
||||||
field->value.constant + "\");";
|
escaped + ");";
|
||||||
} else {
|
} else {
|
||||||
code_ +=
|
code_ +=
|
||||||
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
|
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
|
||||||
@@ -3797,7 +3831,9 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code += WrapInNameSpace(*vector_type.struct_def) + ">> ";
|
code += WrapInNameSpace(*vector_type.struct_def) + ">> ";
|
||||||
code += "(" + value + ".size(), ";
|
code += "(" + value + ".size(), ";
|
||||||
code += "[](size_t i, _VectorArgs *__va) { ";
|
code += "[](size_t i, _VectorArgs *__va) { ";
|
||||||
code += "return Create" + vector_type.struct_def->name;
|
code += "return " +
|
||||||
|
WrapInNameSpace(vector_type.struct_def->defined_namespace,
|
||||||
|
"Create" + vector_type.struct_def->name);
|
||||||
code += "(*__va->__fbb, ";
|
code += "(*__va->__fbb, ";
|
||||||
if (field.native_inline) {
|
if (field.native_inline) {
|
||||||
code += "&(__va->_" + value + "[i])";
|
code += "&(__va->_" + value + "[i])";
|
||||||
@@ -3910,8 +3946,10 @@ class CppGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// _o->field ? CreateT(_fbb, _o->field.get(), _rehasher);
|
// _o->field ? CreateT(_fbb, _o->field.get(), _rehasher);
|
||||||
const std::string& type = field.value.type.struct_def->name;
|
const auto& nested_struct = *field.value.type.struct_def;
|
||||||
code += value + " ? Create" + type;
|
code += value + " ? " +
|
||||||
|
WrapInNameSpace(nested_struct.defined_namespace,
|
||||||
|
"Create" + nested_struct.name);
|
||||||
code += "(_fbb, " + value;
|
code += "(_fbb, " + value;
|
||||||
if (!field.native_inline) code += GenPtrGet(field);
|
if (!field.native_inline) code += GenPtrGet(field);
|
||||||
code += ", _rehasher) : 0";
|
code += ", _rehasher) : 0";
|
||||||
|
|||||||
@@ -1243,6 +1243,58 @@ class CSharpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
code += " }\n";
|
code += " }\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate Length property and ByteBuffer accessor for arrays in structs.
|
||||||
|
if (IsArray(field.value.type) && struct_def.fixed &&
|
||||||
|
IsScalar(field.value.type.VectorType().base_type)) {
|
||||||
|
auto camel_name = Name(field);
|
||||||
|
if (camel_name == struct_def.name) { camel_name += "_"; }
|
||||||
|
|
||||||
|
// Generate Length constant
|
||||||
|
code += " public const int " + camel_name;
|
||||||
|
code += "Length = ";
|
||||||
|
code += NumToString(field.value.type.fixed_length);
|
||||||
|
code += ";\n";
|
||||||
|
|
||||||
|
// Generate GetBytes methods for scalar arrays (similar to vector pattern)
|
||||||
|
code += "#if ENABLE_SPAN_T\n";
|
||||||
|
code += " public Span<" + GenTypeBasic(field.value.type.VectorType()) +
|
||||||
|
"> Get";
|
||||||
|
code += camel_name;
|
||||||
|
code += "Bytes() { return ";
|
||||||
|
|
||||||
|
// For byte arrays, we can return the span directly
|
||||||
|
if (field.value.type.VectorType().base_type == BASE_TYPE_UCHAR) {
|
||||||
|
code += "__p.bb.ToSpan(__p.bb_pos + ";
|
||||||
|
code += NumToString(field.value.offset);
|
||||||
|
code += ", ";
|
||||||
|
code += NumToString(field.value.type.fixed_length *
|
||||||
|
SizeOf(field.value.type.VectorType().base_type));
|
||||||
|
code += ")";
|
||||||
|
} else {
|
||||||
|
// For other types, we need to cast the byte span
|
||||||
|
code += "System.Runtime.InteropServices.MemoryMarshal.Cast<byte, " +
|
||||||
|
GenTypeBasic(field.value.type.VectorType()) + ">(__p.bb.ToSpan(__p.bb_pos + ";
|
||||||
|
code += NumToString(field.value.offset);
|
||||||
|
code += ", ";
|
||||||
|
code += NumToString(field.value.type.fixed_length *
|
||||||
|
SizeOf(field.value.type.VectorType().base_type));
|
||||||
|
code += "))";
|
||||||
|
}
|
||||||
|
code += "; }\n";
|
||||||
|
code += "#else\n";
|
||||||
|
code += " public ArraySegment<byte>? Get";
|
||||||
|
code += camel_name;
|
||||||
|
code += "Bytes() { return ";
|
||||||
|
code += "__p.bb.ToArraySegment(__p.bb_pos + ";
|
||||||
|
code += NumToString(field.value.offset);
|
||||||
|
code += ", ";
|
||||||
|
code += NumToString(field.value.type.fixed_length *
|
||||||
|
SizeOf(field.value.type.VectorType().base_type));
|
||||||
|
code += ");}\n";
|
||||||
|
code += "#endif\n";
|
||||||
|
}
|
||||||
|
|
||||||
// generate object accessors if is nested_flatbuffer
|
// generate object accessors if is nested_flatbuffer
|
||||||
if (field.nested_flatbuffer) {
|
if (field.nested_flatbuffer) {
|
||||||
auto nested_type_name = NamespacedName(*field.nested_flatbuffer);
|
auto nested_type_name = NamespacedName(*field.nested_flatbuffer);
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ static Namer::Config DartDefaultConfig() {
|
|||||||
/*object_suffix=*/"T",
|
/*object_suffix=*/"T",
|
||||||
/*keyword_prefix=*/"$",
|
/*keyword_prefix=*/"$",
|
||||||
/*keyword_suffix=*/"",
|
/*keyword_suffix=*/"",
|
||||||
|
/*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
|
||||||
/*filenames=*/Case::kKeep,
|
/*filenames=*/Case::kKeep,
|
||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
@@ -653,34 +654,15 @@ class DartGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
std::string NamespaceAliasFromUnionType(Namespace* root_namespace,
|
std::string NamespaceAliasFromUnionType(Namespace* root_namespace,
|
||||||
const Type& type) {
|
const Type& type) {
|
||||||
const std::vector<std::string> qualified_name_parts =
|
const Namespace& type_namespace = *type.struct_def->defined_namespace;
|
||||||
type.struct_def->defined_namespace->components;
|
if (root_namespace->components == type_namespace.components) {
|
||||||
if (std::equal(root_namespace->components.begin(),
|
|
||||||
root_namespace->components.end(),
|
|
||||||
qualified_name_parts.begin())) {
|
|
||||||
return namer_.Type(*type.struct_def);
|
return namer_.Type(*type.struct_def);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ns;
|
const std::string ns = namer_.Namespace(type_namespace);
|
||||||
|
return ns.empty()
|
||||||
for (auto it = qualified_name_parts.begin();
|
? namer_.Type(*type.struct_def)
|
||||||
it != qualified_name_parts.end(); ++it) {
|
: ImportAliasName(ns) + "." + namer_.Type(*type.struct_def);
|
||||||
auto& part = *it;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < part.length(); i++) {
|
|
||||||
if (i && !isdigit(part[i]) && part[i] == CharToUpper(part[i])) {
|
|
||||||
ns += "_";
|
|
||||||
ns += CharToLower(part[i]);
|
|
||||||
} else {
|
|
||||||
ns += CharToLower(part[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (it != qualified_name_parts.end() - 1) {
|
|
||||||
ns += "_";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ns + "." + namer_.Type(*type.struct_def);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenImplementationGetters(
|
void GenImplementationGetters(
|
||||||
|
|||||||
@@ -368,7 +368,17 @@ static std::string GenerateFBS(const Parser& parser,
|
|||||||
if (field.value.type.base_type != BASE_TYPE_UTYPE) {
|
if (field.value.type.base_type != BASE_TYPE_UTYPE) {
|
||||||
GenComment(field.doc_comment, &schema, nullptr, " ");
|
GenComment(field.doc_comment, &schema, nullptr, " ");
|
||||||
schema += " " + field.name + ":" + GenType(field.value.type);
|
schema += " " + field.name + ":" + GenType(field.value.type);
|
||||||
if (field.value.constant != "0") schema += " = " + field.value.constant;
|
if (field.value.constant != "0") {
|
||||||
|
if (IsString(field.value.type)) {
|
||||||
|
std::string escaped;
|
||||||
|
flatbuffers::EscapeString(field.value.constant.c_str(),
|
||||||
|
field.value.constant.length(), &escaped,
|
||||||
|
true, false);
|
||||||
|
schema += " = " + escaped;
|
||||||
|
} else {
|
||||||
|
schema += " = " + field.value.constant;
|
||||||
|
}
|
||||||
|
}
|
||||||
std::vector<std::string> attributes;
|
std::vector<std::string> attributes;
|
||||||
if (field.IsRequired()) attributes.push_back("required");
|
if (field.IsRequired()) attributes.push_back("required");
|
||||||
if (field.key) attributes.push_back("key");
|
if (field.key) attributes.push_back("key");
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ static Namer::Config GoDefaultConfig() {
|
|||||||
/*object_suffix=*/"T",
|
/*object_suffix=*/"T",
|
||||||
/*keyword_prefix=*/"",
|
/*keyword_prefix=*/"",
|
||||||
/*keyword_suffix=*/"_",
|
/*keyword_suffix=*/"_",
|
||||||
|
/*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
|
||||||
/*filenames=*/Case::kKeep,
|
/*filenames=*/Case::kKeep,
|
||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ static Namer::Config JavaDefaultConfig() {
|
|||||||
/*object_suffix=*/"T",
|
/*object_suffix=*/"T",
|
||||||
/*keyword_prefix=*/"",
|
/*keyword_prefix=*/"",
|
||||||
/*keyword_suffix=*/"_",
|
/*keyword_suffix=*/"_",
|
||||||
|
/*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
|
||||||
/*filenames=*/Case::kKeep,
|
/*filenames=*/Case::kKeep,
|
||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ static Namer::Config KotlinDefaultConfig() {
|
|||||||
/*object_suffix=*/"T",
|
/*object_suffix=*/"T",
|
||||||
/*keyword_prefix=*/"",
|
/*keyword_prefix=*/"",
|
||||||
/*keyword_suffix=*/"_",
|
/*keyword_suffix=*/"_",
|
||||||
|
/*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
|
||||||
/*filenames=*/Case::kKeep,
|
/*filenames=*/Case::kKeep,
|
||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ static Namer::Config KotlinDefaultConfig() {
|
|||||||
/*object_suffix=*/"T",
|
/*object_suffix=*/"T",
|
||||||
/*keyword_prefix=*/"",
|
/*keyword_prefix=*/"",
|
||||||
/*keyword_suffix=*/"E",
|
/*keyword_suffix=*/"E",
|
||||||
|
/*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
|
||||||
/*filenames=*/Case::kUpperCamel,
|
/*filenames=*/Case::kUpperCamel,
|
||||||
/*directories=*/Case::kLowerCamel,
|
/*directories=*/Case::kLowerCamel,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
|
|||||||
@@ -593,6 +593,18 @@ class PythonStubGenerator {
|
|||||||
"bytes) -> uoffset: ...\n";
|
"bytes) -> uoffset: ...\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stub << "def ";
|
||||||
|
if (!parser_.opts.python_no_type_prefix_suffix) stub << type;
|
||||||
|
stub << "Create" << namer_.Method(*field)
|
||||||
|
<< "Vector(builder: flatbuffers.Builder, data: typing.Iterable["
|
||||||
|
"typing.Any]) -> uoffset: ...\n";
|
||||||
|
if (!parser_.opts.one_file &&
|
||||||
|
!parser_.opts.python_no_type_prefix_suffix) {
|
||||||
|
stub << "def Create" << namer_.Method(*field)
|
||||||
|
<< "Vector(builder: flatbuffers.Builder, data: "
|
||||||
|
"typing.Iterable[typing.Any]) -> uoffset: ...\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1201,12 +1213,15 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
return;
|
return;
|
||||||
} // There is no nested flatbuffer.
|
} // There is no nested flatbuffer.
|
||||||
|
|
||||||
const std::string unqualified_name = nested->constant;
|
std::string unqualified_name = nested->constant;
|
||||||
std::string qualified_name = NestedFlatbufferType(unqualified_name);
|
std::string qualified_name = NestedFlatbufferType(unqualified_name);
|
||||||
if (qualified_name.empty()) {
|
if (qualified_name.empty()) {
|
||||||
qualified_name = nested->constant;
|
qualified_name = nested->constant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// name may be partially qualified -- need to get the true unqualified name
|
||||||
|
unqualified_name = namer_.Denamespace(qualified_name);
|
||||||
|
|
||||||
const ImportMapEntry import_entry = {qualified_name, unqualified_name};
|
const ImportMapEntry import_entry = {qualified_name, unqualified_name};
|
||||||
|
|
||||||
auto& code = *code_ptr;
|
auto& code = *code_ptr;
|
||||||
@@ -1464,6 +1479,59 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BuildVectorCreationHelper(const StructDef& struct_def,
|
||||||
|
const FieldDef& field, std::string* code_ptr,
|
||||||
|
ImportMap& imports) const {
|
||||||
|
auto& code = *code_ptr;
|
||||||
|
const auto vector_type = field.value.type.VectorType();
|
||||||
|
const bool is_struct_vector = IsStruct(vector_type);
|
||||||
|
const bool is_scalar_vector =
|
||||||
|
IsScalar(vector_type.base_type) || vector_type.enum_def != nullptr;
|
||||||
|
const std::string struct_type = namer_.Type(struct_def);
|
||||||
|
const std::string field_method = namer_.Method(field);
|
||||||
|
const std::string helper_name =
|
||||||
|
parser_.opts.python_no_type_prefix_suffix
|
||||||
|
? "Create" + field_method + "Vector"
|
||||||
|
: struct_type + "Create" + field_method + "Vector";
|
||||||
|
|
||||||
|
if (parser_.opts.python_typing) {
|
||||||
|
imports.insert(ImportMapEntry{"typing", "Iterable"});
|
||||||
|
code += "def " + helper_name +
|
||||||
|
"(builder: flatbuffers.Builder, data: Iterable[Any]) -> int:\n";
|
||||||
|
} else {
|
||||||
|
code += "def " + helper_name + "(builder, data):\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_scalar_vector || is_struct_vector) {
|
||||||
|
auto alignment = InlineAlignment(vector_type);
|
||||||
|
auto elem_size = InlineSize(vector_type);
|
||||||
|
code += Indent + "data = list(data)\n";
|
||||||
|
code += Indent + "builder.StartVector(" + NumToString(elem_size) +
|
||||||
|
", len(data), " + NumToString(alignment) + ")\n";
|
||||||
|
code += Indent + "for item in reversed(data):\n";
|
||||||
|
if (is_struct_vector) {
|
||||||
|
code += Indent + Indent + "item.Pack(builder)\n";
|
||||||
|
} else {
|
||||||
|
code += Indent + Indent + "builder.Prepend" +
|
||||||
|
namer_.Method(GenTypeBasic(vector_type)) + "(item)\n";
|
||||||
|
}
|
||||||
|
code += Indent + "return builder.EndVector()\n\n";
|
||||||
|
} else {
|
||||||
|
code += Indent + "return builder.CreateVectorOfTables(data)\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
|
||||||
|
if (parser_.opts.python_typing) {
|
||||||
|
code += "def Create" + field_method +
|
||||||
|
"Vector(builder: flatbuffers.Builder, data: Iterable[Any]) "
|
||||||
|
"-> int:\n";
|
||||||
|
} else {
|
||||||
|
code += "def Create" + field_method + "Vector(builder, data):\n";
|
||||||
|
}
|
||||||
|
code += Indent + "return " + helper_name + "(builder, data)\n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set the value of one of the members of a table's vector and fills in the
|
// Set the value of one of the members of a table's vector and fills in the
|
||||||
// elements from a bytearray. This is for simplifying the use of nested
|
// elements from a bytearray. This is for simplifying the use of nested
|
||||||
// flatbuffers.
|
// flatbuffers.
|
||||||
@@ -1614,8 +1682,8 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate table constructors, conditioned on its members' types.
|
// Generate table constructors, conditioned on its members' types.
|
||||||
void GenTableBuilders(const StructDef& struct_def,
|
void GenTableBuilders(const StructDef& struct_def, std::string* code_ptr,
|
||||||
std::string* code_ptr) const {
|
ImportMap& imports) const {
|
||||||
GetStartOfTable(struct_def, code_ptr);
|
GetStartOfTable(struct_def, code_ptr);
|
||||||
|
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
@@ -1627,6 +1695,7 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
BuildFieldOfTable(struct_def, field, offset, code_ptr);
|
BuildFieldOfTable(struct_def, field, offset, code_ptr);
|
||||||
if (IsVector(field.value.type)) {
|
if (IsVector(field.value.type)) {
|
||||||
BuildVectorOfTable(struct_def, field, code_ptr);
|
BuildVectorOfTable(struct_def, field, code_ptr);
|
||||||
|
BuildVectorCreationHelper(struct_def, field, code_ptr, imports);
|
||||||
BuildVectorOfTableFromBytes(struct_def, field, code_ptr);
|
BuildVectorOfTableFromBytes(struct_def, field, code_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1693,7 +1762,7 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
GenStructBuilder(struct_def, code_ptr);
|
GenStructBuilder(struct_def, code_ptr);
|
||||||
} else {
|
} else {
|
||||||
// Creates a set of functions that allow table construction.
|
// Creates a set of functions that allow table construction.
|
||||||
GenTableBuilders(struct_def, code_ptr);
|
GenTableBuilders(struct_def, code_ptr, imports);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2026,12 +2095,12 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
const auto field_method = namer_.Method(field);
|
const auto field_method = namer_.Method(field);
|
||||||
const auto struct_var = namer_.Variable(struct_def);
|
const auto struct_var = namer_.Variable(struct_def);
|
||||||
const EnumDef& enum_def = *field.value.type.enum_def;
|
const EnumDef& enum_def = *field.value.type.enum_def;
|
||||||
auto union_type = namer_.Type(enum_def);
|
auto union_fn = namer_.Function(enum_def);
|
||||||
|
|
||||||
if (parser_.opts.include_dependence_headers) {
|
if (parser_.opts.include_dependence_headers) {
|
||||||
union_type = namer_.NamespacedType(enum_def) + "." + union_type;
|
union_fn = namer_.NamespacedType(enum_def) + "." + union_fn;
|
||||||
}
|
}
|
||||||
code += GenIndents(2) + "self." + field_field + " = " + union_type +
|
code += GenIndents(2) + "self." + field_field + " = " + union_fn +
|
||||||
"Creator(" + "self." + field_field + "Type, " + struct_var + "." +
|
"Creator(" + "self." + field_field + "Type, " + struct_var + "." +
|
||||||
field_method + "())";
|
field_method + "())";
|
||||||
}
|
}
|
||||||
@@ -2402,7 +2471,7 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
} else {
|
} else {
|
||||||
GenPackForScalarVectorFieldHelper(struct_def, field, code_prefix_ptr, 3);
|
GenPackForScalarVectorFieldHelper(struct_def, field, code_prefix_ptr, 3);
|
||||||
code_prefix += "(self." + field_field + "[i])";
|
code_prefix += "(self." + field_field + "[i])";
|
||||||
code_prefix += GenIndents(4) + field_field + " = builder.EndVector()";
|
code_prefix += GenIndents(3) + field_field + " = builder.EndVector()";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -47,6 +47,7 @@ static Namer::Config SwiftDefaultConfig() {
|
|||||||
/*object_suffix=*/"T",
|
/*object_suffix=*/"T",
|
||||||
/*keyword_prefix=*/"",
|
/*keyword_prefix=*/"",
|
||||||
/*keyword_suffix=*/"_",
|
/*keyword_suffix=*/"_",
|
||||||
|
/*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
|
||||||
/*filenames=*/Case::kKeep,
|
/*filenames=*/Case::kKeep,
|
||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
@@ -163,15 +164,14 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
bool generate() {
|
bool generate() {
|
||||||
code_.Clear();
|
code_.Clear();
|
||||||
code_.SetValue("ACCESS", "_accessor");
|
code_.SetValue("ACCESS", "_accessor");
|
||||||
code_.SetValue("TABLEOFFSET", "VTOFFSET");
|
code_.SetValue("TABLEOFFSET", "VT");
|
||||||
code_ += "// " + std::string(FlatBuffersGeneratedWarning());
|
code_ += "// " + std::string(FlatBuffersGeneratedWarning());
|
||||||
code_ += "// swiftlint:disable all";
|
code_ += "// swiftlint:disable all";
|
||||||
code_ += "// swiftformat:disable all\n";
|
code_ += "// swiftformat:disable all\n";
|
||||||
|
|
||||||
if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) {
|
if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) {
|
||||||
code_.SetValue("IMPLEMENTONLY", parser_.opts.swift_implementation_only
|
code_.SetValue("IMPLEMENTONLY",
|
||||||
? "@_implementationOnly "
|
parser_.opts.swift_implementation_only ? "internal " : "");
|
||||||
: "");
|
|
||||||
code_ += "#if canImport(Common)";
|
code_ += "#if canImport(Common)";
|
||||||
code_ += "{{IMPLEMENTONLY}}import Common";
|
code_ += "{{IMPLEMENTONLY}}import Common";
|
||||||
code_ += "#endif";
|
code_ += "#endif";
|
||||||
@@ -281,9 +281,16 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
NumToString(field.value.type.VectorType().fixed_length);
|
NumToString(field.value.type.VectorType().fixed_length);
|
||||||
code_.SetValue("FIXEDLENGTH", fixed_length);
|
code_.SetValue("FIXEDLENGTH", fixed_length);
|
||||||
|
|
||||||
const auto vector_base_type = IsStruct(field.value.type.VectorType())
|
std::string vector_base_type;
|
||||||
? (type + "()")
|
if (IsStruct(field.value.type.VectorType())) {
|
||||||
: SwiftConstant(field);
|
vector_base_type = type + "()";
|
||||||
|
} else if (IsBool(field.value.type.VectorType().base_type)) {
|
||||||
|
vector_base_type = "false";
|
||||||
|
} else if (IsFloat(field.value.type.VectorType().base_type)) {
|
||||||
|
vector_base_type = "0.0";
|
||||||
|
} else {
|
||||||
|
vector_base_type = SwiftConstant(field);
|
||||||
|
}
|
||||||
code_ += "private var _{{FIELDVAR}}: InlineArray<{{FIXEDLENGTH}}, " +
|
code_ += "private var _{{FIELDVAR}}: InlineArray<{{FIXEDLENGTH}}, " +
|
||||||
valueType + ">";
|
valueType + ">";
|
||||||
|
|
||||||
@@ -517,7 +524,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
void GenTableAccessors(const StructDef& struct_def) {
|
void GenTableAccessors(const StructDef& struct_def) {
|
||||||
// Generate field id constants.
|
// Generate field id constants.
|
||||||
if (struct_def.fields.vec.size() > 0) {
|
if (struct_def.fields.vec.size() > 0) {
|
||||||
code_ += "private enum {{TABLEOFFSET}}: VOffset {";
|
code_ += "private struct {{TABLEOFFSET}} {";
|
||||||
Indent();
|
Indent();
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
@@ -527,10 +534,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
code_.SetValue("OFFSET_NAME", namer_.Variable(field));
|
code_.SetValue("OFFSET_NAME", namer_.Variable(field));
|
||||||
code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset));
|
code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset));
|
||||||
code_ += "case {{OFFSET_NAME}} = {{OFFSET_VALUE}}";
|
code_ += "static let {{OFFSET_NAME}}: VOffset = {{OFFSET_VALUE}}";
|
||||||
}
|
}
|
||||||
code_ += "var v: Int32 { Int32(self.rawValue) }";
|
|
||||||
code_ += "var p: VOffset { self.rawValue }";
|
|
||||||
Outdent();
|
Outdent();
|
||||||
code_ += "}";
|
code_ += "}";
|
||||||
code_ += "";
|
code_ += "";
|
||||||
@@ -543,13 +548,14 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_.SetValue("SHORT_STRUCTNAME", namer_.Type(struct_def));
|
code_.SetValue("SHORT_STRUCTNAME", namer_.Type(struct_def));
|
||||||
code_.SetValue("STRUCTNAME", namer_.NamespacedType(struct_def));
|
code_.SetValue("STRUCTNAME", namer_.NamespacedType(struct_def));
|
||||||
code_.SetValue("OBJECTTYPE", struct_def.fixed ? "Struct" : "Table");
|
code_.SetValue("OBJECTTYPE", struct_def.fixed ? "Struct" : "Table");
|
||||||
|
code_.SetValue("PROTOCOL", struct_def.fixed ? "FlatBufferStruct"
|
||||||
|
: "FlatBufferVerifiableTable");
|
||||||
code_.SetValue("MUTABLE", struct_def.fixed ? Mutable() : "");
|
code_.SetValue("MUTABLE", struct_def.fixed ? Mutable() : "");
|
||||||
|
|
||||||
GenOSVersionChecks();
|
GenOSVersionChecks();
|
||||||
code_ +=
|
code_ +=
|
||||||
"{{ACCESS_TYPE}} struct {{STRUCTNAME}}{{MUTABLE}}: "
|
"{{ACCESS_TYPE}} struct {{STRUCTNAME}}{{MUTABLE}}: "
|
||||||
"FlatBuffer{{OBJECTTYPE}}, FlatbuffersVectorInitializable\\";
|
"{{PROTOCOL}}, FlatbuffersVectorInitializable\\";
|
||||||
if (!struct_def.fixed) code_ += ", Verifiable\\";
|
|
||||||
if (!struct_def.fixed && parser_.opts.generate_object_based_api)
|
if (!struct_def.fixed && parser_.opts.generate_object_based_api)
|
||||||
code_ += ", ObjectAPIPacker\\";
|
code_ += ", ObjectAPIPacker\\";
|
||||||
code_ += " {\n";
|
code_ += " {\n";
|
||||||
@@ -619,7 +625,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
if (should_generate_create) {
|
if (should_generate_create) {
|
||||||
code_ += "{{ACCESS_TYPE}} static func create{{SHORT_STRUCTNAME}}(";
|
code_ += "{{ACCESS_TYPE}} static func create{{SHORT_STRUCTNAME}}(";
|
||||||
Indent();
|
Indent();
|
||||||
code_ += "_ fbb: inout FlatBufferBuilder,";
|
code_ += "_ fbb: inout FlatBufferBuilder\\";
|
||||||
|
if (create_func_header.empty() == false) code_ += ",";
|
||||||
for (auto it = create_func_header.begin(); it < create_func_header.end();
|
for (auto it = create_func_header.begin(); it < create_func_header.end();
|
||||||
++it) {
|
++it) {
|
||||||
code_ += *it + "\\";
|
code_ += *it + "\\";
|
||||||
@@ -698,7 +705,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += field.IsOptional() ? (optional_enum + "\\")
|
code_ += field.IsOptional() ? (optional_enum + "\\")
|
||||||
: (is_enum + ", def: {{CONSTANT}}\\");
|
: (is_enum + ", def: {{CONSTANT}}\\");
|
||||||
|
|
||||||
code_ += ", at: {{TABLEOFFSET}}.{{OFFSET}}.p) }";
|
code_ += ", at: {{TABLEOFFSET}}.{{OFFSET}}) }";
|
||||||
|
|
||||||
const auto default_value =
|
const auto default_value =
|
||||||
IsEnum(field.value.type)
|
IsEnum(field.value.type)
|
||||||
@@ -718,7 +725,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ +=
|
code_ +=
|
||||||
"{{VALUETYPE}}" + builder_string + "fbb.add(element: {{FIELDVAR}},\\";
|
"{{VALUETYPE}}" + builder_string + "fbb.add(element: {{FIELDVAR}},\\";
|
||||||
code_ += field.IsOptional() ? "\\" : " def: {{CONSTANT}},";
|
code_ += field.IsOptional() ? "\\" : " def: {{CONSTANT}},";
|
||||||
code_ += " at: {{TABLEOFFSET}}.{{OFFSET}}.p) }";
|
code_ += " at: {{TABLEOFFSET}}.{{OFFSET}}) }";
|
||||||
create_func_header.push_back(
|
create_func_header.push_back(
|
||||||
field_var + ": " + nullable_type + " = " +
|
field_var + ": " + nullable_type + " = " +
|
||||||
(field.IsOptional() ? "nil" : default_value));
|
(field.IsOptional() ? "nil" : default_value));
|
||||||
@@ -729,7 +736,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
const auto create_struct =
|
const auto create_struct =
|
||||||
"guard let {{FIELDVAR}} = {{FIELDVAR}} else { return };"
|
"guard let {{FIELDVAR}} = {{FIELDVAR}} else { return };"
|
||||||
" fbb.create(struct: {{FIELDVAR}}, position: "
|
" fbb.create(struct: {{FIELDVAR}}, position: "
|
||||||
"{{TABLEOFFSET}}.{{OFFSET}}.p) }";
|
"{{TABLEOFFSET}}.{{OFFSET}}) }";
|
||||||
code_ += type + "?" + builder_string + create_struct;
|
code_ += type + "?" + builder_string + create_struct;
|
||||||
/// Optional hard coded since structs are always optional
|
/// Optional hard coded since structs are always optional
|
||||||
create_func_header.push_back(field_var + ": " + type +
|
create_func_header.push_back(field_var + ": " + type +
|
||||||
@@ -746,8 +753,9 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
(field.IsRequired() ? "" : " = Offset()"));
|
(field.IsRequired() ? "" : " = Offset()"));
|
||||||
const auto reader_type =
|
const auto reader_type =
|
||||||
IsStruct(field.value.type) && field.value.type.struct_def->fixed
|
IsStruct(field.value.type) && field.value.type.struct_def->fixed
|
||||||
? "structOffset: {{TABLEOFFSET}}.{{OFFSET}}.p) }"
|
? "structOffset: {{TABLEOFFSET}}.{{OFFSET}}) }"
|
||||||
: "offset: {{FIELDVAR}}, at: {{TABLEOFFSET}}.{{OFFSET}}.p) }";
|
: "offset: {{FIELDVAR}}, at: {{TABLEOFFSET}}.{{OFFSET}}) "
|
||||||
|
"}";
|
||||||
code_ += "Offset" + builder_string + "fbb.add(" + reader_type;
|
code_ += "Offset" + builder_string + "fbb.add(" + reader_type;
|
||||||
|
|
||||||
const auto vectortype = field.value.type.VectorType();
|
const auto vectortype = field.value.type.VectorType();
|
||||||
@@ -851,7 +859,10 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BASE_TYPE_STRING: {
|
case BASE_TYPE_STRING: {
|
||||||
const auto default_string = "\"" + SwiftConstant(field) + "\"";
|
const auto sc = SwiftConstant(field);
|
||||||
|
std::string default_string;
|
||||||
|
flatbuffers::EscapeString(sc.c_str(), sc.length(), &default_string,
|
||||||
|
true, false);
|
||||||
code_.SetValue("VALUETYPE", GenType(field.value.type));
|
code_.SetValue("VALUETYPE", GenType(field.value.type));
|
||||||
code_.SetValue("CONSTANT", field.IsDefault() ? default_string : "nil");
|
code_.SetValue("CONSTANT", field.IsDefault() ? default_string : "nil");
|
||||||
code_ += GenReaderMainBody(is_required) + GenOffset() +
|
code_ += GenReaderMainBody(is_required) + GenOffset() +
|
||||||
@@ -859,7 +870,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "{{ACCESS_TYPE}} var {{FIELDVAR}}SegmentArray: [UInt8]" +
|
code_ += "{{ACCESS_TYPE}} var {{FIELDVAR}}SegmentArray: [UInt8]" +
|
||||||
is_required +
|
is_required +
|
||||||
" { return "
|
" { return "
|
||||||
"{{ACCESS}}.getVector(at: {{TABLEOFFSET}}.{{OFFSET}}.v) }";
|
"{{ACCESS}}.getVector(at: {{TABLEOFFSET}}.{{OFFSET}}) }";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_ARRAY:
|
case BASE_TYPE_ARRAY:
|
||||||
@@ -893,7 +904,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ +=
|
code_ +=
|
||||||
"{{ACCESS_TYPE}} var {{FIELDVAR}}: "
|
"{{ACCESS_TYPE}} var {{FIELDVAR}}: "
|
||||||
"FlatbufferVector<{{VALUETYPE}}> "
|
"FlatbufferVector<{{VALUETYPE}}> "
|
||||||
"{ return {{ACCESS}}.vector(at: {{TABLEOFFSET}}.{{OFFSET}}.v, "
|
"{ return {{ACCESS}}.vector(at: {{TABLEOFFSET}}.{{OFFSET}}, "
|
||||||
"byteSize: {{SIZE}}) }";
|
"byteSize: {{SIZE}}) }";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -910,7 +921,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ +=
|
code_ +=
|
||||||
"{{ACCESS_TYPE}} var {{FIELDVAR}}: "
|
"{{ACCESS_TYPE}} var {{FIELDVAR}}: "
|
||||||
"FlatbufferVector<{{VALUETYPE}}_Mutable> "
|
"FlatbufferVector<{{VALUETYPE}}_Mutable> "
|
||||||
"{ return {{ACCESS}}.vector(at: {{TABLEOFFSET}}.{{OFFSET}}.v, "
|
"{ return {{ACCESS}}.vector(at: {{TABLEOFFSET}}.{{OFFSET}}, "
|
||||||
"byteSize: {{SIZE}}) }";
|
"byteSize: {{SIZE}}) }";
|
||||||
GenUnsafeBufferPointer(field);
|
GenUnsafeBufferPointer(field);
|
||||||
return;
|
return;
|
||||||
@@ -919,7 +930,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
if (vectortype.base_type == BASE_TYPE_UNION) {
|
if (vectortype.base_type == BASE_TYPE_UNION) {
|
||||||
code_ +=
|
code_ +=
|
||||||
"{{ACCESS_TYPE}} var {{FIELDVAR}}: UnionFlatbufferVector "
|
"{{ACCESS_TYPE}} var {{FIELDVAR}}: UnionFlatbufferVector "
|
||||||
"{ return {{ACCESS}}.unionVector(at: {{TABLEOFFSET}}.{{OFFSET}}.v, "
|
"{ return {{ACCESS}}.unionVector(at: "
|
||||||
|
"{{TABLEOFFSET}}.{{OFFSET}}, "
|
||||||
"byteSize: {{SIZE}}) }";
|
"byteSize: {{SIZE}}) }";
|
||||||
code_ +=
|
code_ +=
|
||||||
"{{ACCESS_TYPE}} func {{FIELDVAR}}<T: FlatbuffersInitializable>(at "
|
"{{ACCESS_TYPE}} func {{FIELDVAR}}<T: FlatbuffersInitializable>(at "
|
||||||
@@ -953,24 +965,21 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
"{{ACCESS_TYPE}} func {{functionName}}<T>(_ body: "
|
"{{ACCESS_TYPE}} func {{functionName}}<T>(_ body: "
|
||||||
"(UnsafeRawBufferPointer, Int) throws -> T) rethrows -> T? { return "
|
"(UnsafeRawBufferPointer, Int) throws -> T) rethrows -> T? { return "
|
||||||
"try "
|
"try "
|
||||||
"{{ACCESS}}.withUnsafePointerToSlice(at: {{TABLEOFFSET}}.{{OFFSET}}.v, "
|
"{{ACCESS}}.withUnsafePointerToSlice(at: "
|
||||||
|
"{{TABLEOFFSET}}.{{OFFSET}}, "
|
||||||
"body: body) }";
|
"body: body) }";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateCodingKeys(const StructDef& struct_def) {
|
std::vector<std::string> GenerateCodingKeys(const StructDef& struct_def) {
|
||||||
code_ += "enum CodingKeys: String, CodingKey {";
|
std::vector<std::string> coding_keys;
|
||||||
Indent();
|
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto& field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
|
coding_keys.push_back("case " + namer_.Variable(field) + " = \"" +
|
||||||
code_.SetValue("RAWVALUENAME", field.name);
|
field.name + "\"");
|
||||||
code_.SetValue("FIELDVAR", namer_.Variable(field));
|
|
||||||
code_ += "case {{FIELDVAR}} = \"{{RAWVALUENAME}}\"";
|
|
||||||
}
|
}
|
||||||
Outdent();
|
return coding_keys;
|
||||||
code_ += "}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateEncoderUnionBody(const FieldDef& field) {
|
void GenerateEncoderUnionBody(const FieldDef& field) {
|
||||||
@@ -1092,14 +1101,31 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
GenOSVersionChecks();
|
GenOSVersionChecks();
|
||||||
code_ += "extension {{STRUCTNAME}}: Encodable {";
|
code_ += "extension {{STRUCTNAME}}: Encodable {";
|
||||||
Indent();
|
Indent();
|
||||||
code_ += "";
|
auto coding_keys = GenerateCodingKeys(struct_def);
|
||||||
if (struct_def.fields.vec.empty() == false) GenerateCodingKeys(struct_def);
|
|
||||||
|
if (coding_keys.empty() == false) {
|
||||||
|
code_ += "enum CodingKeys: String, CodingKey {";
|
||||||
|
Indent();
|
||||||
|
for (auto it = coding_keys.begin(); it != coding_keys.end(); ++it) {
|
||||||
|
const auto& field = *it;
|
||||||
|
code_ += field;
|
||||||
|
}
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
|
||||||
|
code_ += "";
|
||||||
|
}
|
||||||
|
|
||||||
code_ += "{{ACCESS_TYPE}} func encode(to encoder: Encoder) throws {";
|
code_ += "{{ACCESS_TYPE}} func encode(to encoder: Encoder) throws {";
|
||||||
Indent();
|
|
||||||
if (struct_def.fields.vec.empty() == false) GenerateEncoderBody(struct_def);
|
if (coding_keys.empty() == false) {
|
||||||
Outdent();
|
Indent();
|
||||||
|
GenerateEncoderBody(struct_def);
|
||||||
|
Outdent();
|
||||||
|
}
|
||||||
|
|
||||||
code_ += "}";
|
code_ += "}";
|
||||||
|
|
||||||
Outdent();
|
Outdent();
|
||||||
code_ += "}";
|
code_ += "}";
|
||||||
code_ += "";
|
code_ += "";
|
||||||
@@ -1129,7 +1155,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
code_ +=
|
code_ +=
|
||||||
"try _v.visit(field: {{TABLEOFFSET}}.{{OFFSET}}.p, fieldName: "
|
"try _v.visit(field: {{TABLEOFFSET}}.{{OFFSET}}, fieldName: "
|
||||||
"\"{{FIELDVAR}}\", required: {{ISREQUIRED}}, type: "
|
"\"{{FIELDVAR}}\", required: {{ISREQUIRED}}, type: "
|
||||||
"{{VALUETYPE}}.self)";
|
"{{VALUETYPE}}.self)";
|
||||||
}
|
}
|
||||||
@@ -1149,8 +1175,9 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_.SetValue("VALUETYPE", namer_.NamespacedType(union_def));
|
code_.SetValue("VALUETYPE", namer_.NamespacedType(union_def));
|
||||||
code_.SetValue("FUNCTION_NAME", is_vector ? "visitUnionVector" : "visit");
|
code_.SetValue("FUNCTION_NAME", is_vector ? "visitUnionVector" : "visit");
|
||||||
code_ +=
|
code_ +=
|
||||||
"try _v.{{FUNCTION_NAME}}(unionKey: {{TABLEOFFSET}}.{{OFFSET}}Type.p, "
|
"try _v.{{FUNCTION_NAME}}(unionKey: "
|
||||||
"unionField: {{TABLEOFFSET}}.{{OFFSET}}.p, unionKeyName: "
|
"{{TABLEOFFSET}}.{{OFFSET}}Type, "
|
||||||
|
"unionField: {{TABLEOFFSET}}.{{OFFSET}}, unionKeyName: "
|
||||||
"\"{{FIELDVAR}}Type\", fieldName: \"{{FIELDVAR}}\", required: "
|
"\"{{FIELDVAR}}Type\", fieldName: \"{{FIELDVAR}}\", required: "
|
||||||
"{{ISREQUIRED}}, completion: { (verifier, key: {{VALUETYPE}}, pos) in";
|
"{{ISREQUIRED}}, completion: { (verifier, key: {{VALUETYPE}}, pos) in";
|
||||||
Indent();
|
Indent();
|
||||||
@@ -1625,15 +1652,23 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
buffer_constructor.push_back(field_var + " = _t." + field_field);
|
buffer_constructor.push_back(field_var + " = _t." + field_field);
|
||||||
|
|
||||||
if (field.IsRequired()) {
|
if (field.IsRequired()) {
|
||||||
std::string default_value =
|
std::string default_value;
|
||||||
field.IsDefault() ? SwiftConstant(field) : "";
|
if (field.IsDefault()) {
|
||||||
base_constructor.push_back(field_var + " = \"" + default_value +
|
const auto sc = SwiftConstant(field);
|
||||||
"\"");
|
flatbuffers::EscapeString(sc.c_str(), sc.length(), &default_value,
|
||||||
|
true, false);
|
||||||
|
} else {
|
||||||
|
default_value = "\"\"";
|
||||||
|
}
|
||||||
|
base_constructor.push_back(field_var + " = " + default_value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (field.IsDefault() && !field.IsRequired()) {
|
if (field.IsDefault() && !field.IsRequired()) {
|
||||||
std::string value = field.IsDefault() ? SwiftConstant(field) : "nil";
|
const auto sc = SwiftConstant(field);
|
||||||
base_constructor.push_back(field_var + " = \"" + value + "\"");
|
std::string value;
|
||||||
|
flatbuffers::EscapeString(sc.c_str(), sc.length(), &value,
|
||||||
|
true, false);
|
||||||
|
base_constructor.push_back(field_var + " = " + value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1892,7 +1927,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string GenOffset() {
|
std::string GenOffset() {
|
||||||
return "let o = {{ACCESS}}.offset({{TABLEOFFSET}}.{{OFFSET}}.v); ";
|
return "let o = {{ACCESS}}.offset({{TABLEOFFSET}}.{{OFFSET}}); ";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenReaderMainBody(const std::string& optional = "") {
|
std::string GenReaderMainBody(const std::string& optional = "") {
|
||||||
@@ -1962,7 +1997,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
std::string GenType(const Type& type,
|
std::string GenType(const Type& type,
|
||||||
const bool should_consider_suffix = false) const {
|
const bool should_consider_suffix = false) const {
|
||||||
return IsScalar(type.base_type) ? GenTypeBasic(type)
|
return IsScalar(type.base_type) ? GenTypeBasic(type)
|
||||||
: IsArray(type) ? GenType(type.VectorType())
|
: IsArray(type) ? GenType(type.VectorType())
|
||||||
: GenTypePointer(type, should_consider_suffix);
|
: GenTypePointer(type, should_consider_suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ Namer::Config TypeScriptDefaultConfig() {
|
|||||||
/*object_suffix=*/"T",
|
/*object_suffix=*/"T",
|
||||||
/*keyword_prefix=*/"",
|
/*keyword_prefix=*/"",
|
||||||
/*keyword_suffix=*/"_",
|
/*keyword_suffix=*/"_",
|
||||||
|
/*keywords_casing=*/Namer::Config::KeywordsCasing::CaseSensitive,
|
||||||
/*filenames=*/Case::kDasher,
|
/*filenames=*/Case::kDasher,
|
||||||
/*directories=*/Case::kDasher,
|
/*directories=*/Case::kDasher,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
@@ -86,6 +87,7 @@ std::set<std::string> TypescriptKeywords() {
|
|||||||
"throw", "true", "try", "typeof", "var", "void",
|
"throw", "true", "try", "typeof", "var", "void",
|
||||||
"while", "with", "as", "implements", "interface", "let",
|
"while", "with", "as", "implements", "interface", "let",
|
||||||
"package", "private", "protected", "public", "static", "yield",
|
"package", "private", "protected", "public", "static", "yield",
|
||||||
|
"undefined" // Used with --ts-undefined-for-optionals
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +112,9 @@ class TsGenerator : public BaseGenerator {
|
|||||||
const std::string& file_name)
|
const std::string& file_name)
|
||||||
: BaseGenerator(parser, path, file_name, "", "_", "ts"),
|
: BaseGenerator(parser, path, file_name, "", "_", "ts"),
|
||||||
namer_(WithFlagOptions(TypeScriptDefaultConfig(), parser.opts, path),
|
namer_(WithFlagOptions(TypeScriptDefaultConfig(), parser.opts, path),
|
||||||
TypescriptKeywords()) {}
|
TypescriptKeywords()),
|
||||||
|
null_keyword_(parser_.opts.ts_undefined_for_optionals ? "undefined"
|
||||||
|
: "null") {}
|
||||||
|
|
||||||
bool generate() {
|
bool generate() {
|
||||||
generateEnums();
|
generateEnums();
|
||||||
@@ -214,6 +218,8 @@ class TsGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
std::map<std::string, NsDefinition> ns_defs_;
|
std::map<std::string, NsDefinition> ns_defs_;
|
||||||
|
|
||||||
|
std::string null_keyword_;
|
||||||
|
|
||||||
// Generate code for all enums.
|
// Generate code for all enums.
|
||||||
void generateEnums() {
|
void generateEnums() {
|
||||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
@@ -318,9 +324,10 @@ class TsGenerator : public BaseGenerator {
|
|||||||
export_counter++;
|
export_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (export_counter > 0)
|
if (export_counter > 0) {
|
||||||
parser_.opts.file_saver->SaveFile(it.second.filepath.c_str(), code,
|
parser_.opts.file_saver->SaveFile(it.second.filepath.c_str(), code,
|
||||||
false);
|
false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,7 +474,7 @@ class TsGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
std::string GenDefaultValue(const FieldDef& field, import_set& imports) {
|
std::string GenDefaultValue(const FieldDef& field, import_set& imports) {
|
||||||
if (field.IsScalarOptional()) {
|
if (field.IsScalarOptional()) {
|
||||||
return "null";
|
return null_keyword_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& value = field.value;
|
const auto& value = field.value;
|
||||||
@@ -515,10 +522,23 @@ class TsGenerator : public BaseGenerator {
|
|||||||
case BASE_TYPE_BOOL:
|
case BASE_TYPE_BOOL:
|
||||||
return value.constant == "0" ? "false" : "true";
|
return value.constant == "0" ? "false" : "true";
|
||||||
|
|
||||||
case BASE_TYPE_STRING:
|
case BASE_TYPE_STRING: {
|
||||||
|
// NOTE: Strings without a default value are parsed as "0" by
|
||||||
|
// the parser, so therefore we have to treat "0" as a null-signifying
|
||||||
|
// value.
|
||||||
|
if (value.constant == "0" || value.constant == "null") {
|
||||||
|
return "null";
|
||||||
|
} else {
|
||||||
|
std::string escaped;
|
||||||
|
flatbuffers::EscapeString(value.constant.c_str(),
|
||||||
|
value.constant.length(), &escaped,
|
||||||
|
true, false);
|
||||||
|
return escaped;
|
||||||
|
}
|
||||||
|
}
|
||||||
case BASE_TYPE_UNION:
|
case BASE_TYPE_UNION:
|
||||||
case BASE_TYPE_STRUCT: {
|
case BASE_TYPE_STRUCT: {
|
||||||
return "null";
|
return null_keyword_;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BASE_TYPE_ARRAY:
|
case BASE_TYPE_ARRAY:
|
||||||
@@ -554,16 +574,16 @@ class TsGenerator : public BaseGenerator {
|
|||||||
} else {
|
} else {
|
||||||
name = AddImport(imports, owner, *type.struct_def).name;
|
name = AddImport(imports, owner, *type.struct_def).name;
|
||||||
}
|
}
|
||||||
return allowNull ? (name + "|null") : name;
|
return allowNull ? (name + "|" + null_keyword_) : name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_BOOL:
|
case BASE_TYPE_BOOL:
|
||||||
return allowNull ? "boolean|null" : "boolean";
|
return allowNull ? ("boolean|" + null_keyword_) : "boolean";
|
||||||
case BASE_TYPE_LONG:
|
case BASE_TYPE_LONG:
|
||||||
case BASE_TYPE_ULONG:
|
case BASE_TYPE_ULONG:
|
||||||
return allowNull ? "bigint|null" : "bigint";
|
return allowNull ? ("bigint|" + null_keyword_) : "bigint";
|
||||||
case BASE_TYPE_ARRAY: {
|
case BASE_TYPE_ARRAY: {
|
||||||
std::string name;
|
std::string name;
|
||||||
if (type.element == BASE_TYPE_LONG || type.element == BASE_TYPE_ULONG) {
|
if (type.element == BASE_TYPE_LONG || type.element == BASE_TYPE_ULONG) {
|
||||||
@@ -578,16 +598,16 @@ class TsGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return name + (allowNull ? "|null" : "");
|
return name + (allowNull ? ("|" + null_keyword_) : "");
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if (IsScalar(type.base_type)) {
|
if (IsScalar(type.base_type)) {
|
||||||
if (type.enum_def) {
|
if (type.enum_def) {
|
||||||
const auto enum_name =
|
const auto enum_name =
|
||||||
AddImport(imports, owner, *type.enum_def).name;
|
AddImport(imports, owner, *type.enum_def).name;
|
||||||
return allowNull ? (enum_name + "|null") : enum_name;
|
return allowNull ? (enum_name + "|" + null_keyword_) : enum_name;
|
||||||
}
|
}
|
||||||
return allowNull ? "number|null" : "number";
|
return allowNull ? ("number|" + null_keyword_) : "number";
|
||||||
}
|
}
|
||||||
return "flatbuffers.Offset";
|
return "flatbuffers.Offset";
|
||||||
}
|
}
|
||||||
@@ -641,7 +661,8 @@ class TsGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GenStructArgs(import_set& imports, const StructDef& struct_def,
|
void GenStructArgs(import_set& imports, const StructDef& struct_def,
|
||||||
std::string* arguments, const std::string& nameprefix) {
|
const Definition& owner, std::string* arguments,
|
||||||
|
const std::string& nameprefix) {
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto& field = **it;
|
auto& field = **it;
|
||||||
@@ -649,11 +670,11 @@ class TsGenerator : public BaseGenerator {
|
|||||||
// Generate arguments for a struct inside a struct. To ensure names
|
// Generate arguments for a struct inside a struct. To ensure names
|
||||||
// don't clash, and to make it obvious these arguments are constructing
|
// don't clash, and to make it obvious these arguments are constructing
|
||||||
// a nested struct, prefix the name with the field name.
|
// a nested struct, prefix the name with the field name.
|
||||||
GenStructArgs(imports, *field.value.type.struct_def, arguments,
|
GenStructArgs(imports, *field.value.type.struct_def, owner, arguments,
|
||||||
nameprefix + field.name + "_");
|
nameprefix + field.name + "_");
|
||||||
} else {
|
} else {
|
||||||
*arguments += ", " + nameprefix + field.name + ": " +
|
*arguments += ", " + nameprefix + field.name + ": " +
|
||||||
GenTypeName(imports, field, field.value.type, true,
|
GenTypeName(imports, owner, field.value.type, true,
|
||||||
field.IsOptional());
|
field.IsOptional());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -915,6 +936,48 @@ class TsGenerator : public BaseGenerator {
|
|||||||
return symbols_expression;
|
return symbols_expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> PathComponents(const std::string& path) const {
|
||||||
|
std::vector<std::string> components;
|
||||||
|
size_t start = 0;
|
||||||
|
while (start < path.size()) {
|
||||||
|
auto end = path.find(kPathSeparator, start);
|
||||||
|
if (end == std::string::npos) end = path.size();
|
||||||
|
if (end > start) {
|
||||||
|
components.emplace_back(path.substr(start, end - start));
|
||||||
|
}
|
||||||
|
if (end == path.size()) break;
|
||||||
|
start = end + 1;
|
||||||
|
}
|
||||||
|
return components;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RelativeDirectory(const std::vector<std::string>& from,
|
||||||
|
const std::vector<std::string>& to) const {
|
||||||
|
size_t common = 0;
|
||||||
|
while (common < from.size() && common < to.size() &&
|
||||||
|
from[common] == to[common]) {
|
||||||
|
++common;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string rel;
|
||||||
|
const size_t ups = from.size() - common;
|
||||||
|
if (ups == 0) {
|
||||||
|
rel = ".";
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < ups; ++i) {
|
||||||
|
if (!rel.empty()) rel += kPathSeparator;
|
||||||
|
rel += "..";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = common; i < to.size(); ++i) {
|
||||||
|
if (!rel.empty()) rel += kPathSeparator;
|
||||||
|
rel += to[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return rel;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename DefinitionT>
|
template <typename DefinitionT>
|
||||||
ImportDefinition AddImport(import_set& imports, const Definition& dependent,
|
ImportDefinition AddImport(import_set& imports, const Definition& dependent,
|
||||||
const DefinitionT& dependency) {
|
const DefinitionT& dependency) {
|
||||||
@@ -942,26 +1005,32 @@ class TsGenerator : public BaseGenerator {
|
|||||||
const std::string symbols_expression = GenSymbolExpression(
|
const std::string symbols_expression = GenSymbolExpression(
|
||||||
dependency, has_name_clash, import_name, name, object_name);
|
dependency, has_name_clash, import_name, name, object_name);
|
||||||
|
|
||||||
std::string bare_file_path;
|
const Namespace* dependent_ns = dependent.defined_namespace
|
||||||
std::string rel_file_path;
|
? dependent.defined_namespace
|
||||||
if (dependent.defined_namespace) {
|
: parser_.empty_namespace_;
|
||||||
const auto& dep_comps = dependent.defined_namespace->components;
|
const Namespace* dependency_ns = dependency.defined_namespace
|
||||||
for (size_t i = 0; i < dep_comps.size(); i++) {
|
? dependency.defined_namespace
|
||||||
rel_file_path += i == 0 ? ".." : (kPathSeparator + std::string(".."));
|
: parser_.empty_namespace_;
|
||||||
}
|
|
||||||
if (dep_comps.size() == 0) {
|
|
||||||
rel_file_path += ".";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rel_file_path += "..";
|
|
||||||
}
|
|
||||||
|
|
||||||
bare_file_path +=
|
const std::string dependent_dirs =
|
||||||
kPathSeparator +
|
namer_.Directories(*dependent_ns, SkipDir::OutputPath);
|
||||||
namer_.Directories(dependency.defined_namespace->components,
|
const std::string dependency_dirs =
|
||||||
SkipDir::OutputPath) +
|
namer_.Directories(*dependency_ns, SkipDir::OutputPath);
|
||||||
|
|
||||||
|
const auto dependent_components = PathComponents(dependent_dirs);
|
||||||
|
const auto dependency_components = PathComponents(dependency_dirs);
|
||||||
|
|
||||||
|
std::string rel_dir =
|
||||||
|
RelativeDirectory(dependent_components, dependency_components);
|
||||||
|
if (rel_dir.empty()) rel_dir = ".";
|
||||||
|
if (!rel_dir.empty()) rel_dir += kPathSeparator;
|
||||||
|
|
||||||
|
std::string rel_file_path =
|
||||||
|
rel_dir + namer_.File(dependency, SkipFile::SuffixAndExtension);
|
||||||
|
|
||||||
|
std::string bare_file_path =
|
||||||
|
kPathSeparator + dependency_dirs +
|
||||||
namer_.File(dependency, SkipFile::SuffixAndExtension);
|
namer_.File(dependency, SkipFile::SuffixAndExtension);
|
||||||
rel_file_path += bare_file_path;
|
|
||||||
|
|
||||||
ImportDefinition import;
|
ImportDefinition import;
|
||||||
import.name = name;
|
import.name = name;
|
||||||
@@ -1039,7 +1108,8 @@ class TsGenerator : public BaseGenerator {
|
|||||||
const auto& enum_def = *union_type.enum_def;
|
const auto& enum_def = *union_type.enum_def;
|
||||||
|
|
||||||
const auto valid_union_type = GenUnionTypeTS(enum_def, imports);
|
const auto valid_union_type = GenUnionTypeTS(enum_def, imports);
|
||||||
const auto valid_union_type_with_null = valid_union_type + "|null";
|
const auto valid_union_type_with_null =
|
||||||
|
valid_union_type + "|" + null_keyword_;
|
||||||
|
|
||||||
auto ret = "\n\nexport function " + GenUnionConvFuncName(enum_def) +
|
auto ret = "\n\nexport function " + GenUnionConvFuncName(enum_def) +
|
||||||
"(\n type: " + GetTypeName(enum_def) +
|
"(\n type: " + GetTypeName(enum_def) +
|
||||||
@@ -1051,7 +1121,7 @@ class TsGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
const auto union_enum_loop = [&](const std::string& accessor_str) {
|
const auto union_enum_loop = [&](const std::string& accessor_str) {
|
||||||
ret += " switch(" + enum_type + "[type]) {\n";
|
ret += " switch(" + enum_type + "[type]) {\n";
|
||||||
ret += " case 'NONE': return null; \n";
|
ret += " case 'NONE': return " + null_keyword_ + "; \n";
|
||||||
|
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
|
||||||
++it) {
|
++it) {
|
||||||
@@ -1075,7 +1145,7 @@ class TsGenerator : public BaseGenerator {
|
|||||||
ret += "\n";
|
ret += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
ret += " default: return null;\n";
|
ret += " default: return " + null_keyword_ + ";\n";
|
||||||
ret += " }\n";
|
ret += " }\n";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1120,7 +1190,8 @@ class TsGenerator : public BaseGenerator {
|
|||||||
ret += " const temp = " + conversion_function + "(this." +
|
ret += " const temp = " + conversion_function + "(this." +
|
||||||
namer_.Method(field_name, "Type") + "(), " +
|
namer_.Method(field_name, "Type") + "(), " +
|
||||||
field_binded_method + ");\n";
|
field_binded_method + ");\n";
|
||||||
ret += " if(temp === null) { return null; }\n";
|
ret += " if(temp === " + null_keyword_ + ") { return " +
|
||||||
|
null_keyword_ + "; }\n";
|
||||||
ret += union_has_string
|
ret += union_has_string
|
||||||
? " if(typeof temp === 'string') { return temp; }\n"
|
? " if(typeof temp === 'string') { return temp; }\n"
|
||||||
: "";
|
: "";
|
||||||
@@ -1140,12 +1211,12 @@ class TsGenerator : public BaseGenerator {
|
|||||||
"++targetEnumIndex) {\n";
|
"++targetEnumIndex) {\n";
|
||||||
ret += " const targetEnum = this." +
|
ret += " const targetEnum = this." +
|
||||||
namer_.Method(field_name, "Type") + "(targetEnumIndex);\n";
|
namer_.Method(field_name, "Type") + "(targetEnumIndex);\n";
|
||||||
ret += " if(targetEnum === null || " + enum_type +
|
ret += " if(targetEnum === " + null_keyword_ + " || " + enum_type +
|
||||||
"[targetEnum!] === 'NONE') { "
|
"[targetEnum!] === 'NONE') { "
|
||||||
"continue; }\n\n";
|
"continue; }\n\n";
|
||||||
ret += " const temp = " + conversion_function + "(targetEnum, " +
|
ret += " const temp = " + conversion_function + "(targetEnum, " +
|
||||||
field_binded_method + ", targetEnumIndex);\n";
|
field_binded_method + ", targetEnumIndex);\n";
|
||||||
ret += " if(temp === null) { continue; }\n";
|
ret += " if(temp === " + null_keyword_ + ") { continue; }\n";
|
||||||
ret += union_has_string ? " if(typeof temp === 'string') { "
|
ret += union_has_string ? " if(typeof temp === 'string') { "
|
||||||
"ret.push(temp); continue; }\n"
|
"ret.push(temp); continue; }\n"
|
||||||
: "";
|
: "";
|
||||||
@@ -1162,11 +1233,12 @@ class TsGenerator : public BaseGenerator {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenNullCheckConditional(
|
std::string GenNullCheckConditional(const std::string& nullCheckVar,
|
||||||
const std::string& nullCheckVar, const std::string& trueVal,
|
const std::string& trueVal,
|
||||||
const std::string& falseVal = "null") {
|
const std::string& falseVal = "") {
|
||||||
return "(" + nullCheckVar + " !== null ? " + trueVal + " : " + falseVal +
|
std::string false_val = falseVal.empty() ? null_keyword_ : falseVal;
|
||||||
")";
|
return "(" + nullCheckVar + " !== " + null_keyword_ + " ? " + trueVal +
|
||||||
|
" : " + false_val + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenStructMemberValueTS(const StructDef& struct_def,
|
std::string GenStructMemberValueTS(const StructDef& struct_def,
|
||||||
@@ -1275,10 +1347,9 @@ class TsGenerator : public BaseGenerator {
|
|||||||
// Emit a scalar field
|
// Emit a scalar field
|
||||||
const auto is_string = IsString(field.value.type);
|
const auto is_string = IsString(field.value.type);
|
||||||
if (IsScalar(field.value.type.base_type) || is_string) {
|
if (IsScalar(field.value.type.base_type) || is_string) {
|
||||||
const auto has_null_default = is_string || HasNullDefault(field);
|
field_type +=
|
||||||
|
GenTypeName(imports, field, field.value.type, false,
|
||||||
field_type += GenTypeName(imports, field, field.value.type, false,
|
!HasDefaultValue(field) || HasNullDefault(field));
|
||||||
has_null_default);
|
|
||||||
field_val = "this." + namer_.Method(field) + "()";
|
field_val = "this." + namer_.Method(field) + "()";
|
||||||
|
|
||||||
if (field.value.type.base_type != BASE_TYPE_STRING) {
|
if (field.value.type.base_type != BASE_TYPE_STRING) {
|
||||||
@@ -1300,8 +1371,8 @@ class TsGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
const std::string field_accessor =
|
const std::string field_accessor =
|
||||||
"this." + namer_.Method(field) + "()";
|
"this." + namer_.Method(field) + "()";
|
||||||
field_val = GenNullCheckConditional(field_accessor,
|
field_val = GenNullCheckConditional(
|
||||||
field_accessor + "!.unpack()");
|
field_accessor, field_accessor + "!.unpack()", null_keyword_);
|
||||||
auto packing = GenNullCheckConditional(
|
auto packing = GenNullCheckConditional(
|
||||||
"this." + field_field,
|
"this." + field_field,
|
||||||
"this." + field_field + "!.pack(builder)", "0");
|
"this." + field_field + "!.pack(builder)", "0");
|
||||||
@@ -1509,8 +1580,8 @@ class TsGenerator : public BaseGenerator {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// length 0 vector is simply empty instead of null
|
// length 0 vector is simply empty instead of null/undefined.
|
||||||
field_type += is_vector ? "" : "|null";
|
field_type += is_vector ? "" : ("|" + null_keyword_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!field_offset_decl.empty()) {
|
if (!field_offset_decl.empty()) {
|
||||||
@@ -1539,7 +1610,7 @@ class TsGenerator : public BaseGenerator {
|
|||||||
} else {
|
} else {
|
||||||
if (field.IsScalarOptional()) {
|
if (field.IsScalarOptional()) {
|
||||||
pack_func_create_call +=
|
pack_func_create_call +=
|
||||||
" if (" + field_offset_val + " !== null)\n ";
|
" if (" + field_offset_val + " !== " + null_keyword_ + ")\n ";
|
||||||
}
|
}
|
||||||
pack_func_create_call += " " + struct_name + "." +
|
pack_func_create_call += " " + struct_name + "." +
|
||||||
namer_.Method("add", field) + "(builder, " +
|
namer_.Method("add", field) + "(builder, " +
|
||||||
@@ -1624,12 +1695,14 @@ class TsGenerator : public BaseGenerator {
|
|||||||
GenDocComment(struct_def.doc_comment, code_ptr);
|
GenDocComment(struct_def.doc_comment, code_ptr);
|
||||||
code += "export class ";
|
code += "export class ";
|
||||||
code += object_name;
|
code += object_name;
|
||||||
if (parser.opts.generate_object_based_api)
|
if (parser.opts.generate_object_based_api) {
|
||||||
code += " implements flatbuffers.IUnpackableObject<" + object_api_name +
|
code += " implements flatbuffers.IUnpackableObject<" + object_api_name +
|
||||||
"> {\n";
|
"> {\n";
|
||||||
else
|
} else {
|
||||||
code += " {\n";
|
code += " {\n";
|
||||||
code += " bb: flatbuffers.ByteBuffer|null = null;\n";
|
}
|
||||||
|
code += " bb: flatbuffers.ByteBuffer|" + null_keyword_ + " = " +
|
||||||
|
null_keyword_ + ";\n";
|
||||||
code += " bb_pos = 0;\n";
|
code += " bb_pos = 0;\n";
|
||||||
|
|
||||||
// Generate the __init method that sets the field in a pre-existing
|
// Generate the __init method that sets the field in a pre-existing
|
||||||
@@ -1670,21 +1743,22 @@ class TsGenerator : public BaseGenerator {
|
|||||||
offset_prefix = " const offset = " + GenBBAccess() +
|
offset_prefix = " const offset = " + GenBBAccess() +
|
||||||
".__offset(this.bb_pos, " +
|
".__offset(this.bb_pos, " +
|
||||||
NumToString(field.value.offset) + ");\n";
|
NumToString(field.value.offset) + ");\n";
|
||||||
offset_prefix += " return offset ? ";
|
offset_prefix += " return ";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit a scalar field
|
// Emit a scalar field
|
||||||
const auto is_string = IsString(field.value.type);
|
const auto is_string = IsString(field.value.type);
|
||||||
if (IsScalar(field.value.type.base_type) || is_string) {
|
if (IsScalar(field.value.type.base_type) || is_string) {
|
||||||
const auto has_null_default = is_string || HasNullDefault(field);
|
const auto has_null_default =
|
||||||
|
!field.IsRequired() && !HasDefaultValue(field);
|
||||||
|
|
||||||
GenDocComment(field.doc_comment, code_ptr);
|
GenDocComment(field.doc_comment, code_ptr);
|
||||||
std::string prefix = namer_.Method(field) + "(";
|
std::string prefix = namer_.Method(field) + "(";
|
||||||
if (is_string) {
|
if (is_string) {
|
||||||
code += prefix + "):string|null\n";
|
code += prefix + "):" + (has_null_default ? "string|" + null_keyword_ : "string") + "\n";
|
||||||
code +=
|
code +=
|
||||||
prefix + "optionalEncoding:flatbuffers.Encoding" + "):" +
|
prefix + "optionalEncoding:flatbuffers.Encoding" + "):" +
|
||||||
GenTypeName(imports, struct_def, field.value.type, false, true) +
|
GenTypeName(imports, struct_def, field.value.type, false, has_null_default) +
|
||||||
"\n";
|
"\n";
|
||||||
code += prefix + "optionalEncoding?:any";
|
code += prefix + "optionalEncoding?:any";
|
||||||
} else {
|
} else {
|
||||||
@@ -1713,9 +1787,16 @@ class TsGenerator : public BaseGenerator {
|
|||||||
if (is_string) {
|
if (is_string) {
|
||||||
index += ", optionalEncoding";
|
index += ", optionalEncoding";
|
||||||
}
|
}
|
||||||
code +=
|
if (field.IsRequired()) {
|
||||||
offset_prefix + GenGetter(field.value.type, "(" + index + ")");
|
code +=
|
||||||
if (field.value.type.base_type != BASE_TYPE_ARRAY) {
|
offset_prefix + GenGetter(field.value.type, "(" + index + ")");
|
||||||
|
;
|
||||||
|
} else {
|
||||||
|
code += offset_prefix + "offset ? " +
|
||||||
|
GenGetter(field.value.type, "(" + index + ")");
|
||||||
|
}
|
||||||
|
if (field.value.type.base_type != BASE_TYPE_ARRAY &&
|
||||||
|
!field.IsRequired()) {
|
||||||
code += " : " + GenDefaultValue(field, imports);
|
code += " : " + GenDefaultValue(field, imports);
|
||||||
}
|
}
|
||||||
code += ";\n";
|
code += ";\n";
|
||||||
@@ -1731,7 +1812,8 @@ class TsGenerator : public BaseGenerator {
|
|||||||
.name;
|
.name;
|
||||||
GenDocComment(field.doc_comment, code_ptr);
|
GenDocComment(field.doc_comment, code_ptr);
|
||||||
code += namer_.Method(field);
|
code += namer_.Method(field);
|
||||||
code += "(obj?:" + type + "):" + type + "|null {\n";
|
code +=
|
||||||
|
"(obj?:" + type + "):" + type + "|" + null_keyword_ + " {\n";
|
||||||
|
|
||||||
if (struct_def.fixed) {
|
if (struct_def.fixed) {
|
||||||
code += " return (obj || " + GenerateNewExpression(type);
|
code += " return (obj || " + GenerateNewExpression(type);
|
||||||
@@ -1739,12 +1821,12 @@ class TsGenerator : public BaseGenerator {
|
|||||||
code +=
|
code +=
|
||||||
MaybeAdd(field.value.offset) + ", " + GenBBAccess() + ");\n";
|
MaybeAdd(field.value.offset) + ", " + GenBBAccess() + ");\n";
|
||||||
} else {
|
} else {
|
||||||
code += offset_prefix + "(obj || " + GenerateNewExpression(type) +
|
code += offset_prefix + "offset ? (obj || " +
|
||||||
").__init(";
|
GenerateNewExpression(type) + ").__init(";
|
||||||
code += field.value.type.struct_def->fixed
|
code += field.value.type.struct_def->fixed
|
||||||
? "this.bb_pos + offset"
|
? "this.bb_pos + offset"
|
||||||
: GenBBAccess() + ".__indirect(this.bb_pos + offset)";
|
: GenBBAccess() + ".__indirect(this.bb_pos + offset)";
|
||||||
code += ", " + GenBBAccess() + ") : null;\n";
|
code += ", " + GenBBAccess() + ") : " + null_keyword_ + ";\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1797,7 +1879,7 @@ class TsGenerator : public BaseGenerator {
|
|||||||
} else {
|
} else {
|
||||||
code += prefix;
|
code += prefix;
|
||||||
}
|
}
|
||||||
code += "):" + vectortypename + "|null {\n";
|
code += "):" + vectortypename + "|" + null_keyword_ + " {\n";
|
||||||
|
|
||||||
if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
||||||
code += offset_prefix + "(obj || " +
|
code += offset_prefix + "(obj || " +
|
||||||
@@ -1837,7 +1919,7 @@ class TsGenerator : public BaseGenerator {
|
|||||||
code += " : 0";
|
code += " : 0";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
code += ": null";
|
code += ": " + null_keyword_;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1895,10 +1977,10 @@ class TsGenerator : public BaseGenerator {
|
|||||||
} else {
|
} else {
|
||||||
code += prefix;
|
code += prefix;
|
||||||
}
|
}
|
||||||
code += "):" + vectortypename + "|null {\n";
|
code += "):" + vectortypename + "|" + null_keyword_ + " {\n";
|
||||||
|
|
||||||
if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
||||||
code += offset_prefix + "(obj || " +
|
code += offset_prefix + "offset ? (obj || " +
|
||||||
GenerateNewExpression(vectortypename);
|
GenerateNewExpression(vectortypename);
|
||||||
code += ").__init(";
|
code += ").__init(";
|
||||||
code += vectortype.struct_def->fixed
|
code += vectortype.struct_def->fixed
|
||||||
@@ -1911,7 +1993,8 @@ class TsGenerator : public BaseGenerator {
|
|||||||
} else if (IsString(vectortype)) {
|
} else if (IsString(vectortype)) {
|
||||||
index += ", optionalEncoding";
|
index += ", optionalEncoding";
|
||||||
}
|
}
|
||||||
code += offset_prefix + GenGetter(vectortype, "(" + index + ")");
|
code += offset_prefix + "offset ? " +
|
||||||
|
GenGetter(vectortype, "(" + index + ")");
|
||||||
}
|
}
|
||||||
code += " : ";
|
code += " : ";
|
||||||
if (field.value.type.element == BASE_TYPE_BOOL) {
|
if (field.value.type.element == BASE_TYPE_BOOL) {
|
||||||
@@ -1921,12 +2004,12 @@ class TsGenerator : public BaseGenerator {
|
|||||||
code += "BigInt(0)";
|
code += "BigInt(0)";
|
||||||
} else if (IsScalar(field.value.type.element)) {
|
} else if (IsScalar(field.value.type.element)) {
|
||||||
if (field.value.type.enum_def) {
|
if (field.value.type.enum_def) {
|
||||||
code += "null";
|
code += null_keyword_;
|
||||||
} else {
|
} else {
|
||||||
code += "0";
|
code += "0";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
code += "null";
|
code += null_keyword_;
|
||||||
}
|
}
|
||||||
code += ";\n";
|
code += ";\n";
|
||||||
break;
|
break;
|
||||||
@@ -1939,13 +2022,13 @@ class TsGenerator : public BaseGenerator {
|
|||||||
const auto& union_enum = *(field.value.type.enum_def);
|
const auto& union_enum = *(field.value.type.enum_def);
|
||||||
const auto union_type = GenUnionGenericTypeTS(union_enum);
|
const auto union_type = GenUnionGenericTypeTS(union_enum);
|
||||||
code += "<T extends flatbuffers.Table>(obj:" + union_type +
|
code += "<T extends flatbuffers.Table>(obj:" + union_type +
|
||||||
"):" + union_type +
|
"):" + union_type + "|" + null_keyword_ +
|
||||||
"|null "
|
" "
|
||||||
"{\n";
|
"{\n";
|
||||||
|
|
||||||
code += offset_prefix +
|
code += offset_prefix + "offset ? " +
|
||||||
GenGetter(field.value.type, "(obj, this.bb_pos + offset)") +
|
GenGetter(field.value.type, "(obj, this.bb_pos + offset)") +
|
||||||
" : null;\n";
|
" : " + null_keyword_ + ";\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -1996,7 +2079,7 @@ class TsGenerator : public BaseGenerator {
|
|||||||
// Emit a length helper
|
// Emit a length helper
|
||||||
GenDocComment(code_ptr);
|
GenDocComment(code_ptr);
|
||||||
code += namer_.Method(field, "Length");
|
code += namer_.Method(field, "Length");
|
||||||
code += "():number {\n" + offset_prefix;
|
code += "():number {\n" + offset_prefix + "offset ? ";
|
||||||
|
|
||||||
code +=
|
code +=
|
||||||
GenBBAccess() + ".__vector_len(this.bb_pos + offset) : 0;\n}\n\n";
|
GenBBAccess() + ".__vector_len(this.bb_pos + offset) : 0;\n}\n\n";
|
||||||
@@ -2007,14 +2090,30 @@ class TsGenerator : public BaseGenerator {
|
|||||||
GenDocComment(code_ptr);
|
GenDocComment(code_ptr);
|
||||||
|
|
||||||
code += namer_.Method(field, "Array");
|
code += namer_.Method(field, "Array");
|
||||||
code +=
|
|
||||||
"():" + GenType(vectorType) + "Array|null {\n" + offset_prefix;
|
|
||||||
|
|
||||||
code += "new " + GenType(vectorType) + "Array(" + GenBBAccess() +
|
std::string return_type =
|
||||||
".bytes().buffer, " + GenBBAccess() +
|
(field.IsRequired() || HasDefaultValue(field))
|
||||||
".bytes().byteOffset + " + GenBBAccess() +
|
? "Array"
|
||||||
".__vector(this.bb_pos + offset), " + GenBBAccess() +
|
: ("Array|" + null_keyword_);
|
||||||
".__vector_len(this.bb_pos + offset)) : null;\n}\n\n";
|
if (field.IsRequired()) {
|
||||||
|
code += "():" + GenType(vectorType) + return_type + " {\n" +
|
||||||
|
offset_prefix + "new " + GenType(vectorType) + "Array(" +
|
||||||
|
GenBBAccess() + ".bytes().buffer, " + GenBBAccess() +
|
||||||
|
".bytes().byteOffset + " + GenBBAccess() +
|
||||||
|
".__vector(this.bb_pos + offset), " + GenBBAccess() +
|
||||||
|
".__vector_len(this.bb_pos + offset));\n}\n\n";
|
||||||
|
} else {
|
||||||
|
std::string value = HasDefaultValue(field)
|
||||||
|
? "new " + GenType(vectorType) + "Array()"
|
||||||
|
: "null";
|
||||||
|
code += "():" + GenType(vectorType) + return_type + " {\n" +
|
||||||
|
offset_prefix + "offset ? new " + GenType(vectorType) +
|
||||||
|
"Array(" + GenBBAccess() + ".bytes().buffer, " +
|
||||||
|
GenBBAccess() + ".bytes().byteOffset + " + GenBBAccess() +
|
||||||
|
".__vector(this.bb_pos + offset), " + GenBBAccess() +
|
||||||
|
".__vector_len(this.bb_pos + offset)) : " + value +
|
||||||
|
";\n}\n\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2043,7 +2142,7 @@ class TsGenerator : public BaseGenerator {
|
|||||||
// Emit a factory constructor
|
// Emit a factory constructor
|
||||||
if (struct_def.fixed) {
|
if (struct_def.fixed) {
|
||||||
std::string arguments;
|
std::string arguments;
|
||||||
GenStructArgs(imports, struct_def, &arguments, "");
|
GenStructArgs(imports, struct_def, struct_def, &arguments, "");
|
||||||
GenDocComment(code_ptr);
|
GenDocComment(code_ptr);
|
||||||
|
|
||||||
code += "static create" + GetPrefixedName(struct_def) +
|
code += "static create" + GetPrefixedName(struct_def) +
|
||||||
@@ -2084,7 +2183,7 @@ class TsGenerator : public BaseGenerator {
|
|||||||
if (!IsScalar(field.value.type.base_type)) {
|
if (!IsScalar(field.value.type.base_type)) {
|
||||||
code += "0";
|
code += "0";
|
||||||
} else if (HasNullDefault(field)) {
|
} else if (HasNullDefault(field)) {
|
||||||
code += "null";
|
code += null_keyword_;
|
||||||
} else {
|
} else {
|
||||||
if (field.value.type.base_type == BASE_TYPE_BOOL) {
|
if (field.value.type.base_type == BASE_TYPE_BOOL) {
|
||||||
code += "+";
|
code += "+";
|
||||||
@@ -2201,7 +2300,7 @@ class TsGenerator : public BaseGenerator {
|
|||||||
const auto arg_name = GetArgName(field);
|
const auto arg_name = GetArgName(field);
|
||||||
|
|
||||||
if (field.IsScalarOptional()) {
|
if (field.IsScalarOptional()) {
|
||||||
code += " if (" + arg_name + " !== null)\n ";
|
code += " if (" + arg_name + " !== " + null_keyword_ + ")\n ";
|
||||||
}
|
}
|
||||||
|
|
||||||
code += " " + methodPrefix + "." + namer_.Method("add", field) + "(";
|
code += " " + methodPrefix + "." + namer_.Method("add", field) + "(";
|
||||||
@@ -2241,10 +2340,38 @@ class TsGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HasNullDefault(const FieldDef& field) {
|
bool HasNullDefault(const FieldDef& field) {
|
||||||
return field.IsOptional() && field.value.constant == "null";
|
return field.IsOptional() && field.value.constant == "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool HasDefaultValue(const FieldDef& field) {
|
||||||
|
switch (field.value.type.base_type) {
|
||||||
|
// These types can't have defaults
|
||||||
|
case BASE_TYPE_UNION:
|
||||||
|
case BASE_TYPE_STRUCT: {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrays always have a default (empty array)
|
||||||
|
case BASE_TYPE_ARRAY:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// The only supported default for vectors is []
|
||||||
|
case BASE_TYPE_VECTOR:
|
||||||
|
return field.value.constant == "[]";
|
||||||
|
|
||||||
|
// Even strings are presumed to be null-default if the default value is
|
||||||
|
// "0", this is intended behavior.
|
||||||
|
case BASE_TYPE_STRING: {
|
||||||
|
return field.value.constant != "0" && field.value.constant != "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
return field.value.constant != "null";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetArgType(import_set& imports, const Definition& owner,
|
std::string GetArgType(import_set& imports, const Definition& owner,
|
||||||
const FieldDef& field, bool allowNull) {
|
const FieldDef& field, bool allowNull) {
|
||||||
return GenTypeName(imports, owner, field.value.type, true,
|
return GenTypeName(imports, owner, field.value.type, true,
|
||||||
|
|||||||
@@ -2755,6 +2755,42 @@ std::vector<IncludedFile> Parser::GetIncludedFiles() const {
|
|||||||
return {it->second.cbegin(), it->second.cend()};
|
return {it->second.cbegin(), it->second.cend()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Parser::HasCircularStructDependency() {
|
||||||
|
std::function<bool(StructDef*)> visit =
|
||||||
|
[&](StructDef* struct_def) {
|
||||||
|
// Only consider fixed structs and structs we have yet to check
|
||||||
|
if (!struct_def->fixed || struct_def->cycle_status == StructDef::CycleStatus::Checked) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (struct_def->cycle_status == StructDef::CycleStatus::InProgress) {
|
||||||
|
// cycle found
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct_def->cycle_status = StructDef::CycleStatus::InProgress;
|
||||||
|
|
||||||
|
for (const auto& field : struct_def->fields.vec) {
|
||||||
|
if (field->value.type.base_type == BASE_TYPE_STRUCT) {
|
||||||
|
if (visit(field->value.type.struct_def)) {
|
||||||
|
return true; // Cycle detected in recursion.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct_def->cycle_status = StructDef::CycleStatus::Checked;
|
||||||
|
return false; // No cycle detected.
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& struct_def : structs_.vec) {
|
||||||
|
if (visit(struct_def)) {
|
||||||
|
return true; // Cycle detected.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // No cycle detected.
|
||||||
|
}
|
||||||
|
|
||||||
bool Parser::SupportsOptionalScalars(const flatbuffers::IDLOptions& opts) {
|
bool Parser::SupportsOptionalScalars(const flatbuffers::IDLOptions& opts) {
|
||||||
static FLATBUFFERS_CONSTEXPR unsigned long supported_langs =
|
static FLATBUFFERS_CONSTEXPR unsigned long supported_langs =
|
||||||
IDLOptions::kRust | IDLOptions::kSwift | IDLOptions::kLobster |
|
IDLOptions::kRust | IDLOptions::kSwift | IDLOptions::kLobster |
|
||||||
@@ -2773,7 +2809,8 @@ bool Parser::SupportsOptionalScalars() const {
|
|||||||
bool Parser::SupportsDefaultVectorsAndStrings() const {
|
bool Parser::SupportsDefaultVectorsAndStrings() const {
|
||||||
static FLATBUFFERS_CONSTEXPR unsigned long supported_langs =
|
static FLATBUFFERS_CONSTEXPR unsigned long supported_langs =
|
||||||
IDLOptions::kRust | IDLOptions::kSwift | IDLOptions::kNim |
|
IDLOptions::kRust | IDLOptions::kSwift | IDLOptions::kNim |
|
||||||
IDLOptions::kCpp | IDLOptions::kBinary | IDLOptions::kJson;
|
IDLOptions::kCpp | IDLOptions::kBinary | IDLOptions::kJson |
|
||||||
|
IDLOptions::kTs;
|
||||||
return !(opts.lang_to_generate & ~supported_langs);
|
return !(opts.lang_to_generate & ~supported_langs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3135,8 +3172,10 @@ CheckedError Parser::ParseProtoFields(StructDef* struct_def, bool isextend,
|
|||||||
return Error("Protobuf has non positive number in reserved ids");
|
return Error("Protobuf has non positive number in reserved ids");
|
||||||
|
|
||||||
if (range) {
|
if (range) {
|
||||||
for (voffset_t id = from + 1; id <= attribute; id++)
|
for (uint32_t id = static_cast<uint32_t>(from) + 1;
|
||||||
struct_def->reserved_ids.push_back(id);
|
id <= static_cast<uint32_t>(attribute); id++) {
|
||||||
|
struct_def->reserved_ids.push_back(static_cast<voffset_t>(id));
|
||||||
|
}
|
||||||
|
|
||||||
range = false;
|
range = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -4093,7 +4132,15 @@ bool StructDef::Deserialize(Parser& parser, const reflection::Object* object) {
|
|||||||
sortbysize = attributes.Lookup("original_order") == nullptr && !fixed;
|
sortbysize = attributes.Lookup("original_order") == nullptr && !fixed;
|
||||||
const auto& of = *(object->fields());
|
const auto& of = *(object->fields());
|
||||||
auto indexes = std::vector<uoffset_t>(of.size());
|
auto indexes = std::vector<uoffset_t>(of.size());
|
||||||
for (uoffset_t i = 0; i < of.size(); i++) indexes[of.Get(i)->id()] = i;
|
for (uoffset_t i = 0; i < of.size(); i++) {
|
||||||
|
uint16_t field_id = of.Get(i)->id();
|
||||||
|
if (field_id >= of.size()) {
|
||||||
|
parser.error_ = "Field ID " + std::to_string(field_id) +
|
||||||
|
" exceeds field count " + std::to_string(of.size());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
indexes[field_id] = i;
|
||||||
|
}
|
||||||
size_t tmp_struct_size = 0;
|
size_t tmp_struct_size = 0;
|
||||||
for (size_t i = 0; i < indexes.size(); i++) {
|
for (size_t i = 0; i < indexes.size(); i++) {
|
||||||
auto field = of.Get(indexes[i]);
|
auto field = of.Get(indexes[i]);
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ static bool VerifyVector(flatbuffers::Verifier& v,
|
|||||||
auto type_vec = table.GetPointer<Vector<uint8_t>*>(vec_field.offset() -
|
auto type_vec = table.GetPointer<Vector<uint8_t>*>(vec_field.offset() -
|
||||||
sizeof(voffset_t));
|
sizeof(voffset_t));
|
||||||
if (!v.VerifyVector(type_vec)) return false;
|
if (!v.VerifyVector(type_vec)) return false;
|
||||||
|
if (type_vec->size() != vec->size()) return false;
|
||||||
for (uoffset_t j = 0; j < vec->size(); j++) {
|
for (uoffset_t j = 0; j < vec->size(); j++) {
|
||||||
// get union type from the prev field
|
// get union type from the prev field
|
||||||
auto utype = type_vec->Get(j);
|
auto utype = type_vec->Get(j);
|
||||||
@@ -388,7 +389,7 @@ void ForAllFields(const reflection::Object* object, bool reverse,
|
|||||||
|
|
||||||
for (size_t i = 0; i < field_to_id_map.size(); ++i) {
|
for (size_t i = 0; i < field_to_id_map.size(); ++i) {
|
||||||
func(object->fields()->Get(
|
func(object->fields()->Get(
|
||||||
field_to_id_map[reverse ? field_to_id_map.size() - i + 1 : i]));
|
field_to_id_map[reverse ? field_to_id_map.size() - (i + 1) : i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,7 +641,10 @@ const uint8_t* AddFlatBuffer(std::vector<uint8_t>& flatbuf,
|
|||||||
const uint8_t* newbuf, size_t newlen) {
|
const uint8_t* newbuf, size_t newlen) {
|
||||||
// Align to sizeof(uoffset_t) past sizeof(largest_scalar_t) since we're
|
// Align to sizeof(uoffset_t) past sizeof(largest_scalar_t) since we're
|
||||||
// going to chop off the root offset.
|
// going to chop off the root offset.
|
||||||
|
if (!newbuf || newlen < sizeof(uoffset_t)) return nullptr;
|
||||||
FLATBUFFERS_ASSERT(newlen >= sizeof(uoffset_t));
|
FLATBUFFERS_ASSERT(newlen >= sizeof(uoffset_t));
|
||||||
|
auto root = ReadScalar<uoffset_t>(newbuf);
|
||||||
|
if (root < sizeof(uoffset_t) || root >= newlen) return nullptr;
|
||||||
while ((flatbuf.size() & (sizeof(uoffset_t) - 1)) ||
|
while ((flatbuf.size() & (sizeof(uoffset_t) - 1)) ||
|
||||||
!(flatbuf.size() & (sizeof(largest_scalar_t) - 1))) {
|
!(flatbuf.size() & (sizeof(largest_scalar_t) - 1))) {
|
||||||
flatbuf.push_back(0);
|
flatbuf.push_back(0);
|
||||||
@@ -648,7 +652,7 @@ const uint8_t* AddFlatBuffer(std::vector<uint8_t>& flatbuf,
|
|||||||
auto insertion_point = static_cast<uoffset_t>(flatbuf.size());
|
auto insertion_point = static_cast<uoffset_t>(flatbuf.size());
|
||||||
// Insert the entire FlatBuffer minus the root pointer.
|
// Insert the entire FlatBuffer minus the root pointer.
|
||||||
flatbuf.insert(flatbuf.end(), newbuf + sizeof(uoffset_t), newbuf + newlen);
|
flatbuf.insert(flatbuf.end(), newbuf + sizeof(uoffset_t), newbuf + newlen);
|
||||||
auto root_offset = ReadScalar<uoffset_t>(newbuf) - sizeof(uoffset_t);
|
auto root_offset = root - sizeof(uoffset_t);
|
||||||
return flatbuf.data() + insertion_point + root_offset;
|
return flatbuf.data() + insertion_point + root_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ swift_library(
|
|||||||
name = "swift",
|
name = "swift",
|
||||||
srcs = glob([
|
srcs = glob([
|
||||||
"Sources/FlatBuffers/*.swift",
|
"Sources/FlatBuffers/*.swift",
|
||||||
"Sources/Common/*.swift",
|
"Sources/FlatBuffers/Vectors/*.swift",
|
||||||
|
"Sources/Common/*.swift"
|
||||||
]),
|
]),
|
||||||
module_name = "FlatBuffers",
|
module_name = "FlatBuffers",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public let FileIdLength = 4
|
|||||||
/// Protocol that All Scalars should conform to
|
/// Protocol that All Scalars should conform to
|
||||||
///
|
///
|
||||||
/// Scalar is used to conform all the numbers that can be represented in a FlatBuffer. It's used to write/read from the buffer.
|
/// Scalar is used to conform all the numbers that can be represented in a FlatBuffer. It's used to write/read from the buffer.
|
||||||
public protocol Scalar: Equatable {
|
public protocol Scalar: Equatable, BitwiseCopyable {
|
||||||
associatedtype NumericValue
|
associatedtype NumericValue
|
||||||
var convertedEndian: NumericValue { get }
|
var convertedEndian: NumericValue { get }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,22 +20,56 @@ import Foundation
|
|||||||
/// it allows users to write and read data directly from memory thus the use of its
|
/// it allows users to write and read data directly from memory thus the use of its
|
||||||
/// functions should be used
|
/// functions should be used
|
||||||
@frozen
|
@frozen
|
||||||
public struct ByteBuffer {
|
public struct ByteBuffer: @unchecked Sendable {
|
||||||
|
|
||||||
/// Storage is a container that would hold the memory pointer to solve the issue of
|
/// Storage is a container that would hold the memory pointer to solve the issue of
|
||||||
/// deallocating the memory that was held by (memory: UnsafeMutableRawPointer)
|
/// deallocating the memory that was held by (memory: UnsafeMutableRawPointer)
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
final class Storage {
|
final class Storage {
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
enum Blob {
|
@frozen enum Blob: ~Copyable {
|
||||||
#if !os(WASI)
|
#if !os(WASI)
|
||||||
case data(Data)
|
case data(Data)
|
||||||
case bytes(ContiguousBytes)
|
case bytes(any ContiguousBytes)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case byteBuffer(_InternalByteBuffer)
|
case byteBuffer(_InternalByteBuffer)
|
||||||
case array([UInt8])
|
case array([UInt8])
|
||||||
case pointer(UnsafeMutableRawPointer)
|
case pointer(UnsafeMutableRawPointer)
|
||||||
|
|
||||||
|
init(_ other: borrowing Blob) {
|
||||||
|
switch other {
|
||||||
|
#if !os(WASI)
|
||||||
|
case .data(let data):
|
||||||
|
self = .data(data)
|
||||||
|
case .bytes(let contiguousBytes):
|
||||||
|
self = .bytes(contiguousBytes)
|
||||||
|
#endif
|
||||||
|
case .byteBuffer(let internalByteBuffer):
|
||||||
|
self = .byteBuffer(internalByteBuffer)
|
||||||
|
case .array(let array):
|
||||||
|
self = .array(array)
|
||||||
|
case .pointer(let unsafeMutableRawPointer):
|
||||||
|
self = .pointer(unsafeMutableRawPointer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
switch self {
|
||||||
|
#if !os(WASI)
|
||||||
|
case .data(let data):
|
||||||
|
"data: \(data)"
|
||||||
|
case .bytes(let contiguousBytes):
|
||||||
|
"bytes: \(contiguousBytes)"
|
||||||
|
#endif
|
||||||
|
case .byteBuffer(let internalByteBuffer):
|
||||||
|
"byteBuffer: \(internalByteBuffer)"
|
||||||
|
case .array(let array):
|
||||||
|
"array: \(array)"
|
||||||
|
case .pointer(let unsafeMutableRawPointer):
|
||||||
|
"pointer: \(unsafeMutableRawPointer)"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This storage doesn't own the memory, therefore, we won't deallocate on deinit.
|
/// This storage doesn't own the memory, therefore, we won't deallocate on deinit.
|
||||||
@@ -44,7 +78,7 @@ public struct ByteBuffer {
|
|||||||
private let capacity: Int
|
private let capacity: Int
|
||||||
/// Retained blob of data that requires the storage to retain a pointer to.
|
/// Retained blob of data that requires the storage to retain a pointer to.
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
var retainedBlob: Blob
|
let retainedBlob: Blob
|
||||||
|
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
init(count: Int) {
|
init(count: Int) {
|
||||||
@@ -57,9 +91,9 @@ public struct ByteBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
init(blob: Blob, capacity count: Int) {
|
init(blob: borrowing Blob, capacity count: Int) {
|
||||||
capacity = count
|
capacity = count
|
||||||
retainedBlob = blob
|
retainedBlob = .init(blob)
|
||||||
isOwned = false
|
isOwned = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +184,7 @@ public struct ByteBuffer {
|
|||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
@inline(__always)
|
@inline(__always)
|
||||||
|
@inlinable
|
||||||
func readWithUnsafeRawPointer<T>(
|
func readWithUnsafeRawPointer<T>(
|
||||||
position: Int,
|
position: Int,
|
||||||
_ body: (UnsafeRawPointer) throws -> T) rethrows -> T
|
_ body: (UnsafeRawPointer) throws -> T) rethrows -> T
|
||||||
@@ -278,7 +313,7 @@ public struct ByteBuffer {
|
|||||||
/// - removeBytes: Removes a number of bytes from the current size
|
/// - removeBytes: Removes a number of bytes from the current size
|
||||||
@inline(__always)
|
@inline(__always)
|
||||||
init(
|
init(
|
||||||
blob: Storage.Blob,
|
blob: borrowing Storage.Blob,
|
||||||
count: Int,
|
count: Int,
|
||||||
removing removeBytes: Int)
|
removing removeBytes: Int)
|
||||||
{
|
{
|
||||||
@@ -318,7 +353,8 @@ public struct ByteBuffer {
|
|||||||
/// - def: Type of the object
|
/// - def: Type of the object
|
||||||
/// - position: the index of the object in the buffer
|
/// - position: the index of the object in the buffer
|
||||||
@inline(__always)
|
@inline(__always)
|
||||||
public func read<T>(def: T.Type, position: Int) -> T {
|
@inlinable
|
||||||
|
public func read<T: BitwiseCopyable>(def: T.Type, position: Int) -> T {
|
||||||
_storage.readWithUnsafeRawPointer(position: position) {
|
_storage.readWithUnsafeRawPointer(position: position) {
|
||||||
$0.bindMemory(to: T.self, capacity: 1)
|
$0.bindMemory(to: T.self, capacity: 1)
|
||||||
.pointee
|
.pointee
|
||||||
@@ -412,7 +448,7 @@ public struct ByteBuffer {
|
|||||||
/// - Parameter removeBytes: the amount of bytes to remove from the current Size
|
/// - Parameter removeBytes: the amount of bytes to remove from the current Size
|
||||||
@inline(__always)
|
@inline(__always)
|
||||||
public func duplicate(removing removeBytes: Int = 0) -> ByteBuffer {
|
public func duplicate(removing removeBytes: Int = 0) -> ByteBuffer {
|
||||||
assert(removeBytes > 0, "Can NOT remove negative bytes")
|
assert(removeBytes >= 0, "Can NOT remove negative bytes")
|
||||||
assert(
|
assert(
|
||||||
removeBytes < capacity,
|
removeBytes < capacity,
|
||||||
"Can NOT remove more bytes than the ones allocated")
|
"Can NOT remove more bytes than the ones allocated")
|
||||||
@@ -464,8 +500,9 @@ public struct ByteBuffer {
|
|||||||
extension ByteBuffer: CustomDebugStringConvertible {
|
extension ByteBuffer: CustomDebugStringConvertible {
|
||||||
|
|
||||||
public var debugDescription: String {
|
public var debugDescription: String {
|
||||||
"""
|
let blobDescription = _storage.retainedBlob.description
|
||||||
buffer located at: \(_storage.retainedBlob),
|
return """
|
||||||
|
buffer located at: \(blobDescription),
|
||||||
with capacity of \(capacity),
|
with capacity of \(capacity),
|
||||||
{ writtenSize: \(_readerIndex), readerSize: \(reader),
|
{ writtenSize: \(_readerIndex), readerSize: \(reader),
|
||||||
size: \(size) }
|
size: \(size) }
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import Common
|
|||||||
/// Enum is a protocol that all flatbuffers enums should conform to
|
/// Enum is a protocol that all flatbuffers enums should conform to
|
||||||
/// Since it allows us to get the actual `ByteSize` and `Value` from
|
/// Since it allows us to get the actual `ByteSize` and `Value` from
|
||||||
/// a swift enum.
|
/// a swift enum.
|
||||||
public protocol Enum {
|
public protocol Enum: Sendable {
|
||||||
/// associatedtype that the type of the enum should conform to
|
/// associatedtype that the type of the enum should conform to
|
||||||
associatedtype T: Scalar & Verifiable
|
associatedtype T: Scalar & Verifiable
|
||||||
/// Size of the current associatedtype in the enum
|
/// Size of the current associatedtype in the enum
|
||||||
|
|||||||
@@ -45,9 +45,10 @@ public struct FlatBufferBuilder {
|
|||||||
/// Dictonary that stores a map of all the strings that were written to the buffer
|
/// Dictonary that stores a map of all the strings that were written to the buffer
|
||||||
private var stringOffsetMap: [String: Offset] = [:]
|
private var stringOffsetMap: [String: Offset] = [:]
|
||||||
/// A check to see if finish(::) was ever called to retreive data object
|
/// A check to see if finish(::) was ever called to retreive data object
|
||||||
private var finished = false
|
private(set) var finished = false
|
||||||
/// A check to see if the buffer should serialize Default values
|
/// A check to see if the buffer should serialize Default values
|
||||||
private var serializeDefaults: Bool
|
@usableFromInline
|
||||||
|
let serializeDefaults: Bool
|
||||||
|
|
||||||
/// Current alignment for the buffer
|
/// Current alignment for the buffer
|
||||||
var _minAlignment: Int = 0 {
|
var _minAlignment: Int = 0 {
|
||||||
@@ -488,7 +489,7 @@ public struct FlatBufferBuilder {
|
|||||||
///
|
///
|
||||||
/// - Parameter bytes: bytes to be written into the buffer
|
/// - Parameter bytes: bytes to be written into the buffer
|
||||||
/// - Returns: ``Offset`` of the vector
|
/// - Returns: ``Offset`` of the vector
|
||||||
mutating public func createVector(bytes: ContiguousBytes) -> Offset {
|
mutating public func createVector(bytes: any ContiguousBytes) -> Offset {
|
||||||
bytes.withUnsafeBytes {
|
bytes.withUnsafeBytes {
|
||||||
startVector($0.count, elementSize: MemoryLayout<UInt8>.size)
|
startVector($0.count, elementSize: MemoryLayout<UInt8>.size)
|
||||||
_bb.push(bytes: $0)
|
_bb.push(bytes: $0)
|
||||||
@@ -756,6 +757,7 @@ public struct FlatBufferBuilder {
|
|||||||
/// - offset: ``Offset`` of another object to be written
|
/// - offset: ``Offset`` of another object to be written
|
||||||
/// - position: The predefined position of the object
|
/// - position: The predefined position of the object
|
||||||
@inline(__always)
|
@inline(__always)
|
||||||
|
@inlinable
|
||||||
mutating public func add(offset: Offset, at position: VOffset) {
|
mutating public func add(offset: Offset, at position: VOffset) {
|
||||||
if offset.isEmpty { return }
|
if offset.isEmpty { return }
|
||||||
add(element: refer(to: offset.o), def: 0, at: position)
|
add(element: refer(to: offset.o), def: 0, at: position)
|
||||||
@@ -794,6 +796,7 @@ public struct FlatBufferBuilder {
|
|||||||
/// - def: Default value for that element
|
/// - def: Default value for that element
|
||||||
/// - position: The predefined position of the element
|
/// - position: The predefined position of the element
|
||||||
@inline(__always)
|
@inline(__always)
|
||||||
|
@inlinable
|
||||||
mutating public func add<T: Scalar>(
|
mutating public func add<T: Scalar>(
|
||||||
element: T,
|
element: T,
|
||||||
def: T,
|
def: T,
|
||||||
@@ -813,6 +816,7 @@ public struct FlatBufferBuilder {
|
|||||||
/// - element: Optional element of type scalar
|
/// - element: Optional element of type scalar
|
||||||
/// - position: The predefined position of the element
|
/// - position: The predefined position of the element
|
||||||
@inline(__always)
|
@inline(__always)
|
||||||
|
@inlinable
|
||||||
mutating public func add<T: Scalar>(element: T?, at position: VOffset) {
|
mutating public func add<T: Scalar>(element: T?, at position: VOffset) {
|
||||||
guard let element = element else { return }
|
guard let element = element else { return }
|
||||||
track(offset: push(element: element), at: position)
|
track(offset: push(element: element), at: position)
|
||||||
@@ -825,6 +829,7 @@ public struct FlatBufferBuilder {
|
|||||||
/// - Parameter element: Element to insert
|
/// - Parameter element: Element to insert
|
||||||
/// - returns: position of the Element
|
/// - returns: position of the Element
|
||||||
@inline(__always)
|
@inline(__always)
|
||||||
|
@inlinable
|
||||||
@discardableResult
|
@discardableResult
|
||||||
mutating public func push<T: Scalar>(element: T) -> UOffset {
|
mutating public func push<T: Scalar>(element: T) -> UOffset {
|
||||||
let size = MemoryLayout<T>.size
|
let size = MemoryLayout<T>.size
|
||||||
@@ -836,7 +841,8 @@ public struct FlatBufferBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@inline(__always)
|
@inline(__always)
|
||||||
public func read<T>(def: T.Type, position: Int) -> T {
|
@inlinable
|
||||||
|
public func read<T: BitwiseCopyable>(def: T.Type, position: Int) -> T {
|
||||||
_bb.read(def: def, position: position)
|
_bb.read(def: def, position: position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user