forked from BigfootDev/flatbuffers
Compare commits
14 Commits
dependabot
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f438bd40f | ||
|
|
392165432a | ||
|
|
e6bbb3d22e | ||
|
|
a6979fe14a | ||
|
|
bab10754d9 | ||
|
|
ac7ef1176a | ||
|
|
d6444fb7fc | ||
|
|
e223d69b36 | ||
|
|
05cc7a2eff | ||
|
|
8a12183c3b | ||
|
|
21b706b62d | ||
|
|
c5f151ab33 | ||
|
|
3860f1cf7f | ||
|
|
4e582b0c1d |
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -137,7 +137,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
- name: Add msbuild to PATH
|
- name: Add msbuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v3
|
uses: microsoft/setup-msbuild@v2
|
||||||
- name: cmake
|
- name: cmake
|
||||||
run: >
|
run: >
|
||||||
cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release
|
cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release
|
||||||
@@ -162,7 +162,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
- name: Add msbuild to PATH
|
- name: Add msbuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v3
|
uses: microsoft/setup-msbuild@v2
|
||||||
- name: cmake
|
- name: cmake
|
||||||
run: cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_CPP17=ON -DFLATBUFFERS_STRICT_MODE=ON .
|
run: cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_CPP17=ON -DFLATBUFFERS_STRICT_MODE=ON .
|
||||||
- name: build
|
- name: build
|
||||||
@@ -350,7 +350,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
- name: Add msbuild to PATH
|
- name: Add msbuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v3
|
uses: microsoft/setup-msbuild@v2
|
||||||
- name: cmake
|
- name: cmake
|
||||||
run: cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_CPP17=ON -DFLATBUFFERS_STRICT_MODE=ON .
|
run: cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_CPP17=ON -DFLATBUFFERS_STRICT_MODE=ON .
|
||||||
- name: build
|
- name: build
|
||||||
@@ -495,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
|
||||||
@@ -534,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
|
||||||
@@ -545,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
|
||||||
- name: deps
|
- name: deps
|
||||||
run: pnpm i
|
run: pnpm i
|
||||||
- name: compile
|
- name: compile
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
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 }
|
||||||
@@ -23,16 +23,16 @@ public struct models_HelloReply: FlatBufferTable, FlatbuffersVectorInitializable
|
|||||||
|
|
||||||
public var message: String? { let o = _accessor.offset(VT.message); 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: VT.message) }
|
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: VT.message) }
|
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 {
|
||||||
@@ -42,7 +42,7 @@ public struct models_HelloReply: FlatBufferTable, FlatbuffersVectorInitializable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension models_HelloReply: Encodable {
|
extension models_HelloResponse: Encodable {
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case message = "message"
|
case message = "message"
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ extension models_HelloReply: Encodable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 }
|
||||||
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
pnpm-lock.yaml
generated
6
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':
|
||||||
|
|||||||
2
pnpm-workspace.yaml
Normal file
2
pnpm-workspace.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
packages:
|
||||||
|
- tests/ts
|
||||||
@@ -12,33 +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',
|
||||||
'Operating System :: OS Independent',
|
license='Apache 2.0',
|
||||||
'Programming Language :: Python',
|
author='Derek Bailey',
|
||||||
'Programming Language :: Python :: 3',
|
author_email='derekbailey@google.com',
|
||||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
url='https://google.github.io/flatbuffers/',
|
||||||
],
|
long_description=(
|
||||||
project_urls={
|
'Python runtime library for use with the '
|
||||||
'Documentation': 'https://google.github.io/flatbuffers/',
|
'`Flatbuffers <https://google.github.io/flatbuffers/>`_ '
|
||||||
'Source': 'https://github.com/google/flatbuffers',
|
'serialization format.'
|
||||||
},
|
),
|
||||||
)
|
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()
|
||||||
|
|||||||
@@ -337,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
|
||||||
@@ -360,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
|
||||||
@@ -397,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.
|
||||||
@@ -405,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.
|
||||||
@@ -424,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.
|
||||||
@@ -439,10 +500,31 @@ 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.
|
/// Create a utf8 string, and de-duplicate if already created.
|
||||||
@@ -452,26 +534,20 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
#[cfg(feature = "std")]
|
#[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.assert_not_nested(
|
self.try_create_shared_string(s)
|
||||||
"create_shared_string can not be called when a table or vector is under construction",
|
.expect("Flatbuffer allocation failure")
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(&offset) = self.strings_pool.get(s) {
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
let address = WIPOffset::new(self.create_byte_string(s.as_bytes()).value());
|
|
||||||
self.strings_pool.insert(s.to_owned(), address);
|
|
||||||
address
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a utf8 string, and de-duplicate if already created.
|
/// Fallible version of [`create_shared_string`](Self::create_shared_string).
|
||||||
///
|
///
|
||||||
/// Uses a sorted Vec with binary search to track previously written
|
/// Uses a sorted Vec with binary search to track previously written
|
||||||
/// strings when in `no_std` mode.
|
/// strings when in `no_std` mode.
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn create_shared_string<'a: 'b, 'b>(&'a mut self, s: &'b str) -> WIPOffset<&'fbb str> {
|
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",
|
||||||
);
|
);
|
||||||
@@ -494,52 +570,83 @@ impl<'fbb, A: Allocator> FlatBufferBuilder<'fbb, A> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
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();
|
||||||
@@ -553,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.
|
||||||
@@ -565,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.
|
||||||
@@ -635,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
|
||||||
@@ -650,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
|
||||||
@@ -658,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]
|
||||||
@@ -676,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.
|
||||||
@@ -725,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();
|
||||||
@@ -750,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.
|
||||||
@@ -794,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*
|
||||||
@@ -814,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",
|
||||||
@@ -827,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]
|
||||||
@@ -863,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 {
|
||||||
@@ -1129,4 +1302,111 @@ mod tests {
|
|||||||
allocs
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 }
|
||||||
@@ -400,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 }
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -2471,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()";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -170,9 +170,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
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";
|
||||||
@@ -549,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";
|
||||||
|
|||||||
@@ -4132,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]);
|
||||||
|
|||||||
@@ -389,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]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ 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)
|
||||||
@@ -30,7 +30,7 @@ public struct ByteBuffer {
|
|||||||
enum Blob {
|
enum Blob {
|
||||||
#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)
|
||||||
|
|||||||
@@ -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,7 +45,7 @@ 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
|
private var serializeDefaults: Bool
|
||||||
|
|
||||||
@@ -488,7 +488,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)
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import Foundation
|
|||||||
/// since now we will be serializing native structs into the buffer.
|
/// since now we will be serializing native structs into the buffer.
|
||||||
public protocol NativeStruct {}
|
public protocol NativeStruct {}
|
||||||
|
|
||||||
|
public protocol FlatBufferVerifiableNativeStruct: NativeStruct, Verifiable {}
|
||||||
|
|
||||||
/// FlatbuffersInitializable is a protocol that allows any object to be
|
/// FlatbuffersInitializable is a protocol that allows any object to be
|
||||||
/// Initialized from a ByteBuffer
|
/// Initialized from a ByteBuffer
|
||||||
public protocol FlatbuffersInitializable {
|
public protocol FlatbuffersInitializable {
|
||||||
@@ -35,6 +37,8 @@ public protocol FlatBufferTable: FlatbuffersInitializable,
|
|||||||
var __buffer: ByteBuffer! { get }
|
var __buffer: ByteBuffer! { get }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public protocol FlatBufferVerifiableTable: FlatBufferTable, Verifiable {}
|
||||||
|
|
||||||
/// FlatbufferStruct structures all the Flatbuffers structs
|
/// FlatbufferStruct structures all the Flatbuffers structs
|
||||||
public protocol FlatBufferStruct: FlatbuffersInitializable,
|
public protocol FlatBufferStruct: FlatbuffersInitializable,
|
||||||
FlatbuffersVectorInitializable
|
FlatbuffersVectorInitializable
|
||||||
|
|||||||
@@ -16,50 +16,52 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/// FlatBufferGRPCMessage protocol that should allow us to invoke
|
enum FlatbuffersGRPCError: Error {
|
||||||
/// initializers directly from the GRPC generated code
|
case finishedNotCalledOnBuilder
|
||||||
public protocol FlatBufferGRPCMessage {
|
|
||||||
/// Size of readable bytes in the buffer
|
|
||||||
var size: Int { get }
|
|
||||||
|
|
||||||
init(byteBuffer: ByteBuffer)
|
|
||||||
|
|
||||||
@discardableResult
|
|
||||||
@inline(__always)
|
|
||||||
func withUnsafeReadableBytes<T>(
|
|
||||||
_ body: (UnsafeRawBufferPointer) throws
|
|
||||||
-> T) rethrows -> T
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Message is a wrapper around Buffers to to able to send Flatbuffers `Buffers` through the
|
public protocol GRPCVerifiableMessage<Message> {
|
||||||
/// GRPC library
|
associatedtype Message
|
||||||
public struct Message<T: FlatBufferTable>: FlatBufferGRPCMessage {
|
|
||||||
internal var buffer: ByteBuffer
|
|
||||||
|
|
||||||
/// Returns the an object of type T that would be read from the buffer
|
init(pointer: UnsafeRawBufferPointer)
|
||||||
public var object: T {
|
init(byteBuffer: ByteBuffer)
|
||||||
T.init(
|
|
||||||
buffer,
|
func decode() throws -> Message
|
||||||
o: Int32(buffer.read(def: UOffset.self, position: buffer.reader)) &+
|
func withUnsafeReadableBytes<Data>(
|
||||||
Int32(buffer.reader))
|
_ body: (UnsafeRawBufferPointer) throws
|
||||||
}
|
-> Data) rethrows -> Data
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct GRPCMessage<
|
||||||
|
Table: FlatBufferVerifiableTable
|
||||||
|
>: Sendable, GRPCVerifiableMessage {
|
||||||
|
public typealias Message = Table
|
||||||
|
|
||||||
|
private let buffer: ByteBuffer
|
||||||
|
|
||||||
public var size: Int { Int(buffer.size) }
|
public var size: Int { Int(buffer.size) }
|
||||||
|
|
||||||
/// Initializes the message with the type Flatbuffer.Bytebuffer that is transmitted over
|
public init(pointer: UnsafeRawBufferPointer) {
|
||||||
/// GRPC
|
buffer = ByteBuffer(
|
||||||
/// - Parameter byteBuffer: Flatbuffer ByteBuffer object
|
copyingMemoryBound: pointer.baseAddress!,
|
||||||
|
capacity: pointer.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(builder: inout FlatBufferBuilder) throws {
|
||||||
|
guard builder.finished else {
|
||||||
|
throw FlatbuffersGRPCError.finishedNotCalledOnBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = builder.sizedBuffer
|
||||||
|
}
|
||||||
|
|
||||||
public init(byteBuffer: ByteBuffer) {
|
public init(byteBuffer: ByteBuffer) {
|
||||||
buffer = byteBuffer
|
buffer = byteBuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes the message by copying the buffer to the message to be sent.
|
public func decode() throws -> Table {
|
||||||
/// from the builder
|
var buf = buffer
|
||||||
/// - Parameter builder: FlatbufferBuilder that has the bytes created in
|
return try getCheckedRoot(byteBuffer: &buf)
|
||||||
/// - Note: Use `builder.finish(offset)` before passing the builder without prefixing anything to it
|
|
||||||
public init(builder: inout FlatBufferBuilder) {
|
|
||||||
buffer = builder.sizedBuffer
|
|
||||||
builder.clear()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
@@ -73,3 +75,30 @@ public struct Message<T: FlatBufferTable>: FlatBufferGRPCMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
public struct FlatBuffersMessageSerializer<
|
||||||
|
Message: GRPCVerifiableMessage
|
||||||
|
>: Sendable {
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
public func serialize<Data>(
|
||||||
|
message: Message,
|
||||||
|
_ completion: (UnsafeRawBufferPointer) throws -> Data) throws -> Data
|
||||||
|
{
|
||||||
|
return try message.withUnsafeReadableBytes {
|
||||||
|
try completion($0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
public struct FlatBuffersMessageDeserializer<
|
||||||
|
Message: GRPCVerifiableMessage
|
||||||
|
>: Sendable {
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
public func deserialize(pointer: UnsafeRawBufferPointer) throws -> Message {
|
||||||
|
Message.init(pointer: pointer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public struct TableVerifier {
|
|||||||
unionKeyName: String,
|
unionKeyName: String,
|
||||||
fieldName: String,
|
fieldName: String,
|
||||||
required: Bool,
|
required: Bool,
|
||||||
completion: @escaping (inout Verifier, T, Int) throws -> Void) throws
|
completion: (inout Verifier, T, Int) throws -> Void) throws
|
||||||
where T: UnionEnum
|
where T: UnionEnum
|
||||||
{
|
{
|
||||||
let keyPos = try dereference(key)
|
let keyPos = try dereference(key)
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public struct FlatbufferVector<
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension FlatbufferVector: Encodable where Element: Encodable {
|
extension FlatbufferVector: Encodable where Element: Encodable {
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: any Encoder) throws {
|
||||||
var container = encoder.unkeyedContainer()
|
var container = encoder.unkeyedContainer()
|
||||||
for element in self {
|
for element in self {
|
||||||
try container.encode(element)
|
try container.encode(element)
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ public struct UnionFlatbufferVector {
|
|||||||
|
|
||||||
public subscript(
|
public subscript(
|
||||||
position: Int,
|
position: Int,
|
||||||
Type: FlatbuffersVectorInitializable
|
Type: any FlatbuffersVectorInitializable
|
||||||
.Type) -> FlatbuffersVectorInitializable
|
.Type) -> any FlatbuffersVectorInitializable
|
||||||
{
|
{
|
||||||
guard position < count else {
|
guard position < count else {
|
||||||
fatalError(
|
fatalError(
|
||||||
|
|||||||
@@ -56,8 +56,15 @@ extension Verifiable {
|
|||||||
let len: UOffset = try verifier.getValue(at: position)
|
let len: UOffset = try verifier.getValue(at: position)
|
||||||
let intLen = Int(len)
|
let intLen = Int(len)
|
||||||
let start = Int(clamping: (position &+ MemoryLayout<Int32>.size).magnitude)
|
let start = Int(clamping: (position &+ MemoryLayout<Int32>.size).magnitude)
|
||||||
|
let byteCount = intLen.multipliedReportingOverflow(
|
||||||
|
by: MemoryLayout<T>.size)
|
||||||
|
guard !byteCount.overflow else {
|
||||||
|
throw FlatbuffersErrors.outOfBounds(
|
||||||
|
position: UInt.max,
|
||||||
|
end: verifier.capacity)
|
||||||
|
}
|
||||||
try verifier.isAligned(position: start, type: type.self)
|
try verifier.isAligned(position: start, type: type.self)
|
||||||
try verifier.rangeInBuffer(position: start, size: intLen)
|
try verifier.rangeInBuffer(position: start, size: byteCount.partialValue)
|
||||||
return (start, intLen)
|
return (start, intLen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ struct _InternalByteBuffer {
|
|||||||
#if !os(WASI)
|
#if !os(WASI)
|
||||||
@inline(__always)
|
@inline(__always)
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
mutating func push(bytes: ContiguousBytes) {
|
mutating func push(bytes: any ContiguousBytes) {
|
||||||
bytes.withUnsafeBytes { ptr in
|
bytes.withUnsafeBytes { ptr in
|
||||||
ensureSpace(size: ptr.count)
|
ensureSpace(size: ptr.count)
|
||||||
memcpy(
|
memcpy(
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public struct ByteBuffer {
|
|||||||
enum Blob {
|
enum Blob {
|
||||||
#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)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public enum FlexBufferType: UInt64 {
|
public enum FlexBufferType: UInt64, Sendable {
|
||||||
case null = 0
|
case null = 0
|
||||||
/// Variable width signed integer: `Int8, Int16, Int32, Int64`
|
/// Variable width signed integer: `Int8, Int16, Int32, Int64`
|
||||||
case int = 1
|
case int = 1
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
enum BitWidth: UInt64, CaseIterable {
|
enum BitWidth: UInt64, CaseIterable, Sendable {
|
||||||
case w8 = 0
|
case w8 = 0
|
||||||
case w16 = 1
|
case w16 = 1
|
||||||
case w32 = 2
|
case w32 = 2
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ import Foundation
|
|||||||
import Common
|
import Common
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public struct Value: Equatable {
|
public struct Value: Equatable, Sendable {
|
||||||
|
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
enum Union: Equatable {
|
enum Union: Equatable, Sendable {
|
||||||
case i(Int64)
|
case i(Int64)
|
||||||
case u(UInt64)
|
case u(UInt64)
|
||||||
case f(Double)
|
case f(Double)
|
||||||
|
|||||||
@@ -977,6 +977,9 @@ fileprivate struct Stack: RandomAccessCollection {
|
|||||||
mutating func removeAll(keepingCapacity keepCapacity: Bool = false) {
|
mutating func removeAll(keepingCapacity keepCapacity: Bool = false) {
|
||||||
count = 0
|
count = 0
|
||||||
if !keepCapacity {
|
if !keepCapacity {
|
||||||
|
let ptr = storage.memory
|
||||||
|
defer { ptr.deallocate() }
|
||||||
|
|
||||||
capacity = Self.initialCapacity
|
capacity = Self.initialCapacity
|
||||||
storage.memory = UnsafeMutableRawPointer.allocate(
|
storage.memory = UnsafeMutableRawPointer.allocate(
|
||||||
byteCount: capacity,
|
byteCount: capacity,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "flexbuffers_test.h"
|
#include "flexbuffers_test.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#include "flatbuffers/flexbuffers.h"
|
#include "flatbuffers/flexbuffers.h"
|
||||||
@@ -13,6 +14,13 @@ namespace tests {
|
|||||||
// Shortcuts for the infinity.
|
// Shortcuts for the infinity.
|
||||||
static const auto infinity_d = std::numeric_limits<double>::infinity();
|
static const auto infinity_d = std::numeric_limits<double>::infinity();
|
||||||
|
|
||||||
|
static bool IsAligned(const void* ptr, std::size_t alignment) {
|
||||||
|
void* p = const_cast<void*>(ptr);
|
||||||
|
std::size_t space = 2 * alignment;
|
||||||
|
void* q = std::align(alignment, alignment, p, space);
|
||||||
|
return q != nullptr && p == ptr && space == 2 * alignment;
|
||||||
|
}
|
||||||
|
|
||||||
void FlexBuffersTest() {
|
void FlexBuffersTest() {
|
||||||
flexbuffers::Builder slb(512,
|
flexbuffers::Builder slb(512,
|
||||||
flexbuffers::BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
|
flexbuffers::BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
|
||||||
@@ -29,7 +37,10 @@ void FlexBuffersTest() {
|
|||||||
slb.IndirectFloat(4.0f);
|
slb.IndirectFloat(4.0f);
|
||||||
auto i_f = slb.LastValue();
|
auto i_f = slb.LastValue();
|
||||||
uint8_t blob[] = {77};
|
uint8_t blob[] = {77};
|
||||||
slb.Blob(blob, 1);
|
uint32_t aligned_blob[] = {88, 99};
|
||||||
|
slb.Blob(blob, sizeof blob);
|
||||||
|
slb.AlignedBlob(aligned_blob, sizeof aligned_blob,
|
||||||
|
flexbuffers::BIT_WIDTH_32);
|
||||||
slb += false;
|
slb += false;
|
||||||
slb.ReuseValue(i_f);
|
slb.ReuseValue(i_f);
|
||||||
});
|
});
|
||||||
@@ -62,7 +73,7 @@ void FlexBuffersTest() {
|
|||||||
auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
|
auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
|
||||||
TEST_EQ(map.size(), 7);
|
TEST_EQ(map.size(), 7);
|
||||||
auto vec = map["vec"].AsVector();
|
auto vec = map["vec"].AsVector();
|
||||||
TEST_EQ(vec.size(), 6);
|
TEST_EQ(vec.size(), 7);
|
||||||
TEST_EQ(vec[0].AsInt64(), -100);
|
TEST_EQ(vec[0].AsInt64(), -100);
|
||||||
TEST_EQ_STR(vec[1].AsString().c_str(), "Fred");
|
TEST_EQ_STR(vec[1].AsString().c_str(), "Fred");
|
||||||
TEST_EQ(vec[1].AsInt64(), 0); // Number parsing failed.
|
TEST_EQ(vec[1].AsInt64(), 0); // Number parsing failed.
|
||||||
@@ -80,9 +91,15 @@ void FlexBuffersTest() {
|
|||||||
auto blob = vec[3].AsBlob();
|
auto blob = vec[3].AsBlob();
|
||||||
TEST_EQ(blob.size(), 1);
|
TEST_EQ(blob.size(), 1);
|
||||||
TEST_EQ(blob.data()[0], 77);
|
TEST_EQ(blob.data()[0], 77);
|
||||||
TEST_EQ(vec[4].IsBool(), true); // Check if type is a bool
|
TEST_EQ(vec[4].IsBlob(), true);
|
||||||
TEST_EQ(vec[4].AsBool(), false); // Check if value is false
|
auto aligned_blob = vec[4].AsBlob();
|
||||||
TEST_EQ(vec[5].AsDouble(), 4.0); // This is shared with vec[2] !
|
TEST_EQ(aligned_blob.size(), 8);
|
||||||
|
TEST_EQ(reinterpret_cast<const uint32_t*>(aligned_blob.data())[0], 88);
|
||||||
|
TEST_EQ(reinterpret_cast<const uint32_t*>(aligned_blob.data())[1], 99);
|
||||||
|
TEST_EQ(IsAligned(aligned_blob.data(), 4), true);
|
||||||
|
TEST_EQ(vec[5].IsBool(), true); // Check if type is a bool
|
||||||
|
TEST_EQ(vec[5].AsBool(), false); // Check if value is false
|
||||||
|
TEST_EQ(vec[6].AsDouble(), 4.0); // This is shared with vec[2] !
|
||||||
auto tvec = map["bar"].AsTypedVector();
|
auto tvec = map["bar"].AsTypedVector();
|
||||||
TEST_EQ(tvec.size(), 3);
|
TEST_EQ(tvec.size(), 3);
|
||||||
TEST_EQ(tvec[2].AsInt8(), 3);
|
TEST_EQ(tvec[2].AsInt8(), 3);
|
||||||
@@ -107,9 +124,9 @@ void FlexBuffersTest() {
|
|||||||
TEST_EQ(vec[2].MutateFloat(2.0f), true);
|
TEST_EQ(vec[2].MutateFloat(2.0f), true);
|
||||||
TEST_EQ(vec[2].AsFloat(), 2.0f);
|
TEST_EQ(vec[2].AsFloat(), 2.0f);
|
||||||
TEST_EQ(vec[2].MutateFloat(3.14159), false); // Double does not fit in float.
|
TEST_EQ(vec[2].MutateFloat(3.14159), false); // Double does not fit in float.
|
||||||
TEST_EQ(vec[4].AsBool(), false); // Is false before change
|
TEST_EQ(vec[5].AsBool(), false); // Is false before change
|
||||||
TEST_EQ(vec[4].MutateBool(true), true); // Can change a bool
|
TEST_EQ(vec[5].MutateBool(true), true); // Can change a bool
|
||||||
TEST_EQ(vec[4].AsBool(), true); // Changed bool is now true
|
TEST_EQ(vec[5].AsBool(), true); // Changed bool is now true
|
||||||
|
|
||||||
// Parse from JSON:
|
// Parse from JSON:
|
||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
|
|||||||
@@ -248,6 +248,93 @@ void ReflectionTest(const std::string& tests_data_path, uint8_t* flatbuf,
|
|||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that ForAllFields with reverse=true iterates fields in descending
|
||||||
|
// ID order. This exercises a fix for an operator precedence bug where the
|
||||||
|
// expression `size() - i + 1` was evaluated as `(size() - i) + 1` instead
|
||||||
|
// of the correct `size() - (i + 1)`, causing an out-of-bounds read.
|
||||||
|
void ForAllFieldsReverseTest(const std::string& tests_data_path) {
|
||||||
|
// Load the binary schema.
|
||||||
|
std::string bfbsfile;
|
||||||
|
TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.bfbs").c_str(),
|
||||||
|
true, &bfbsfile),
|
||||||
|
true);
|
||||||
|
|
||||||
|
// Verify the schema.
|
||||||
|
flatbuffers::Verifier verifier(
|
||||||
|
reinterpret_cast<const uint8_t*>(bfbsfile.c_str()), bfbsfile.length());
|
||||||
|
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
|
||||||
|
|
||||||
|
auto& schema = *reflection::GetSchema(bfbsfile.c_str());
|
||||||
|
|
||||||
|
// Use the Stat table which has 3 fields with sequential IDs:
|
||||||
|
// id:string (id: 0)
|
||||||
|
// val:long (id: 1)
|
||||||
|
// count:ushort (id: 2)
|
||||||
|
auto stat_object = schema.objects()->LookupByKey("MyGame.Example.Stat");
|
||||||
|
TEST_NOTNULL(stat_object);
|
||||||
|
TEST_EQ(stat_object->fields()->size(), 3u);
|
||||||
|
|
||||||
|
// Test forward iteration: fields should come in ascending ID order (0,1,2).
|
||||||
|
{
|
||||||
|
std::vector<uint16_t> forward_ids;
|
||||||
|
flatbuffers::ForAllFields(
|
||||||
|
stat_object, /*reverse=*/false,
|
||||||
|
[&forward_ids](const reflection::Field* field) {
|
||||||
|
forward_ids.push_back(field->id());
|
||||||
|
});
|
||||||
|
TEST_EQ(forward_ids.size(), 3u);
|
||||||
|
TEST_EQ(forward_ids[0], 0); // id
|
||||||
|
TEST_EQ(forward_ids[1], 1); // val
|
||||||
|
TEST_EQ(forward_ids[2], 2); // count
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test reverse iteration: fields should come in descending ID order (2,1,0).
|
||||||
|
// With the old buggy code `size() - i + 1`, at i=0 this would compute
|
||||||
|
// index 3 - 0 + 1 = 4, which is out of bounds for a size-3 vector.
|
||||||
|
{
|
||||||
|
std::vector<uint16_t> reverse_ids;
|
||||||
|
flatbuffers::ForAllFields(
|
||||||
|
stat_object, /*reverse=*/true,
|
||||||
|
[&reverse_ids](const reflection::Field* field) {
|
||||||
|
reverse_ids.push_back(field->id());
|
||||||
|
});
|
||||||
|
TEST_EQ(reverse_ids.size(), 3u);
|
||||||
|
TEST_EQ(reverse_ids[0], 2); // count (highest ID first)
|
||||||
|
TEST_EQ(reverse_ids[1], 1); // val
|
||||||
|
TEST_EQ(reverse_ids[2], 0); // id (lowest ID last)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also test with the root Monster table which has many fields and
|
||||||
|
// non-sequential definition order vs. ID order (e.g., pos=id:0, hp=id:2,
|
||||||
|
// mana=id:1). This ensures the ID-to-index mapping works correctly.
|
||||||
|
auto root_table = schema.root_table();
|
||||||
|
TEST_NOTNULL(root_table);
|
||||||
|
{
|
||||||
|
std::vector<uint16_t> forward_ids;
|
||||||
|
flatbuffers::ForAllFields(
|
||||||
|
root_table, /*reverse=*/false,
|
||||||
|
[&forward_ids](const reflection::Field* field) {
|
||||||
|
forward_ids.push_back(field->id());
|
||||||
|
});
|
||||||
|
// Verify ascending order.
|
||||||
|
for (size_t i = 1; i < forward_ids.size(); ++i) {
|
||||||
|
TEST_ASSERT(forward_ids[i - 1] < forward_ids[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::vector<uint16_t> reverse_ids;
|
||||||
|
flatbuffers::ForAllFields(
|
||||||
|
root_table, /*reverse=*/true,
|
||||||
|
[&reverse_ids](const reflection::Field* field) {
|
||||||
|
reverse_ids.push_back(field->id());
|
||||||
|
});
|
||||||
|
// Verify descending order.
|
||||||
|
for (size_t i = 1; i < reverse_ids.size(); ++i) {
|
||||||
|
TEST_ASSERT(reverse_ids[i - 1] > reverse_ids[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MiniReflectFlatBuffersTest(uint8_t* flatbuf) {
|
void MiniReflectFlatBuffersTest(uint8_t* flatbuf) {
|
||||||
auto s =
|
auto s =
|
||||||
flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable());
|
flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable());
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace tests {
|
|||||||
|
|
||||||
void ReflectionTest(const std::string& tests_data_path, uint8_t* flatbuf,
|
void ReflectionTest(const std::string& tests_data_path, uint8_t* flatbuf,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
void ForAllFieldsReverseTest(const std::string& tests_data_path);
|
||||||
void MiniReflectFixedLengthArrayTest();
|
void MiniReflectFixedLengthArrayTest();
|
||||||
void MiniReflectFlatBuffersTest(uint8_t* flatbuf);
|
void MiniReflectFlatBuffersTest(uint8_t* flatbuf);
|
||||||
|
|
||||||
|
|||||||
@@ -3448,4 +3448,250 @@ fn test_shared_strings_pool_deduplication() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // mod flatbuffers_tests
|
} // mod flatbuffers_tests
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod try_api {
|
||||||
|
extern crate flatbuffers;
|
||||||
|
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
use flatbuffers::Follow;
|
||||||
|
use super::my_game;
|
||||||
|
use super::serialized_example_is_accessible_and_correct;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_api_full_table_roundtrip() {
|
||||||
|
// Build a Monster using exclusively try_* API (mirrors library_code example).
|
||||||
|
let mut builder = flatbuffers::FlatBufferBuilder::new();
|
||||||
|
|
||||||
|
let nested_union_mon = {
|
||||||
|
let name = builder.try_create_string("Fred").unwrap();
|
||||||
|
let table_start = builder.start_table();
|
||||||
|
builder
|
||||||
|
.try_push_slot_always(my_game::example::Monster::VT_NAME, name)
|
||||||
|
.unwrap();
|
||||||
|
builder.try_end_table(table_start).unwrap()
|
||||||
|
};
|
||||||
|
let pos = my_game::example::Vec3::new(
|
||||||
|
1.0,
|
||||||
|
2.0,
|
||||||
|
3.0,
|
||||||
|
3.0,
|
||||||
|
my_game::example::Color::Green,
|
||||||
|
&my_game::example::Test::new(5i16, 6i8),
|
||||||
|
);
|
||||||
|
let inv = builder.try_create_vector(&[0u8, 1, 2, 3, 4]).unwrap();
|
||||||
|
let test4 = builder
|
||||||
|
.try_create_vector(
|
||||||
|
&[
|
||||||
|
my_game::example::Test::new(10, 20),
|
||||||
|
my_game::example::Test::new(30, 40),
|
||||||
|
][..],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let name = builder.try_create_string("MyMonster").unwrap();
|
||||||
|
let test1 = builder.try_create_string("test1").unwrap();
|
||||||
|
let test2 = builder.try_create_string("test2").unwrap();
|
||||||
|
let testarrayofstring = builder.try_create_vector(&[test1, test2]).unwrap();
|
||||||
|
|
||||||
|
let table_start = builder.start_table();
|
||||||
|
builder
|
||||||
|
.try_push_slot(my_game::example::Monster::VT_HP, 80i16, 100)
|
||||||
|
.unwrap();
|
||||||
|
builder
|
||||||
|
.try_push_slot_always(my_game::example::Monster::VT_NAME, name)
|
||||||
|
.unwrap();
|
||||||
|
builder
|
||||||
|
.try_push_slot_always(my_game::example::Monster::VT_POS, &pos)
|
||||||
|
.unwrap();
|
||||||
|
builder
|
||||||
|
.try_push_slot(
|
||||||
|
my_game::example::Monster::VT_TEST_TYPE,
|
||||||
|
my_game::example::Any::Monster,
|
||||||
|
my_game::example::Any::NONE,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
builder
|
||||||
|
.try_push_slot_always(my_game::example::Monster::VT_TEST, nested_union_mon)
|
||||||
|
.unwrap();
|
||||||
|
builder
|
||||||
|
.try_push_slot_always(my_game::example::Monster::VT_INVENTORY, inv)
|
||||||
|
.unwrap();
|
||||||
|
builder
|
||||||
|
.try_push_slot_always(my_game::example::Monster::VT_TEST4, test4)
|
||||||
|
.unwrap();
|
||||||
|
builder
|
||||||
|
.try_push_slot_always(
|
||||||
|
my_game::example::Monster::VT_TESTARRAYOFSTRING,
|
||||||
|
testarrayofstring,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let root = builder.try_end_table(table_start).unwrap();
|
||||||
|
builder
|
||||||
|
.try_finish(root, Some(my_game::example::MONSTER_IDENTIFIER))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let buf = builder.finished_data();
|
||||||
|
serialized_example_is_accessible_and_correct(buf, true, false).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_shared_string_deduplication() {
|
||||||
|
let mut builder = flatbuffers::FlatBufferBuilder::new();
|
||||||
|
let offset1 = builder
|
||||||
|
.try_create_shared_string("welcome to flatbuffers!!")
|
||||||
|
.unwrap();
|
||||||
|
let offset2 = builder.try_create_shared_string("welcome").unwrap();
|
||||||
|
let offset3 = builder
|
||||||
|
.try_create_shared_string("welcome to flatbuffers!!")
|
||||||
|
.unwrap();
|
||||||
|
assert_ne!(offset2.value(), offset3.value());
|
||||||
|
assert_eq!(offset1.value(), offset3.value());
|
||||||
|
|
||||||
|
builder.reset();
|
||||||
|
let offset4 = builder.try_create_shared_string("welcome").unwrap();
|
||||||
|
let offset5 = builder
|
||||||
|
.try_create_shared_string("welcome to flatbuffers!!")
|
||||||
|
.unwrap();
|
||||||
|
assert_ne!(offset2.value(), offset4.value());
|
||||||
|
assert_ne!(offset5.value(), offset1.value());
|
||||||
|
|
||||||
|
builder.reset();
|
||||||
|
// Shared strings work with an object in between writes
|
||||||
|
let name = builder.try_create_shared_string("foo").unwrap();
|
||||||
|
let enemy =
|
||||||
|
my_game::example::Monster::create(&mut builder, &my_game::example::MonsterArgs {
|
||||||
|
name: Some(name),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
let secondary_name = builder.try_create_shared_string("foo").unwrap();
|
||||||
|
assert_eq!(name.value(), secondary_name.value());
|
||||||
|
|
||||||
|
let args = my_game::example::MonsterArgs {
|
||||||
|
name: Some(secondary_name),
|
||||||
|
enemy: Some(enemy),
|
||||||
|
testarrayofstring: Some(builder.try_create_vector(&[name, secondary_name]).unwrap()),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let main_monster = my_game::example::Monster::create(&mut builder, &args);
|
||||||
|
builder.try_finish(main_monster, None).unwrap();
|
||||||
|
let monster =
|
||||||
|
my_game::example::root_as_monster(builder.finished_data()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(monster.enemy().unwrap().name(), "foo");
|
||||||
|
let string_vector = monster.testarrayofstring().unwrap();
|
||||||
|
assert_eq!(string_vector.get(0), "foo");
|
||||||
|
assert_eq!(string_vector.get(1), "foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_vector_manual_build_roundtrip() {
|
||||||
|
// Build a vector of scalars manually using try_start_vector / try_push / try_end_vector.
|
||||||
|
let mut builder = flatbuffers::FlatBufferBuilder::new();
|
||||||
|
let items: Vec<u32> = vec![10, 20, 30, 40, 50];
|
||||||
|
|
||||||
|
builder
|
||||||
|
.try_start_vector::<u32>(items.len())
|
||||||
|
.unwrap();
|
||||||
|
for &v in items.iter().rev() {
|
||||||
|
builder.try_push::<u32>(v).unwrap();
|
||||||
|
}
|
||||||
|
let vecend = builder.try_end_vector::<u32>(items.len()).unwrap();
|
||||||
|
builder.try_finish_minimal(vecend).unwrap();
|
||||||
|
|
||||||
|
let buf = builder.finished_data();
|
||||||
|
let got = unsafe {
|
||||||
|
<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u32>>>::follow(&buf[..], 0)
|
||||||
|
};
|
||||||
|
let result: Vec<u32> = got.iter().collect();
|
||||||
|
assert_eq!(result, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_create_vector_roundtrip() {
|
||||||
|
let mut builder = flatbuffers::FlatBufferBuilder::new();
|
||||||
|
let items: Vec<i64> = vec![-1, 0, 1, i64::MIN, i64::MAX];
|
||||||
|
let offset = builder.try_create_vector(&items).unwrap();
|
||||||
|
builder.try_finish_minimal(offset).unwrap();
|
||||||
|
|
||||||
|
let buf = builder.finished_data();
|
||||||
|
let got = unsafe {
|
||||||
|
<flatbuffers::ForwardsUOffset<flatbuffers::Vector<i64>>>::follow(&buf[..], 0)
|
||||||
|
};
|
||||||
|
let result: Vec<i64> = got.iter().collect();
|
||||||
|
assert_eq!(result, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_create_vector_from_iter_roundtrip() {
|
||||||
|
let mut builder = flatbuffers::FlatBufferBuilder::new();
|
||||||
|
let items: Vec<f64> = vec![1.0, 2.5, -3.14, 0.0];
|
||||||
|
let offset = builder
|
||||||
|
.try_create_vector_from_iter(items.iter().copied())
|
||||||
|
.unwrap();
|
||||||
|
builder.try_finish_minimal(offset).unwrap();
|
||||||
|
|
||||||
|
let buf = builder.finished_data();
|
||||||
|
let got = unsafe {
|
||||||
|
<flatbuffers::ForwardsUOffset<flatbuffers::Vector<f64>>>::follow(&buf[..], 0)
|
||||||
|
};
|
||||||
|
let result: Vec<f64> = got.iter().collect();
|
||||||
|
assert_eq!(result, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_create_byte_string_roundtrip() {
|
||||||
|
let mut builder = flatbuffers::FlatBufferBuilder::new();
|
||||||
|
let data = b"hello bytes";
|
||||||
|
let offset = builder.try_create_byte_string(data).unwrap();
|
||||||
|
builder.try_finish_minimal(offset).unwrap();
|
||||||
|
|
||||||
|
let buf = builder.finished_data();
|
||||||
|
let got = unsafe {
|
||||||
|
<flatbuffers::ForwardsUOffset<&[u8]>>::follow(&buf[..], 0)
|
||||||
|
};
|
||||||
|
assert_eq!(got, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_finish_size_prefixed_roundtrip() {
|
||||||
|
let mut builder = flatbuffers::FlatBufferBuilder::new();
|
||||||
|
let args = &my_game::example::MonsterArgs {
|
||||||
|
mana: 200,
|
||||||
|
hp: 300,
|
||||||
|
name: Some(builder.try_create_string("bob").unwrap()),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let mon = my_game::example::Monster::create(&mut builder, &args);
|
||||||
|
builder.try_finish_size_prefixed(mon, None).unwrap();
|
||||||
|
|
||||||
|
let buf = builder.finished_data();
|
||||||
|
let m = flatbuffers::size_prefixed_root::<my_game::example::Monster>(buf).unwrap();
|
||||||
|
assert_eq!(m.mana(), 200);
|
||||||
|
assert_eq!(m.hp(), 300);
|
||||||
|
assert_eq!(m.name(), "bob");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_finish_with_file_identifier() {
|
||||||
|
let mut builder = flatbuffers::FlatBufferBuilder::new();
|
||||||
|
let name = builder.try_create_string("foo").unwrap();
|
||||||
|
let args = &my_game::example::MonsterArgs {
|
||||||
|
name: Some(name),
|
||||||
|
hp: 42,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let mon = my_game::example::Monster::create(&mut builder, &args);
|
||||||
|
builder
|
||||||
|
.try_finish(mon, Some(my_game::example::MONSTER_IDENTIFIER))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let buf = builder.finished_data();
|
||||||
|
assert!(my_game::example::monster_buffer_has_identifier(buf));
|
||||||
|
let m = my_game::example::root_as_monster(buf).unwrap();
|
||||||
|
assert_eq!(m.name(), "foo");
|
||||||
|
assert_eq!(m.hp(), 42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,51 +14,58 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import XCTest
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
|
||||||
@testable import FlatBuffers
|
@testable import FlatBuffers
|
||||||
|
|
||||||
final class ByteBufferTests: XCTestCase {
|
struct ByteBufferTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCopyingMemory() {
|
func testCopyingMemory() {
|
||||||
let count = 100
|
let count = 100
|
||||||
let ptr = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: 1)
|
let ptr = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: 1)
|
||||||
let byteBuffer = ByteBuffer(copyingMemoryBound: ptr, capacity: count)
|
let byteBuffer = ByteBuffer(copyingMemoryBound: ptr, capacity: count)
|
||||||
byteBuffer.withUnsafeBytes { memory in
|
byteBuffer.withUnsafeBytes { memory in
|
||||||
XCTAssertNotEqual(memory.baseAddress, ptr)
|
#expect(memory.baseAddress! != ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testSamePointer() {
|
func testSamePointer() {
|
||||||
let count = 100
|
let count = 100
|
||||||
let ptr = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: 1)
|
let ptr = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: 1)
|
||||||
let byteBuffer = ByteBuffer(assumingMemoryBound: ptr, capacity: count)
|
let byteBuffer = ByteBuffer(assumingMemoryBound: ptr, capacity: count)
|
||||||
byteBuffer.withUnsafeBytes { memory in
|
byteBuffer.withUnsafeBytes { memory in
|
||||||
XCTAssertEqual(memory.baseAddress!, ptr)
|
#expect(memory.baseAddress! == ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testSameDataPtr() {
|
func testSameDataPtr() {
|
||||||
let count = 100
|
let count = 100
|
||||||
let ptr = Data(repeating: 0, count: count)
|
let ptr = Data(repeating: 0, count: count)
|
||||||
let byteBuffer = ByteBuffer(data: ptr)
|
let byteBuffer = ByteBuffer(data: ptr)
|
||||||
byteBuffer.withUnsafeBytes { memory in
|
byteBuffer.withUnsafeBytes { memory in
|
||||||
ptr.withUnsafeBytes { ptr in
|
ptr.withUnsafeBytes { ptr in
|
||||||
XCTAssertEqual(memory.baseAddress!, ptr.baseAddress!)
|
#expect(memory.baseAddress! == ptr.baseAddress!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testSameArrayPtr() {
|
func testSameArrayPtr() {
|
||||||
let count = 100
|
let count = 100
|
||||||
let ptr: [UInt8] = Array(repeating: 0, count: count)
|
let ptr: [UInt8] = Array(repeating: 0, count: count)
|
||||||
let byteBuffer = ByteBuffer(bytes: ptr)
|
let byteBuffer = ByteBuffer(bytes: ptr)
|
||||||
ptr.withUnsafeBytes { ptr in
|
ptr.withUnsafeBytes { ptr in
|
||||||
byteBuffer.withUnsafeBytes { memory in
|
byteBuffer.withUnsafeBytes { memory in
|
||||||
XCTAssertEqual(memory.baseAddress, ptr.baseAddress)
|
#expect(memory.baseAddress == ptr.baseAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadingDoubleBuffer() {
|
func testReadingDoubleBuffer() {
|
||||||
let count = 8
|
let count = 8
|
||||||
let array: [Double] = Array(repeating: 8.8, count: count)
|
let array: [Double] = Array(repeating: 8.8, count: count)
|
||||||
@@ -69,15 +76,16 @@ final class ByteBufferTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
let byteBuffer = ByteBuffer(bytes: bytes)
|
let byteBuffer = ByteBuffer(bytes: bytes)
|
||||||
byteBuffer.withUnsafePointerToSlice(index: 0, count: count) { ptr in
|
byteBuffer.withUnsafePointerToSlice(index: 0, count: count) { ptr in
|
||||||
XCTAssertEqual(ptr.count, count)
|
#expect(ptr.count == count)
|
||||||
bytes.withUnsafeBufferPointer {
|
bytes.withUnsafeBufferPointer {
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
UnsafeRawPointer($0.baseAddress),
|
UnsafeRawPointer($0.baseAddress) ==
|
||||||
UnsafeRawPointer(ptr.baseAddress))
|
UnsafeRawPointer(ptr.baseAddress))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadingNativeStructs() {
|
func testReadingNativeStructs() {
|
||||||
let array = [
|
let array = [
|
||||||
MyGame_Example_Vec3(
|
MyGame_Example_Vec3(
|
||||||
@@ -111,11 +119,11 @@ final class ByteBufferTests: XCTestCase {
|
|||||||
let byteBuffer = ByteBuffer(bytes: bytes)
|
let byteBuffer = ByteBuffer(bytes: bytes)
|
||||||
byteBuffer
|
byteBuffer
|
||||||
.withUnsafePointerToSlice(index: 0, count: count) { bufferPointer in
|
.withUnsafePointerToSlice(index: 0, count: count) { bufferPointer in
|
||||||
XCTAssertEqual(bufferPointer.count, count)
|
#expect(bufferPointer.count == count)
|
||||||
bytes.withUnsafeBufferPointer { ptr in
|
bytes.withUnsafeBufferPointer { ptr in
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
UnsafeRawPointer(ptr.baseAddress),
|
UnsafeRawPointer(ptr.baseAddress) ==
|
||||||
UnsafeRawPointer(bufferPointer.baseAddress))
|
UnsafeRawPointer(bufferPointer.baseAddress))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,7 +134,3 @@ private struct TestNativeStructs: NativeStruct {
|
|||||||
let y: Double
|
let y: Double
|
||||||
let z: Int
|
let z: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MyGame_Example_Color: CaseIterable {
|
|
||||||
public static var allCases: [MyGame_Example_Color] = [.red, .blue, .green]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,18 +16,22 @@
|
|||||||
|
|
||||||
#if compiler(>=6.2)
|
#if compiler(>=6.2)
|
||||||
|
|
||||||
import XCTest
|
import Testing
|
||||||
|
|
||||||
@testable import FlatBuffers
|
@testable import FlatBuffers
|
||||||
|
|
||||||
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *)
|
struct FlatBuffersArraysTests {
|
||||||
final class FlatBuffersArraysTests: XCTestCase {
|
|
||||||
|
|
||||||
|
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *)
|
||||||
|
@Test
|
||||||
func testStructSizes() {
|
func testStructSizes() {
|
||||||
XCTAssertEqual(MemoryLayout<MyGame_Example_NestedStruct>.size, 32)
|
#expect(MemoryLayout<MyGame_Example_NestedStruct>.size == 32)
|
||||||
XCTAssertEqual(MemoryLayout<MyGame_Example_ArrayStruct>.size, 160)
|
#expect(MemoryLayout<MyGame_Example_ArrayStruct>.size == 160)
|
||||||
|
#expect((MemoryLayout<MyGame_Example_LargeArrayStruct>.size == 2496))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *)
|
||||||
|
@Test
|
||||||
func testGoldenData() {
|
func testGoldenData() {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
let data: [UInt8] = [
|
let data: [UInt8] = [
|
||||||
@@ -44,9 +48,11 @@ final class FlatBuffersArraysTests: XCTestCase {
|
|||||||
]
|
]
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
|
|
||||||
XCTAssertEqual(data, createArrayTable())
|
#expect(data == createArrayTable())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *)
|
||||||
|
@Test
|
||||||
func testData() throws {
|
func testData() throws {
|
||||||
var buf = ByteBuffer(bytes: createArrayTable())
|
var buf = ByteBuffer(bytes: createArrayTable())
|
||||||
let table: MyGame_Example_ArrayTable = try getCheckedRoot(
|
let table: MyGame_Example_ArrayTable = try getCheckedRoot(
|
||||||
@@ -57,6 +63,8 @@ final class FlatBuffersArraysTests: XCTestCase {
|
|||||||
verifyNativeStruct(a: table.a)
|
verifyNativeStruct(a: table.a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *)
|
||||||
|
@Test
|
||||||
func testObjectAPI() throws {
|
func testObjectAPI() throws {
|
||||||
var buf = ByteBuffer(bytes: createArrayTable())
|
var buf = ByteBuffer(bytes: createArrayTable())
|
||||||
let table: MyGame_Example_ArrayTable = try getCheckedRoot(
|
let table: MyGame_Example_ArrayTable = try getCheckedRoot(
|
||||||
@@ -65,105 +73,110 @@ final class FlatBuffersArraysTests: XCTestCase {
|
|||||||
verifyNativeStruct(a: table.unpack().a)
|
verifyNativeStruct(a: table.unpack().a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *)
|
||||||
|
@Test
|
||||||
func testDefaults() {
|
func testDefaults() {
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
MyGame_Example_NestedStruct(),
|
MyGame_Example_NestedStruct() ==
|
||||||
MyGame_Example_NestedStruct(
|
MyGame_Example_NestedStruct(
|
||||||
a: [0, 0],
|
a: [0, 0],
|
||||||
b: .a,
|
b: .a,
|
||||||
c: [0, 0],
|
c: [0, 0],
|
||||||
d: [0, 0]))
|
d: [0, 0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *)
|
||||||
func verifyNativeStruct(a: MyGame_Example_ArrayStruct?) {
|
func verifyNativeStruct(a: MyGame_Example_ArrayStruct?) {
|
||||||
let a = a!
|
let a = a!
|
||||||
XCTAssertEqual(a.a, 12.34)
|
#expect(a.a == 12.34)
|
||||||
XCTAssertEqual(a.b.count, 15)
|
#expect(a.b.count == 15)
|
||||||
var sum: Int32 = 0
|
var sum: Int32 = 0
|
||||||
for i in a.b.startIndex..<a.b.endIndex {
|
for i in a.b.startIndex..<a.b.endIndex {
|
||||||
sum += a.b[i]
|
sum += a.b[i]
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum, 120)
|
#expect(sum == 120)
|
||||||
XCTAssertEqual(a.c, -127)
|
#expect(a.c == -127)
|
||||||
XCTAssertEqual(a.d.count, 2)
|
#expect(a.d.count == 2)
|
||||||
let nestedStruct1 = a.d[0]
|
let nestedStruct1 = a.d[0]
|
||||||
XCTAssertEqual(nestedStruct1.a.toArray(), [-1, 2])
|
#expect(nestedStruct1.a.toArray() == [-1, 2])
|
||||||
XCTAssertEqual(nestedStruct1.b, .a)
|
#expect(nestedStruct1.b == .a)
|
||||||
XCTAssertEqual(nestedStruct1.c.toArray(), [.c, .b])
|
#expect(nestedStruct1.c.toArray() == [.c, .b])
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
nestedStruct1.d.toArray(),
|
nestedStruct1.d.toArray() ==
|
||||||
[0x1122334455667788, -0x1122334455667788])
|
[0x1122334455667788, -0x1122334455667788])
|
||||||
|
|
||||||
let nestedStruct2 = a.d[1]
|
let nestedStruct2 = a.d[1]
|
||||||
XCTAssertEqual(nestedStruct2.a.toArray(), [3, -4])
|
#expect(nestedStruct2.a.toArray() == [3, -4])
|
||||||
XCTAssertEqual(nestedStruct2.b, .b)
|
#expect(nestedStruct2.b == .b)
|
||||||
XCTAssertEqual(nestedStruct2.c.toArray(), [.b, .a])
|
#expect(nestedStruct2.c.toArray() == [.b, .a])
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
nestedStruct2.d.toArray(),
|
nestedStruct2.d.toArray() ==
|
||||||
[-0x1122334455667788, 0x1122334455667788])
|
[-0x1122334455667788, 0x1122334455667788])
|
||||||
|
|
||||||
XCTAssertEqual(a.e, 1)
|
#expect(a.e == 1)
|
||||||
XCTAssertEqual(a.f.count, 2)
|
#expect(a.f.count == 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *)
|
||||||
func verifyMutations(in table: MyGame_Example_ArrayTable) {
|
func verifyMutations(in table: MyGame_Example_ArrayTable) {
|
||||||
let a = table.mutableA!
|
let a = table.mutableA!
|
||||||
XCTAssertEqual(a.a, 12.34)
|
#expect(a.a == 12.34)
|
||||||
XCTAssertEqual(a.b.count, 15)
|
#expect(a.b.count == 15)
|
||||||
var sum: Int32 = 0
|
var sum: Int32 = 0
|
||||||
for i in a.b.startIndex..<a.b.endIndex {
|
for i in a.b.startIndex..<a.b.endIndex {
|
||||||
sum += a.b[i]
|
sum += a.b[i]
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum, 120)
|
#expect(sum == 120)
|
||||||
XCTAssertEqual(a.c, -127)
|
#expect(a.c == -127)
|
||||||
XCTAssertEqual(a.d.count, 2)
|
#expect(a.d.count == 2)
|
||||||
let nestedStruct1 = a.d[0]
|
let nestedStruct1 = a.d[0]
|
||||||
|
|
||||||
XCTAssertEqual(nestedStruct1.a.reduce(0) { $0 + $1 }, 1)
|
#expect(nestedStruct1.a.reduce(0) { $0 + $1 } == 1)
|
||||||
XCTAssertEqual(nestedStruct1.b, .a)
|
#expect(nestedStruct1.b == .a)
|
||||||
XCTAssertEqual(nestedStruct1.c[0], .c)
|
#expect(nestedStruct1.c[0] == .c)
|
||||||
XCTAssertEqual(nestedStruct1.c[1], .b)
|
#expect(nestedStruct1.c[1] == .b)
|
||||||
|
|
||||||
let nestedStruct2 = a.d[1]
|
let nestedStruct2 = a.d[1]
|
||||||
XCTAssertEqual(nestedStruct2.a.reduce(0) { $0 + $1 }, -1)
|
#expect(nestedStruct2.a.reduce(0) { $0 + $1 } == -1)
|
||||||
XCTAssertEqual(nestedStruct2.b, .b)
|
#expect(nestedStruct2.b == .b)
|
||||||
XCTAssertEqual(nestedStruct2.c[0], .b)
|
#expect(nestedStruct2.c[0] == .b)
|
||||||
XCTAssertEqual(nestedStruct2.c[1], .a)
|
#expect(nestedStruct2.c[1] == .a)
|
||||||
XCTAssertEqual(nestedStruct2.d[0], -0x1122334455667788)
|
#expect(nestedStruct2.d[0] == -0x1122334455667788)
|
||||||
XCTAssertEqual(nestedStruct2.d[1], 0x1122334455667788)
|
#expect(nestedStruct2.d[1] == 0x1122334455667788)
|
||||||
|
|
||||||
XCTAssertTrue(a.mutate(b: 1000, at: 0))
|
#expect(a.mutate(b: 1000, at: 0) == true)
|
||||||
XCTAssertTrue(a.mutate(b: 2000, at: 1))
|
#expect(a.mutate(b: 2000, at: 1) == true)
|
||||||
|
|
||||||
XCTAssertTrue(nestedStruct2.mutate(c: .a, at: 0))
|
#expect(nestedStruct2.mutate(c: .a, at: 0) == true)
|
||||||
XCTAssertTrue(nestedStruct2.mutate(c: .b, at: 1))
|
#expect(nestedStruct2.mutate(c: .b, at: 1) == true)
|
||||||
|
|
||||||
XCTAssertEqual(nestedStruct2.c[0], .a)
|
#expect(nestedStruct2.c[0] == .a)
|
||||||
XCTAssertEqual(nestedStruct2.c[1], .b)
|
#expect(nestedStruct2.c[1] == .b)
|
||||||
|
|
||||||
XCTAssertTrue(nestedStruct2.mutate(d: 0, at: 0))
|
#expect(nestedStruct2.mutate(d: 0, at: 0) == true)
|
||||||
XCTAssertTrue(nestedStruct2.mutate(d: 0, at: 1))
|
#expect(nestedStruct2.mutate(d: 0, at: 1) == true)
|
||||||
|
|
||||||
XCTAssertEqual(nestedStruct2.d.reduce(0) { $0 + $1 }, 0)
|
#expect(nestedStruct2.d.reduce(0) { $0 + $1 } == 0)
|
||||||
|
|
||||||
let nativeStruct = table.a?.d[1]
|
let nativeStruct = table.a?.d[1]
|
||||||
|
|
||||||
XCTAssertEqual(nativeStruct?.c[0], .a)
|
#expect(nativeStruct?.c[0] == .a)
|
||||||
XCTAssertEqual(nativeStruct?.c[1], .b)
|
#expect(nativeStruct?.c[1] == .b)
|
||||||
|
|
||||||
XCTAssertEqual(nativeStruct?.d[0], 0)
|
#expect(nativeStruct?.d[0] == 0)
|
||||||
XCTAssertEqual(nativeStruct?.d[1], 0)
|
#expect(nativeStruct?.d[1] == 0)
|
||||||
|
|
||||||
XCTAssertTrue(a.mutate(b: 1, at: 0))
|
#expect(a.mutate(b: 1, at: 0) == true)
|
||||||
XCTAssertTrue(a.mutate(b: 2, at: 1))
|
#expect(a.mutate(b: 2, at: 1) == true)
|
||||||
|
|
||||||
XCTAssertTrue(nestedStruct2.mutate(c: .b, at: 0))
|
#expect(nestedStruct2.mutate(c: .b, at: 0) == true)
|
||||||
XCTAssertTrue(nestedStruct2.mutate(c: .a, at: 1))
|
#expect(nestedStruct2.mutate(c: .a, at: 1) == true)
|
||||||
|
|
||||||
XCTAssertTrue(nestedStruct2.mutate(d: -0x1122334455667788, at: 0))
|
#expect(nestedStruct2.mutate(d: -0x1122334455667788, at: 0) == true)
|
||||||
XCTAssertTrue(nestedStruct2.mutate(d: 0x1122334455667788, at: 1))
|
#expect(nestedStruct2.mutate(d: 0x1122334455667788, at: 1) == true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *)
|
||||||
private func createArrayTable() -> [UInt8] {
|
private func createArrayTable() -> [UInt8] {
|
||||||
var builder = FlatBufferBuilder(initialSize: 1024)
|
var builder = FlatBufferBuilder(initialSize: 1024)
|
||||||
|
|
||||||
@@ -233,4 +246,3 @@ extension InlineArray: @retroactive Equatable where Element: Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import XCTest
|
import Testing
|
||||||
|
|
||||||
@testable import FlatBuffers
|
@testable import FlatBuffers
|
||||||
|
|
||||||
@@ -24,8 +24,9 @@ typealias Monster = MyGame_Example_Monster
|
|||||||
typealias Vec3 = MyGame_Example_Vec3
|
typealias Vec3 = MyGame_Example_Vec3
|
||||||
typealias Stat = MyGame_Example_Stat
|
typealias Stat = MyGame_Example_Stat
|
||||||
|
|
||||||
class FlatBuffersMonsterWriterTests: XCTestCase {
|
struct FlatBuffersMonsterWriterTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
func testData() {
|
func testData() {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
let data = Data([
|
let data = Data([
|
||||||
@@ -47,12 +48,13 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
readVerifiedMonster(fb: _data)
|
readVerifiedMonster(fb: _data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadFromOtherLanguages() {
|
func testReadFromOtherLanguages() {
|
||||||
let path = {
|
let path = {
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
// Gets the current path of this test file then
|
// Gets the current path of this test file then
|
||||||
// strips out the nested directories.
|
// strips out the nested directories.
|
||||||
let filePath = URL(filePath: #file)
|
let filePath = URL(filePath: #filePath)
|
||||||
.deletingLastPathComponent()
|
.deletingLastPathComponent()
|
||||||
return filePath.absoluteString
|
return filePath.absoluteString
|
||||||
#else
|
#else
|
||||||
@@ -71,6 +73,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
readVerifiedMonster(fb: _data)
|
readVerifiedMonster(fb: _data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMonsterData() {
|
func testCreateMonsterData() {
|
||||||
let bytes = createMonster(withPrefix: false)
|
let bytes = createMonster(withPrefix: false)
|
||||||
var buffer = ByteBuffer(data: bytes.data)
|
var buffer = ByteBuffer(data: bytes.data)
|
||||||
@@ -80,30 +83,32 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
readMonster(monster: monster)
|
readMonster(monster: monster)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(.bug("https://github.com/google/flatbuffers/issues/8642"))
|
||||||
func testCreateMonsterResetTests() {
|
func testCreateMonsterResetTests() {
|
||||||
var builder = createMonster(withPrefix: false)
|
var builder = createMonster(withPrefix: false)
|
||||||
var buffer = ByteBuffer(data: builder.data)
|
var buffer = ByteBuffer(data: builder.data)
|
||||||
let monster: MyGame_Example_Monster = getRoot(byteBuffer: &buffer)
|
let monster: MyGame_Example_Monster = getRoot(byteBuffer: &buffer)
|
||||||
readMonster(monster: monster)
|
readMonster(monster: monster)
|
||||||
builder.clear()
|
builder.clear()
|
||||||
XCTAssertEqual(builder.capacity, 1)
|
#expect(builder.capacity == 1)
|
||||||
XCTAssertEqual(builder.size, 0)
|
#expect(builder.size == 0)
|
||||||
|
|
||||||
write(fbb: &builder, prefix: false)
|
write(fbb: &builder, prefix: false)
|
||||||
var _buffer = ByteBuffer(data: builder.data)
|
var _buffer = ByteBuffer(data: builder.data)
|
||||||
XCTAssertEqual(_buffer.capacity, 304)
|
#expect(_buffer.capacity == 304)
|
||||||
let _monster: MyGame_Example_Monster = getRoot(byteBuffer: &_buffer)
|
let _monster: MyGame_Example_Monster = getRoot(byteBuffer: &_buffer)
|
||||||
readMonster(monster: _monster)
|
readMonster(monster: _monster)
|
||||||
builder.clear(keepingCapacity: true)
|
builder.clear(keepingCapacity: true)
|
||||||
XCTAssertEqual(builder.capacity, 512)
|
#expect(builder.capacity == 512)
|
||||||
XCTAssertEqual(builder.size, 0)
|
#expect(builder.size == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMonster() {
|
func testCreateMonster() {
|
||||||
let bytes = createMonster(withPrefix: false)
|
let bytes = createMonster(withPrefix: false)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
bytes.sizedByteArray,
|
bytes.sizedByteArray ==
|
||||||
[
|
[
|
||||||
48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28,
|
48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28,
|
||||||
0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0,
|
0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0,
|
||||||
@@ -127,11 +132,12 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
readMonster(monster: monster)
|
readMonster(monster: monster)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMonsterResizedBuffer() {
|
func testCreateMonsterResizedBuffer() {
|
||||||
let bytes = createMonster(withPrefix: false)
|
let bytes = createMonster(withPrefix: false)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
bytes.sizedByteArray,
|
bytes.sizedByteArray ==
|
||||||
[
|
[
|
||||||
48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28,
|
48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28,
|
||||||
0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0,
|
0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0,
|
||||||
@@ -150,11 +156,12 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
readVerifiedMonster(fb: bytes.sizedBuffer)
|
readVerifiedMonster(fb: bytes.sizedBuffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMonsterPrefixed() {
|
func testCreateMonsterPrefixed() {
|
||||||
let bytes = createMonster(withPrefix: true)
|
let bytes = createMonster(withPrefix: true)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
bytes.sizedByteArray,
|
bytes.sizedByteArray ==
|
||||||
[
|
[
|
||||||
44, 1, 0, 0, 44, 0, 0, 0, 77, 79, 78, 83, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28,
|
44, 1, 0, 0, 44, 0, 0, 0, 77, 79, 78, 83, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28,
|
||||||
0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0,
|
0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0,
|
||||||
@@ -175,6 +182,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
readMonster(monster: getPrefixedSizeRoot(byteBuffer: &buffer))
|
readMonster(monster: getPrefixedSizeRoot(byteBuffer: &buffer))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMonsterUsingCreateMonsterMethodWithNilPos() {
|
func testCreateMonsterUsingCreateMonsterMethodWithNilPos() {
|
||||||
var fbb = FlatBufferBuilder(initialSize: 1)
|
var fbb = FlatBufferBuilder(initialSize: 1)
|
||||||
let name = fbb.create(string: "Frodo")
|
let name = fbb.create(string: "Frodo")
|
||||||
@@ -184,10 +192,11 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
fbb.finish(offset: root)
|
fbb.finish(offset: root)
|
||||||
var buffer = fbb.sizedBuffer
|
var buffer = fbb.sizedBuffer
|
||||||
let newMonster: Monster = getRoot(byteBuffer: &buffer)
|
let newMonster: Monster = getRoot(byteBuffer: &buffer)
|
||||||
XCTAssertNil(newMonster.pos)
|
#expect(newMonster.pos == nil)
|
||||||
XCTAssertEqual(newMonster.name, "Frodo")
|
#expect(newMonster.name == "Frodo")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMonsterUsingCreateMonsterMethodWithPosX() {
|
func testCreateMonsterUsingCreateMonsterMethodWithPosX() {
|
||||||
var fbb = FlatBufferBuilder(initialSize: 1)
|
var fbb = FlatBufferBuilder(initialSize: 1)
|
||||||
let name = fbb.create(string: "Barney")
|
let name = fbb.create(string: "Barney")
|
||||||
@@ -207,10 +216,11 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
|
|
||||||
var buffer = fbb.sizedBuffer
|
var buffer = fbb.sizedBuffer
|
||||||
let newMonster: Monster = getRoot(byteBuffer: &buffer)
|
let newMonster: Monster = getRoot(byteBuffer: &buffer)
|
||||||
XCTAssertEqual(newMonster.pos!.x, 10)
|
#expect(newMonster.pos!.x == 10)
|
||||||
XCTAssertEqual(newMonster.name, "Barney")
|
#expect(newMonster.name == "Barney")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadMonsterFromUnsafePointerWithoutCopying() {
|
func testReadMonsterFromUnsafePointerWithoutCopying() {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
var array: [UInt8] = [
|
var array: [UInt8] = [
|
||||||
@@ -242,6 +252,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
readObjectApi(monster: unpacked)
|
readObjectApi(monster: unpacked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testArrayOfBools() {
|
func testArrayOfBools() {
|
||||||
let boolArray = [false, true, false, true, false, true, false]
|
let boolArray = [false, true, false, true, false, true, false]
|
||||||
var fbb = FlatBufferBuilder(initialSize: 1)
|
var fbb = FlatBufferBuilder(initialSize: 1)
|
||||||
@@ -257,37 +268,41 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
let monster: Monster = getRoot(byteBuffer: &buffer)
|
let monster: Monster = getRoot(byteBuffer: &buffer)
|
||||||
let values = monster.testarrayofbools
|
let values = monster.testarrayofbools
|
||||||
|
|
||||||
XCTAssertEqual(boolArray.count, values.count)
|
#expect(boolArray.count == values.count)
|
||||||
|
|
||||||
for (index, bool) in monster.testarrayofbools.enumerated() {
|
for (index, bool) in monster.testarrayofbools.enumerated() {
|
||||||
XCTAssertEqual(bool, boolArray[index])
|
#expect(bool == boolArray[index])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readVerifiedMonster(fb: ByteBuffer) {
|
func readVerifiedMonster(fb: ByteBuffer) {
|
||||||
var byteBuffer = fb
|
var byteBuffer = fb
|
||||||
XCTAssertNoThrow(
|
do {
|
||||||
try readMonster(
|
try readMonster(
|
||||||
monster: getCheckedRoot(
|
monster: getCheckedRoot(
|
||||||
byteBuffer: &byteBuffer) as MyGame_Example_Monster))
|
byteBuffer: &byteBuffer) as MyGame_Example_Monster)
|
||||||
|
} catch {
|
||||||
|
Issue.record(error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(.bug("https://github.com/google/flatbuffers/issues/8133"))
|
||||||
func testUnalignedRead() {
|
func testUnalignedRead() {
|
||||||
// Aligned read
|
// Aligned read
|
||||||
let fbb = createMonster(withPrefix: false)
|
let fbb = createMonster(withPrefix: false)
|
||||||
let testAligned: () -> Bool = {
|
let testAligned: () -> Bool = {
|
||||||
var buffer = fbb.sizedBuffer
|
var buffer = fbb.sizedBuffer
|
||||||
var monster: Monster = getRoot(byteBuffer: &buffer)
|
var monster: Monster = getRoot(byteBuffer: &buffer)
|
||||||
self.readFlatbufferMonster(monster: &monster)
|
readFlatbufferMonster(monster: &monster)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
XCTAssertEqual(testAligned(), true)
|
#expect(testAligned() == true)
|
||||||
let testUnaligned: () -> Bool = {
|
let testUnaligned: () -> Bool = {
|
||||||
var bytes: [UInt8] = [0x00]
|
var bytes: [UInt8] = [0x00]
|
||||||
bytes.append(contentsOf: fbb.sizedByteArray)
|
bytes.append(contentsOf: fbb.sizedByteArray)
|
||||||
return bytes.withUnsafeMutableBytes { ptr in
|
return bytes.withUnsafeMutableBytes { ptr in
|
||||||
guard var baseAddress = ptr.baseAddress else {
|
guard var baseAddress = ptr.baseAddress else {
|
||||||
XCTFail("Base pointer is not defined")
|
Issue.record("Base pointer is not defined")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
baseAddress = baseAddress.advanced(by: 1)
|
baseAddress = baseAddress.advanced(by: 1)
|
||||||
@@ -296,13 +311,14 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
assumingMemoryBound: unlignedPtr,
|
assumingMemoryBound: unlignedPtr,
|
||||||
capacity: ptr.count - 1)
|
capacity: ptr.count - 1)
|
||||||
var monster: Monster = getRoot(byteBuffer: &bytes)
|
var monster: Monster = getRoot(byteBuffer: &bytes)
|
||||||
self.readFlatbufferMonster(monster: &monster)
|
readFlatbufferMonster(monster: &monster)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XCTAssertEqual(testUnaligned(), true)
|
#expect(testUnaligned() == true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadingRemovedSizeUnalignedBuffer() {
|
func testReadingRemovedSizeUnalignedBuffer() {
|
||||||
// Aligned read
|
// Aligned read
|
||||||
let fbb = createMonster(withPrefix: true)
|
let fbb = createMonster(withPrefix: true)
|
||||||
@@ -311,7 +327,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
bytes.append(contentsOf: fbb.sizedByteArray)
|
bytes.append(contentsOf: fbb.sizedByteArray)
|
||||||
return bytes.withUnsafeMutableBytes { ptr in
|
return bytes.withUnsafeMutableBytes { ptr in
|
||||||
guard var baseAddress = ptr.baseAddress else {
|
guard var baseAddress = ptr.baseAddress else {
|
||||||
XCTFail("Base pointer is not defined")
|
Issue.record("Base pointer is not defined")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
baseAddress = baseAddress.advanced(by: 1)
|
baseAddress = baseAddress.advanced(by: 1)
|
||||||
@@ -321,32 +337,34 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
capacity: ptr.count - 1)
|
capacity: ptr.count - 1)
|
||||||
var newBuf = FlatBuffersUtils.removeSizePrefix(bb: bytes)
|
var newBuf = FlatBuffersUtils.removeSizePrefix(bb: bytes)
|
||||||
var monster: Monster = getRoot(byteBuffer: &newBuf)
|
var monster: Monster = getRoot(byteBuffer: &newBuf)
|
||||||
self.readFlatbufferMonster(monster: &monster)
|
readFlatbufferMonster(monster: &monster)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XCTAssertEqual(testUnaligned(), true)
|
#expect(testUnaligned() == true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMessage() {
|
func testCreateMessage() {
|
||||||
let fbb = createMonster(withPrefix: false)
|
let fbb = createMonster(withPrefix: false)
|
||||||
let byteBuffer = fbb.buffer
|
let byteBuffer = fbb.buffer
|
||||||
let firstMessage = Message<Monster>(byteBuffer: byteBuffer)
|
let firstMessage = GRPCMessage<Monster>(byteBuffer: byteBuffer)
|
||||||
firstMessage.withUnsafeReadableBytes { ptr in
|
firstMessage.withUnsafeReadableBytes { ptr in
|
||||||
var bytes = ByteBuffer(contiguousBytes: ptr, count: ptr.count)
|
var bytes = ByteBuffer(contiguousBytes: ptr, count: ptr.count)
|
||||||
var monster: Monster = getRoot(byteBuffer: &bytes)
|
var monster: Monster = getRoot(byteBuffer: &bytes)
|
||||||
self.readFlatbufferMonster(monster: &monster)
|
readFlatbufferMonster(monster: &monster)
|
||||||
}
|
}
|
||||||
|
|
||||||
let secondByteBuffer = fbb.sizedBuffer
|
let secondByteBuffer = fbb.sizedBuffer
|
||||||
let secondMessage = Message<Monster>(byteBuffer: secondByteBuffer)
|
let secondMessage = GRPCMessage<Monster>(byteBuffer: secondByteBuffer)
|
||||||
secondMessage.withUnsafeReadableBytes { ptr in
|
secondMessage.withUnsafeReadableBytes { ptr in
|
||||||
var bytes = ByteBuffer(contiguousBytes: ptr, count: ptr.count)
|
var bytes = ByteBuffer(contiguousBytes: ptr, count: ptr.count)
|
||||||
var monster: Monster = getRoot(byteBuffer: &bytes)
|
var monster: Monster = getRoot(byteBuffer: &bytes)
|
||||||
self.readFlatbufferMonster(monster: &monster)
|
readFlatbufferMonster(monster: &monster)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testForceRetainedObject() {
|
func testForceRetainedObject() {
|
||||||
let byteBuffer = {
|
let byteBuffer = {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
@@ -452,95 +470,95 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
var fb = fb
|
var fb = fb
|
||||||
|
|
||||||
let monster: Monster = getRoot(byteBuffer: &fb)
|
let monster: Monster = getRoot(byteBuffer: &fb)
|
||||||
XCTAssertFalse(monster.mutate(mana: 10))
|
#expect(monster.mutate(mana: 10) == false)
|
||||||
XCTAssertEqual(monster.testarrayoftables[0].name, "Barney")
|
#expect(monster.testarrayoftables[0].name == "Barney")
|
||||||
XCTAssertEqual(monster.testarrayoftables[1].name, "Frodo")
|
#expect(monster.testarrayoftables[1].name == "Frodo")
|
||||||
XCTAssertEqual(monster.testarrayoftables[2].name, "Wilma")
|
#expect(monster.testarrayoftables[2].name == "Wilma")
|
||||||
|
|
||||||
// Example of searching for a table by the key
|
// Example of searching for a table by the key
|
||||||
XCTAssertNotNil(monster.testarrayoftablesBy(key: "Frodo"))
|
#expect(monster.testarrayoftablesBy(key: "Frodo") != nil)
|
||||||
XCTAssertNotNil(monster.testarrayoftablesBy(key: "Barney"))
|
#expect(monster.testarrayoftablesBy(key: "Barney") != nil)
|
||||||
XCTAssertNotNil(monster.testarrayoftablesBy(key: "Wilma"))
|
#expect(monster.testarrayoftablesBy(key: "Wilma") != nil)
|
||||||
|
|
||||||
XCTAssertEqual(monster.testType, .monster)
|
#expect(monster.testType == .monster)
|
||||||
|
|
||||||
XCTAssertEqual(monster.mutate(inventory: 1, at: 0), true)
|
#expect(monster.mutate(inventory: 1, at: 0) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 2, at: 1), true)
|
#expect(monster.mutate(inventory: 2, at: 1) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 3, at: 2), true)
|
#expect(monster.mutate(inventory: 3, at: 2) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 4, at: 3), true)
|
#expect(monster.mutate(inventory: 4, at: 3) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 5, at: 4), true)
|
#expect(monster.mutate(inventory: 5, at: 4) == true)
|
||||||
|
|
||||||
for i in 0..<monster.inventory.count {
|
for i in 0..<monster.inventory.count {
|
||||||
XCTAssertEqual(monster.inventory[i], Byte(i + 1))
|
#expect(monster.inventory[i] == Byte(i + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(monster.mutate(inventory: 0, at: 0), true)
|
#expect(monster.mutate(inventory: 0, at: 0) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 1, at: 1), true)
|
#expect(monster.mutate(inventory: 1, at: 1) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 2, at: 2), true)
|
#expect(monster.mutate(inventory: 2, at: 2) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 3, at: 3), true)
|
#expect(monster.mutate(inventory: 3, at: 3) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 4, at: 4), true)
|
#expect(monster.mutate(inventory: 4, at: 4) == true)
|
||||||
|
|
||||||
let vec = monster.mutablePos
|
let vec = monster.mutablePos
|
||||||
XCTAssertEqual(vec?.x, 1)
|
#expect(vec?.x == 1)
|
||||||
XCTAssertTrue(vec?.mutate(x: 55.0) ?? false)
|
#expect(vec?.mutate(x: 55.0) == true)
|
||||||
XCTAssertTrue(vec?.mutate(test1: 55) ?? false)
|
#expect(vec?.mutate(test1: 55) == true)
|
||||||
XCTAssertEqual(vec?.x, 55.0)
|
#expect(vec?.x == 55.0)
|
||||||
XCTAssertEqual(vec?.test1, 55.0)
|
#expect(vec?.test1 == 55.0)
|
||||||
XCTAssertTrue(vec?.mutate(x: 1) ?? false)
|
#expect(vec?.mutate(x: 1) == true)
|
||||||
XCTAssertEqual(vec?.x, 1)
|
#expect(vec?.x == 1)
|
||||||
XCTAssertTrue(vec?.mutate(test1: 3) ?? false)
|
#expect(vec?.mutate(test1: 3) == true)
|
||||||
|
|
||||||
let mutableTest4 = monster.mutableTest4
|
let mutableTest4 = monster.mutableTest4
|
||||||
let orignalValues = mutableTest4[0].a
|
let orignalValues = mutableTest4[0].a
|
||||||
XCTAssertEqual(mutableTest4[0].mutate(a: 100), true)
|
#expect(mutableTest4[0].mutate(a: 100) == true)
|
||||||
XCTAssertNotEqual(monster.test4[0].a, orignalValues)
|
#expect(monster.test4[0].a != orignalValues)
|
||||||
XCTAssertEqual(monster.test4[0].a, 100)
|
#expect(monster.test4[0].a == 100)
|
||||||
XCTAssertEqual(mutableTest4[0].mutate(a: orignalValues), true)
|
#expect(mutableTest4[0].mutate(a: orignalValues) == true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readFlatbufferMonster(monster: inout MyGame_Example_Monster) {
|
func readFlatbufferMonster(monster: inout MyGame_Example_Monster) {
|
||||||
XCTAssertEqual(monster.hp, 80)
|
#expect(monster.hp == 80)
|
||||||
XCTAssertEqual(monster.mana, 150)
|
#expect(monster.mana == 150)
|
||||||
XCTAssertEqual(monster.name, "MyMonster")
|
#expect(monster.name == "MyMonster")
|
||||||
let pos = monster.pos
|
let pos = monster.pos
|
||||||
XCTAssertEqual(pos?.x, 1)
|
#expect(pos?.x == 1)
|
||||||
XCTAssertEqual(pos?.y, 2)
|
#expect(pos?.y == 2)
|
||||||
XCTAssertEqual(pos?.z, 3)
|
#expect(pos?.z == 3)
|
||||||
XCTAssertEqual(pos?.test1, 3)
|
#expect(pos?.test1 == 3)
|
||||||
XCTAssertEqual(pos?.test2, .green)
|
#expect(pos?.test2 == .green)
|
||||||
let test = pos?.test3
|
let test = pos?.test3
|
||||||
XCTAssertEqual(test?.a, 5)
|
#expect(test?.a == 5)
|
||||||
XCTAssertEqual(test?.b, 6)
|
#expect(test?.b == 6)
|
||||||
XCTAssertEqual(monster.testType, .monster)
|
#expect(monster.testType == .monster)
|
||||||
let monster2 = monster.test(type: Monster.self)
|
let monster2 = monster.test(type: Monster.self)
|
||||||
XCTAssertEqual(monster2?.name, "Fred")
|
#expect(monster2?.name == "Fred")
|
||||||
|
|
||||||
XCTAssertEqual(monster.mutate(mana: 10), false)
|
#expect(monster.mutate(mana: 10) == false)
|
||||||
|
|
||||||
XCTAssertEqual(monster.mana, 150)
|
#expect(monster.mana == 150)
|
||||||
XCTAssertEqual(monster.inventory.count, 5)
|
#expect(monster.inventory.count == 5)
|
||||||
var sum: Byte = 0
|
var sum: Byte = 0
|
||||||
for inventory in monster.inventory {
|
for inventory in monster.inventory {
|
||||||
sum += inventory
|
sum += inventory
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum, 10)
|
#expect(sum == 10)
|
||||||
|
|
||||||
monster.withUnsafePointerToInventory { ptr, count in
|
monster.withUnsafePointerToInventory { ptr, count in
|
||||||
var sum: UInt8 = 0
|
var sum: UInt8 = 0
|
||||||
for pointee in ptr.startIndex..<ptr.endIndex {
|
for pointee in ptr.startIndex..<ptr.endIndex {
|
||||||
sum += ptr[pointee]
|
sum += ptr[pointee]
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum, 10)
|
#expect(sum == 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(monster.test4.count, 2)
|
#expect(monster.test4.count == 2)
|
||||||
|
|
||||||
let test4 = monster.test4
|
let test4 = monster.test4
|
||||||
var sum0 = 0
|
var sum0 = 0
|
||||||
for test0 in test4 {
|
for test0 in test4 {
|
||||||
sum0 += Int(test0.a) + Int(test0.b)
|
sum0 += Int(test0.a) + Int(test0.b)
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum0, 100)
|
#expect(sum0 == 100)
|
||||||
|
|
||||||
monster.withUnsafePointerToTest4 { ptr, count in
|
monster.withUnsafePointerToTest4 { ptr, count in
|
||||||
guard let ptr = ptr.baseAddress else { return }
|
guard let ptr = ptr.baseAddress else { return }
|
||||||
@@ -556,7 +574,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
pointerSum += Int(bindedMemory[pointee].a) +
|
pointerSum += Int(bindedMemory[pointee].a) +
|
||||||
Int(bindedMemory[pointee].b)
|
Int(bindedMemory[pointee].b)
|
||||||
}
|
}
|
||||||
XCTAssertEqual(pointerSum, 100)
|
#expect(pointerSum == 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
let mutableTest4 = monster.mutableTest4
|
let mutableTest4 = monster.mutableTest4
|
||||||
@@ -564,87 +582,84 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
for test0 in mutableTest4 {
|
for test0 in mutableTest4 {
|
||||||
sum2 += Int(test0.a) + Int(test0.b)
|
sum2 += Int(test0.a) + Int(test0.b)
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum2, 100)
|
#expect(sum2 == 100)
|
||||||
|
|
||||||
let stringArray = monster.testarrayofstring
|
let stringArray = monster.testarrayofstring
|
||||||
XCTAssertEqual(stringArray.count, 2)
|
#expect(stringArray.count == 2)
|
||||||
XCTAssertEqual(stringArray[0], "test1")
|
#expect(stringArray[0] == "test1")
|
||||||
XCTAssertEqual(stringArray[1], "test2")
|
#expect(stringArray[1] == "test2")
|
||||||
XCTAssertEqual(monster.testbool, true)
|
#expect(monster.testbool == true)
|
||||||
|
|
||||||
let array = monster.nameSegmentArray
|
let array = monster.nameSegmentArray
|
||||||
XCTAssertEqual(String(bytes: array ?? [], encoding: .utf8), "MyMonster")
|
#expect(String(bytes: array ?? [], encoding: .utf8) == "MyMonster")
|
||||||
|
|
||||||
if 0 == monster.testarrayofbools.count {
|
if 0 == monster.testarrayofbools.count {
|
||||||
XCTAssertEqual(monster.testarrayofbools.isEmpty, true)
|
#expect(monster.testarrayofbools.isEmpty == true)
|
||||||
} else {
|
} else {
|
||||||
XCTAssertEqual(monster.testarrayofbools.isEmpty, false)
|
#expect(monster.testarrayofbools.isEmpty == false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readObjectApi(monster: MyGame_Example_MonsterT) {
|
func readObjectApi(monster: MyGame_Example_MonsterT) {
|
||||||
XCTAssertEqual(monster.hp, 80)
|
#expect(monster.hp == 80)
|
||||||
XCTAssertEqual(monster.mana, 150)
|
#expect(monster.mana == 150)
|
||||||
XCTAssertEqual(monster.name, "MyMonster")
|
#expect(monster.name == "MyMonster")
|
||||||
let pos = monster.pos
|
let pos = monster.pos
|
||||||
XCTAssertEqual(pos?.x, 1)
|
#expect(pos?.x == 1)
|
||||||
XCTAssertEqual(pos?.y, 2)
|
#expect(pos?.y == 2)
|
||||||
XCTAssertEqual(pos?.z, 3)
|
#expect(pos?.z == 3)
|
||||||
XCTAssertEqual(pos?.test1, 3)
|
#expect(pos?.test1 == 3)
|
||||||
XCTAssertEqual(pos?.test2, .green)
|
#expect(pos?.test2 == .green)
|
||||||
let test = pos?.test3
|
let test = pos?.test3
|
||||||
XCTAssertEqual(test?.a, 5)
|
#expect(test?.a == 5)
|
||||||
XCTAssertEqual(test?.b, 6)
|
#expect(test?.b == 6)
|
||||||
let monster2 = monster.test?.value as? MyGame_Example_MonsterT
|
let monster2 = monster.test?.value as? MyGame_Example_MonsterT
|
||||||
XCTAssertEqual(monster2?.name, "Fred")
|
#expect(monster2?.name == "Fred")
|
||||||
XCTAssertEqual(monster.mana, 150)
|
#expect(monster.mana == 150)
|
||||||
monster.mana = 10
|
monster.mana = 10
|
||||||
XCTAssertEqual(monster.mana, 10)
|
#expect(monster.mana == 10)
|
||||||
monster.mana = 150
|
monster.mana = 150
|
||||||
XCTAssertEqual(monster.mana, 150)
|
#expect(monster.mana == 150)
|
||||||
|
|
||||||
XCTAssertEqual(monster.inventory.count, 5)
|
#expect(monster.inventory.count == 5)
|
||||||
var sum: Byte = 0
|
var sum: Byte = 0
|
||||||
for i in monster.inventory {
|
for i in monster.inventory {
|
||||||
sum += i
|
sum += i
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum, 10)
|
#expect(sum == 10)
|
||||||
XCTAssertEqual(monster.test4.count, 2)
|
#expect(monster.test4.count == 2)
|
||||||
var sum0 = 0
|
var sum0 = 0
|
||||||
for test in monster.test4 {
|
for test in monster.test4 {
|
||||||
sum0 += Int(test.a) + Int(test.b)
|
sum0 += Int(test.a) + Int(test.b)
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum0, 100)
|
#expect(sum0 == 100)
|
||||||
XCTAssertEqual(monster.testbool, true)
|
#expect(monster.testbool == true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEncoding() {
|
@Test
|
||||||
|
func testEncoding() throws {
|
||||||
let fbb = createMonster(withPrefix: false)
|
let fbb = createMonster(withPrefix: false)
|
||||||
var sizedBuffer = fbb.sizedBuffer
|
var sizedBuffer = fbb.sizedBuffer
|
||||||
do {
|
struct Test: Decodable {
|
||||||
struct Test: Decodable {
|
struct Pos: Decodable {
|
||||||
struct Pos: Decodable {
|
let x, y, z: Int
|
||||||
let x, y, z: Int
|
|
||||||
}
|
|
||||||
let hp: Int
|
|
||||||
let inventory: [UInt8]
|
|
||||||
let name: String
|
|
||||||
let pos: Pos
|
|
||||||
}
|
}
|
||||||
let reader: Monster = try getCheckedRoot(byteBuffer: &sizedBuffer)
|
let hp: Int
|
||||||
let encoder = JSONEncoder()
|
let inventory: [UInt8]
|
||||||
encoder.keyEncodingStrategy = .convertToSnakeCase
|
let name: String
|
||||||
let data = try encoder.encode(reader)
|
let pos: Pos
|
||||||
let decoder = JSONDecoder()
|
|
||||||
decoder.keyDecodingStrategy = .convertFromSnakeCase
|
|
||||||
let value = try decoder.decode(Test.self, from: data)
|
|
||||||
XCTAssertEqual(value.name, "MyMonster")
|
|
||||||
XCTAssertEqual(value.pos.x, 1)
|
|
||||||
XCTAssertEqual(value.pos.y, 2)
|
|
||||||
XCTAssertEqual(value.pos.z, 3)
|
|
||||||
} catch {
|
|
||||||
XCTFail(error.localizedDescription)
|
|
||||||
}
|
}
|
||||||
|
let reader: Monster = try getCheckedRoot(byteBuffer: &sizedBuffer)
|
||||||
|
let encoder = JSONEncoder()
|
||||||
|
encoder.keyEncodingStrategy = .convertToSnakeCase
|
||||||
|
let data = try encoder.encode(reader)
|
||||||
|
let decoder = JSONDecoder()
|
||||||
|
decoder.keyDecodingStrategy = .convertFromSnakeCase
|
||||||
|
let value = try decoder.decode(Test.self, from: data)
|
||||||
|
#expect(value.name == "MyMonster")
|
||||||
|
#expect(value.pos.x == 1)
|
||||||
|
#expect(value.pos.y == 2)
|
||||||
|
#expect(value.pos.z == 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonData: String {
|
var jsonData: String {
|
||||||
@@ -653,6 +668,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testContiguousBytes() {
|
func testContiguousBytes() {
|
||||||
let byteArray: [UInt8] = [3, 1, 4, 1, 5, 9]
|
let byteArray: [UInt8] = [3, 1, 4, 1, 5, 9]
|
||||||
var fbb = FlatBufferBuilder(initialSize: 1)
|
var fbb = FlatBufferBuilder(initialSize: 1)
|
||||||
@@ -670,7 +686,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
monster.withUnsafePointerToInventory { ptr, count in
|
monster.withUnsafePointerToInventory { ptr, count in
|
||||||
let array = Array(ptr)
|
let array = Array(ptr)
|
||||||
for (index, value) in values.enumerated() {
|
for (index, value) in values.enumerated() {
|
||||||
XCTAssertEqual(array[index], value)
|
#expect(array[index] == value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,59 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import XCTest
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
|
||||||
@testable import FlatBuffers
|
@testable import FlatBuffers
|
||||||
|
|
||||||
final class FlatBuffersNanInfTests: XCTestCase {
|
struct FlatBuffersNanInfTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
func testInfNanBinary() {
|
||||||
|
let fbb = createTestTable()
|
||||||
|
let data = fbb.sizedByteArray
|
||||||
|
|
||||||
|
var buffer = ByteBuffer(bytes: data)
|
||||||
|
let table: Swift_Tests_NanInfTable = getRoot(byteBuffer: &buffer)
|
||||||
|
#expect(table.defaultNan.isNaN)
|
||||||
|
#expect(table.defaultInf == .infinity)
|
||||||
|
#expect(table.defaultNinf == -.infinity)
|
||||||
|
#expect(table.valueNan.isNaN)
|
||||||
|
#expect(table.valueInf == .infinity)
|
||||||
|
#expect(table.valueNinf == -.infinity)
|
||||||
|
#expect(table.value == 100.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
func testInfNanJSON() throws {
|
||||||
|
let fbb = createTestTable()
|
||||||
|
var bb = fbb.sizedBuffer
|
||||||
|
struct Test: Decodable {
|
||||||
|
let valueInf: Double
|
||||||
|
let value: Int
|
||||||
|
let valueNan: Double
|
||||||
|
let valueNinf: Double
|
||||||
|
}
|
||||||
|
let reader: Swift_Tests_NanInfTable = try getCheckedRoot(byteBuffer: &bb)
|
||||||
|
let encoder = JSONEncoder()
|
||||||
|
encoder.keyEncodingStrategy = .convertToSnakeCase
|
||||||
|
encoder.nonConformingFloatEncodingStrategy =
|
||||||
|
.convertToString(
|
||||||
|
positiveInfinity: "inf",
|
||||||
|
negativeInfinity: "-inf",
|
||||||
|
nan: "nan")
|
||||||
|
let data = try encoder.encode(reader)
|
||||||
|
let decoder = JSONDecoder()
|
||||||
|
decoder.nonConformingFloatDecodingStrategy = .convertFromString(
|
||||||
|
positiveInfinity: "inf",
|
||||||
|
negativeInfinity: "-inf",
|
||||||
|
nan: "nan")
|
||||||
|
decoder.keyDecodingStrategy = .convertFromSnakeCase
|
||||||
|
let value = try decoder.decode(Test.self, from: data)
|
||||||
|
#expect(value.value == 100)
|
||||||
|
#expect(value.valueInf == .infinity)
|
||||||
|
#expect(value.valueNinf == -.infinity)
|
||||||
|
}
|
||||||
|
|
||||||
func createTestTable() -> FlatBufferBuilder {
|
func createTestTable() -> FlatBufferBuilder {
|
||||||
var fbb = FlatBufferBuilder()
|
var fbb = FlatBufferBuilder()
|
||||||
@@ -31,54 +79,4 @@ final class FlatBuffersNanInfTests: XCTestCase {
|
|||||||
fbb.finish(offset: msg)
|
fbb.finish(offset: msg)
|
||||||
return fbb
|
return fbb
|
||||||
}
|
}
|
||||||
|
|
||||||
func testInfNanBinary() {
|
|
||||||
let fbb = createTestTable()
|
|
||||||
let data = fbb.sizedByteArray
|
|
||||||
|
|
||||||
var buffer = ByteBuffer(bytes: data)
|
|
||||||
let table: Swift_Tests_NanInfTable = getRoot(byteBuffer: &buffer)
|
|
||||||
XCTAssert(table.defaultNan.isNaN)
|
|
||||||
XCTAssertEqual(table.defaultInf, .infinity)
|
|
||||||
XCTAssertEqual(table.defaultNinf, -.infinity)
|
|
||||||
XCTAssert(table.valueNan.isNaN)
|
|
||||||
XCTAssertEqual(table.valueInf, .infinity)
|
|
||||||
XCTAssertEqual(table.valueNinf, -.infinity)
|
|
||||||
XCTAssertEqual(table.value, 100.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testInfNanJSON() {
|
|
||||||
let fbb = createTestTable()
|
|
||||||
var bb = fbb.sizedBuffer
|
|
||||||
do {
|
|
||||||
struct Test: Decodable {
|
|
||||||
let valueInf: Double
|
|
||||||
let value: Int
|
|
||||||
let valueNan: Double
|
|
||||||
let valueNinf: Double
|
|
||||||
}
|
|
||||||
let reader: Swift_Tests_NanInfTable = try getCheckedRoot(byteBuffer: &bb)
|
|
||||||
let encoder = JSONEncoder()
|
|
||||||
encoder.keyEncodingStrategy = .convertToSnakeCase
|
|
||||||
encoder.nonConformingFloatEncodingStrategy =
|
|
||||||
.convertToString(
|
|
||||||
positiveInfinity: "inf",
|
|
||||||
negativeInfinity: "-inf",
|
|
||||||
nan: "nan")
|
|
||||||
let data = try encoder.encode(reader)
|
|
||||||
let decoder = JSONDecoder()
|
|
||||||
decoder.nonConformingFloatDecodingStrategy = .convertFromString(
|
|
||||||
positiveInfinity: "inf",
|
|
||||||
negativeInfinity: "-inf",
|
|
||||||
nan: "nan")
|
|
||||||
decoder.keyDecodingStrategy = .convertFromSnakeCase
|
|
||||||
let value = try decoder.decode(Test.self, from: data)
|
|
||||||
XCTAssertEqual(value.value, 100)
|
|
||||||
XCTAssertEqual(value.valueInf, .infinity)
|
|
||||||
XCTAssertEqual(value.valueNinf, -.infinity)
|
|
||||||
} catch {
|
|
||||||
XCTFail(error.localizedDescription)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import XCTest
|
import Testing
|
||||||
|
|
||||||
@testable import FlatBuffers
|
@testable import FlatBuffers
|
||||||
|
|
||||||
final class FlatBuffersStructsTests: XCTestCase {
|
struct FlatBuffersStructsTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
func testWritingAndMutatingBools() {
|
func testWritingAndMutatingBools() {
|
||||||
var fbb = FlatBufferBuilder()
|
var fbb = FlatBufferBuilder()
|
||||||
let start = TestMutatingBool.startTestMutatingBool(&fbb)
|
let start = TestMutatingBool.startTestMutatingBool(&fbb)
|
||||||
@@ -30,11 +31,11 @@ final class FlatBuffersStructsTests: XCTestCase {
|
|||||||
var buffer = fbb.sizedBuffer
|
var buffer = fbb.sizedBuffer
|
||||||
let testMutatingBool: TestMutatingBool = getRoot(byteBuffer: &buffer)
|
let testMutatingBool: TestMutatingBool = getRoot(byteBuffer: &buffer)
|
||||||
let property = testMutatingBool.mutableB
|
let property = testMutatingBool.mutableB
|
||||||
XCTAssertEqual(property?.property, false)
|
#expect(property?.property == false)
|
||||||
property?.mutate(property: false)
|
property?.mutate(property: false)
|
||||||
XCTAssertEqual(property?.property, false)
|
#expect(property?.property == false)
|
||||||
property?.mutate(property: true)
|
property?.mutate(property: true)
|
||||||
XCTAssertEqual(property?.property, true)
|
#expect(property?.property == true)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,44 +14,49 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import XCTest
|
import Testing
|
||||||
|
|
||||||
@testable import Common
|
@testable import Common
|
||||||
@testable import FlatBuffers
|
@testable import FlatBuffers
|
||||||
|
|
||||||
final class FlatBuffersTests: XCTestCase {
|
struct FlatBuffersTests {
|
||||||
|
|
||||||
let country = "Norway"
|
let country = "Norway"
|
||||||
|
|
||||||
func testEndian() { XCTAssertEqual(isLitteEndian, true) }
|
@Test
|
||||||
|
func testEndian() { #expect(isLitteEndian == true) }
|
||||||
|
|
||||||
|
@Test
|
||||||
func testOffset() {
|
func testOffset() {
|
||||||
let o = Offset()
|
let o = Offset()
|
||||||
let b = Offset(offset: 1)
|
let b = Offset(offset: 1)
|
||||||
XCTAssertEqual(o.isEmpty, true)
|
#expect(o.isEmpty == true)
|
||||||
XCTAssertEqual(b.isEmpty, false)
|
#expect(b.isEmpty == false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateString() {
|
func testCreateString() {
|
||||||
let helloWorld = "Hello, world!"
|
let helloWorld = "Hello, world!"
|
||||||
var b = FlatBufferBuilder(initialSize: 16)
|
var b = FlatBufferBuilder(initialSize: 16)
|
||||||
XCTAssertEqual(b.create(string: country).o, 12)
|
#expect(b.create(string: country).o == 12)
|
||||||
XCTAssertEqual(b.create(string: helloWorld).o, 32)
|
#expect(b.create(string: helloWorld).o == 32)
|
||||||
b.clear()
|
b.clear()
|
||||||
XCTAssertEqual(b.create(string: helloWorld).o, 20)
|
#expect(b.create(string: helloWorld).o == 20)
|
||||||
XCTAssertEqual(b.create(string: country).o, 32)
|
#expect(b.create(string: country).o == 32)
|
||||||
b.clear()
|
b.clear()
|
||||||
XCTAssertEqual(b.create(string: String(repeating: "a", count: 257)).o, 264)
|
#expect(b.create(string: String(repeating: "a", count: 257)).o == 264)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testStartTable() {
|
func testStartTable() {
|
||||||
var b = FlatBufferBuilder(initialSize: 16)
|
var b = FlatBufferBuilder(initialSize: 16)
|
||||||
XCTAssertNoThrow(b.startTable(with: 0))
|
_ = b.startTable(with: 0)
|
||||||
b.clear()
|
b.clear()
|
||||||
XCTAssertEqual(b.create(string: country).o, 12)
|
#expect(b.create(string: country).o == 12)
|
||||||
XCTAssertEqual(b.startTable(with: 0), 12)
|
#expect(b.startTable(with: 0) == 12)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateFinish() {
|
func testCreateFinish() {
|
||||||
var b = FlatBufferBuilder(initialSize: 16)
|
var b = FlatBufferBuilder(initialSize: 16)
|
||||||
let countryOff = Country.createCountry(
|
let countryOff = Country.createCountry(
|
||||||
@@ -66,9 +71,10 @@ final class FlatBuffersTests: XCTestCase {
|
|||||||
200, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0,
|
200, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0,
|
||||||
]
|
]
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
XCTAssertEqual(b.sizedByteArray, v)
|
#expect(b.sizedByteArray == v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateFinishWithPrefix() {
|
func testCreateFinishWithPrefix() {
|
||||||
var b = FlatBufferBuilder(initialSize: 16)
|
var b = FlatBufferBuilder(initialSize: 16)
|
||||||
let countryOff = Country.createCountry(
|
let countryOff = Country.createCountry(
|
||||||
@@ -83,9 +89,10 @@ final class FlatBuffersTests: XCTestCase {
|
|||||||
100, 0, 0, 0, 200, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0,
|
100, 0, 0, 0, 200, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0,
|
||||||
]
|
]
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
XCTAssertEqual(b.sizedByteArray, v)
|
#expect(b.sizedByteArray == v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadCountry() {
|
func testReadCountry() {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
let v: [UInt8] = [
|
let v: [UInt8] = [
|
||||||
@@ -95,18 +102,20 @@ final class FlatBuffersTests: XCTestCase {
|
|||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
let buffer = ByteBuffer(bytes: v)
|
let buffer = ByteBuffer(bytes: v)
|
||||||
let c = Country.getRootAsCountry(buffer)
|
let c = Country.getRootAsCountry(buffer)
|
||||||
XCTAssertEqual(c.lan, 100)
|
#expect(c.lan == 100)
|
||||||
XCTAssertEqual(c.log, 200)
|
#expect(c.log == 200)
|
||||||
XCTAssertEqual(c.nameVector, [78, 111, 114, 119, 97, 121])
|
#expect(c.nameVector == [78, 111, 114, 119, 97, 121])
|
||||||
XCTAssertEqual(c.name, country)
|
#expect(c.name == country)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testWriteNullableStrings() {
|
func testWriteNullableStrings() {
|
||||||
var b = FlatBufferBuilder()
|
var b = FlatBufferBuilder()
|
||||||
XCTAssertTrue(b.create(string: nil).isEmpty)
|
#expect(b.create(string: nil).isEmpty)
|
||||||
XCTAssertTrue(b.createShared(string: nil).isEmpty)
|
#expect(b.createShared(string: nil).isEmpty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testWriteOptionalValues() {
|
func testWriteOptionalValues() {
|
||||||
var b = FlatBufferBuilder()
|
var b = FlatBufferBuilder()
|
||||||
let root = optional_scalars_ScalarStuff.createScalarStuff(
|
let root = optional_scalars_ScalarStuff.createScalarStuff(
|
||||||
@@ -121,16 +130,17 @@ final class FlatBuffersTests: XCTestCase {
|
|||||||
b.finish(offset: root)
|
b.finish(offset: root)
|
||||||
var buffer = b.sizedBuffer
|
var buffer = b.sizedBuffer
|
||||||
let scalarTable: optional_scalars_ScalarStuff = getRoot(byteBuffer: &buffer)
|
let scalarTable: optional_scalars_ScalarStuff = getRoot(byteBuffer: &buffer)
|
||||||
XCTAssertEqual(scalarTable.justI8, 80)
|
#expect(scalarTable.justI8 == 80)
|
||||||
XCTAssertNil(scalarTable.maybeI8)
|
#expect(scalarTable.maybeI8 == nil)
|
||||||
XCTAssertEqual(scalarTable.maybeBool, true)
|
#expect(scalarTable.maybeBool == true)
|
||||||
XCTAssertEqual(scalarTable.defaultI8, 42)
|
#expect(scalarTable.defaultI8 == 42)
|
||||||
XCTAssertEqual(scalarTable.justU8, 100)
|
#expect(scalarTable.justU8 == 100)
|
||||||
XCTAssertEqual(scalarTable.maybeU8, 10)
|
#expect(scalarTable.maybeU8 == 10)
|
||||||
XCTAssertEqual(scalarTable.justEnum, .one)
|
#expect(scalarTable.justEnum == .one)
|
||||||
XCTAssertNil(scalarTable.maybeEnum)
|
#expect(scalarTable.maybeEnum == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testAlignmentCrash() {
|
func testAlignmentCrash() {
|
||||||
var builder = FlatBufferBuilder(initialSize: 256)
|
var builder = FlatBufferBuilder(initialSize: 256)
|
||||||
|
|
||||||
|
|||||||
@@ -14,12 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import XCTest
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
|
||||||
@testable import FlatBuffers
|
@testable import FlatBuffers
|
||||||
|
|
||||||
final class FlatBuffersUnionTests: XCTestCase {
|
struct FlatBuffersUnionTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMonstor() {
|
func testCreateMonstor() {
|
||||||
|
|
||||||
var b = FlatBufferBuilder(initialSize: 20)
|
var b = FlatBufferBuilder(initialSize: 20)
|
||||||
@@ -36,8 +38,8 @@ final class FlatBuffersUnionTests: XCTestCase {
|
|||||||
b.finish(offset: root)
|
b.finish(offset: root)
|
||||||
let buffer = b.sizedByteArray
|
let buffer = b.sizedByteArray
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
buffer,
|
buffer ==
|
||||||
[
|
[
|
||||||
16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 7, 0, 12, 0, 10, 0, 0, 0, 0, 0, 0, 1, 8, 0, 0, 0, 20,
|
16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 7, 0, 12, 0, 10, 0, 0, 0, 0, 0, 0, 1, 8, 0, 0, 0, 20,
|
||||||
0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 8, 0, 12, 0, 8, 0, 6, 0, 8, 0, 0, 0, 0, 0, 5, 0, 4, 0, 0,
|
0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 8, 0, 12, 0, 8, 0, 6, 0, 8, 0, 0, 0, 0, 0, 5, 0, 4, 0, 0,
|
||||||
@@ -45,15 +47,16 @@ final class FlatBuffersUnionTests: XCTestCase {
|
|||||||
])
|
])
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
let monster = LocalMonster.getRootAsMonster(bb: ByteBuffer(bytes: buffer))
|
let monster = LocalMonster.getRootAsMonster(bb: ByteBuffer(bytes: buffer))
|
||||||
XCTAssertEqual(monster.weapon(at: 0)?.dmg, dmg)
|
#expect(monster.weapon(at: 0)?.dmg == dmg)
|
||||||
XCTAssertEqual(monster.weapon(at: 0)?.name, str)
|
#expect(monster.weapon(at: 0)?.name == str)
|
||||||
XCTAssertEqual(monster.weapon(at: 0)?.nameVector, [65, 120, 101])
|
#expect(monster.weapon(at: 0)?.nameVector == [65, 120, 101])
|
||||||
let p: Weapon? = monster.equiped()
|
let p: Weapon? = monster.equiped()
|
||||||
XCTAssertEqual(p?.dmg, dmg)
|
#expect(p?.dmg == dmg)
|
||||||
XCTAssertEqual(p?.name, str)
|
#expect(p?.name == str)
|
||||||
XCTAssertEqual(p?.nameVector, [65, 120, 101])
|
#expect(p?.nameVector == [65, 120, 101])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testEndTableFinish() {
|
func testEndTableFinish() {
|
||||||
var builder = FlatBufferBuilder(initialSize: 20)
|
var builder = FlatBufferBuilder(initialSize: 20)
|
||||||
let sword = builder.create(string: "Sword")
|
let sword = builder.create(string: "Sword")
|
||||||
@@ -84,8 +87,8 @@ final class FlatBuffersUnionTests: XCTestCase {
|
|||||||
path: path)
|
path: path)
|
||||||
builder.finish(offset: orc)
|
builder.finish(offset: orc)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
builder.sizedByteArray,
|
builder.sizedByteArray ==
|
||||||
[
|
[
|
||||||
32, 0, 0, 0, 0, 0, 26, 0, 48, 0, 36, 0, 0, 0, 34, 0, 28, 0, 0, 0, 24, 0, 23, 0, 16, 0, 15,
|
32, 0, 0, 0, 0, 0, 26, 0, 48, 0, 36, 0, 0, 0, 34, 0, 28, 0, 0, 0, 24, 0, 23, 0, 16, 0, 15,
|
||||||
0, 8, 0, 4, 0, 26, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 0, 0, 0, 0,
|
0, 8, 0, 4, 0, 26, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 0, 0, 0, 0,
|
||||||
@@ -99,6 +102,7 @@ final class FlatBuffersUnionTests: XCTestCase {
|
|||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testEnumVector() {
|
func testEnumVector() {
|
||||||
let vectorOfEnums: [ColorsNameSpace.RGB] = [.blue, .green]
|
let vectorOfEnums: [ColorsNameSpace.RGB] = [.blue, .green]
|
||||||
|
|
||||||
@@ -109,8 +113,8 @@ final class FlatBuffersUnionTests: XCTestCase {
|
|||||||
let end = ColorsNameSpace.Monster.endMonster(&builder, start: start)
|
let end = ColorsNameSpace.Monster.endMonster(&builder, start: start)
|
||||||
builder.finish(offset: end)
|
builder.finish(offset: end)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
builder.sizedByteArray,
|
builder.sizedByteArray ==
|
||||||
[
|
[
|
||||||
12, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0,
|
12, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0,
|
||||||
0, 0,
|
0, 0,
|
||||||
@@ -118,12 +122,13 @@ final class FlatBuffersUnionTests: XCTestCase {
|
|||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
let monster = ColorsNameSpace.Monster
|
let monster = ColorsNameSpace.Monster
|
||||||
.getRootAsMonster(bb: builder.sizedBuffer)
|
.getRootAsMonster(bb: builder.sizedBuffer)
|
||||||
XCTAssertEqual(monster.colorsCount, 2)
|
#expect(monster.colorsCount == 2)
|
||||||
let colors = monster.colors
|
let colors = monster.colors
|
||||||
XCTAssertEqual(colors[0], .blue)
|
#expect(colors[0] == .blue)
|
||||||
XCTAssertEqual(colors[1], .green)
|
#expect(colors[1] == .green)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testUnionVector() {
|
func testUnionVector() {
|
||||||
var fb = FlatBufferBuilder()
|
var fb = FlatBufferBuilder()
|
||||||
|
|
||||||
@@ -149,30 +154,30 @@ final class FlatBuffersUnionTests: XCTestCase {
|
|||||||
|
|
||||||
var buffer = fb.sizedBuffer
|
var buffer = fb.sizedBuffer
|
||||||
let movie: Movie = getRoot(byteBuffer: &buffer)
|
let movie: Movie = getRoot(byteBuffer: &buffer)
|
||||||
XCTAssertEqual(movie.charactersType.count, characterType.count)
|
#expect(movie.charactersType.count == characterType.count)
|
||||||
XCTAssertEqual(movie.characters.count, characters.count)
|
#expect(movie.characters.count == characters.count)
|
||||||
|
|
||||||
let bufferCharactersType = movie.charactersType
|
let bufferCharactersType = movie.charactersType
|
||||||
for (index, element) in bufferCharactersType.enumerated() {
|
for (index, element) in bufferCharactersType.enumerated() {
|
||||||
XCTAssertEqual(element, characterType[index])
|
#expect(element == characterType[index])
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead,
|
movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead ==
|
||||||
7)
|
7)
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage,
|
movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage ==
|
||||||
swordDmg)
|
swordDmg)
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
movie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead,
|
movie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead ==
|
||||||
2)
|
2)
|
||||||
|
|
||||||
var objc: MovieT? = movie.unpack()
|
var objc: MovieT? = movie.unpack()
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
movie.charactersType.count, objc?.characters.count ?? 0)
|
movie.charactersType.count == objc?.characters.count ?? 0)
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead,
|
movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead ==
|
||||||
(objc?.characters[0]?.value as? BookReader)?.booksRead)
|
(objc?.characters[0]?.value as? BookReader)?.booksRead)
|
||||||
fb.clear()
|
fb.clear()
|
||||||
let newMovie = Movie.pack(&fb, obj: &objc)
|
let newMovie = Movie.pack(&fb, obj: &objc)
|
||||||
fb.finish(offset: newMovie)
|
fb.finish(offset: newMovie)
|
||||||
@@ -180,17 +185,18 @@ final class FlatBuffersUnionTests: XCTestCase {
|
|||||||
var _buffer = fb.sizedBuffer
|
var _buffer = fb.sizedBuffer
|
||||||
let packedMovie: Movie = getRoot(byteBuffer: &_buffer)
|
let packedMovie: Movie = getRoot(byteBuffer: &_buffer)
|
||||||
|
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
packedMovie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead,
|
packedMovie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead ==
|
||||||
movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead)
|
movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead)
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
packedMovie.characters(at: 1, type: Attacker.self)?.swordAttackDamage,
|
packedMovie.characters(at: 1, type: Attacker.self)?.swordAttackDamage ==
|
||||||
movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage)
|
movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage)
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
packedMovie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead,
|
packedMovie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead ==
|
||||||
movie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead)
|
movie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testStringUnion() {
|
func testStringUnion() {
|
||||||
let string = "Awesome \\\\t\t\nstring!"
|
let string = "Awesome \\\\t\t\nstring!"
|
||||||
var fb = FlatBufferBuilder()
|
var fb = FlatBufferBuilder()
|
||||||
@@ -214,30 +220,31 @@ final class FlatBuffersUnionTests: XCTestCase {
|
|||||||
|
|
||||||
var buffer = fb.sizedBuffer
|
var buffer = fb.sizedBuffer
|
||||||
let movie: Movie = getRoot(byteBuffer: &buffer)
|
let movie: Movie = getRoot(byteBuffer: &buffer)
|
||||||
XCTAssertEqual(movie.mainCharacter(type: String.self), string)
|
#expect(movie.mainCharacter(type: String.self) == string)
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead,
|
movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead ==
|
||||||
7)
|
7)
|
||||||
XCTAssertEqual(movie.characters(at: 1, type: String.self), string)
|
#expect(movie.characters(at: 1, type: String.self) == string)
|
||||||
|
|
||||||
var objc: MovieT? = movie.unpack()
|
var objc: MovieT? = movie.unpack()
|
||||||
XCTAssertEqual(objc?.mainCharacter?.value as? String, string)
|
#expect(objc?.mainCharacter?.value as? String == string)
|
||||||
XCTAssertEqual((objc?.characters[0]?.value as? BookReader)?.booksRead, 7)
|
#expect((objc?.characters[0]?.value as? BookReader)?.booksRead == 7)
|
||||||
XCTAssertEqual(objc?.characters[1]?.value as? String, string)
|
#expect(objc?.characters[1]?.value as? String == string)
|
||||||
fb.clear()
|
fb.clear()
|
||||||
let newMovie = Movie.pack(&fb, obj: &objc)
|
let newMovie = Movie.pack(&fb, obj: &objc)
|
||||||
fb.finish(offset: newMovie)
|
fb.finish(offset: newMovie)
|
||||||
|
|
||||||
var _buffer = fb.sizedBuffer
|
var _buffer = fb.sizedBuffer
|
||||||
let packedMovie: Movie = getRoot(byteBuffer: &_buffer)
|
let packedMovie: Movie = getRoot(byteBuffer: &_buffer)
|
||||||
XCTAssertEqual(packedMovie.mainCharacter(type: String.self), string)
|
#expect(packedMovie.mainCharacter(type: String.self) == string)
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
packedMovie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead,
|
packedMovie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead ==
|
||||||
7)
|
7)
|
||||||
XCTAssertEqual(packedMovie.characters(at: 1, type: String.self), string)
|
#expect(packedMovie.characters(at: 1, type: String.self) == string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEncoding() {
|
@Test
|
||||||
|
func testEncoding() throws {
|
||||||
let string = "Awesome \\\\t\t\nstring!"
|
let string = "Awesome \\\\t\t\nstring!"
|
||||||
var fb = FlatBufferBuilder()
|
var fb = FlatBufferBuilder()
|
||||||
|
|
||||||
@@ -265,16 +272,12 @@ final class FlatBuffersUnionTests: XCTestCase {
|
|||||||
Movie.finish(&fb, end: end)
|
Movie.finish(&fb, end: end)
|
||||||
|
|
||||||
var sizedBuffer = fb.sizedBuffer
|
var sizedBuffer = fb.sizedBuffer
|
||||||
do {
|
let reader: Movie = try getCheckedRoot(byteBuffer: &sizedBuffer)
|
||||||
let reader: Movie = try getCheckedRoot(byteBuffer: &sizedBuffer)
|
let encoder = JSONEncoder()
|
||||||
let encoder = JSONEncoder()
|
encoder.keyEncodingStrategy = .convertToSnakeCase
|
||||||
encoder.keyEncodingStrategy = .convertToSnakeCase
|
encoder.outputFormatting = [.sortedKeys]
|
||||||
encoder.outputFormatting = [.sortedKeys]
|
let data = try encoder.encode(reader)
|
||||||
let data = try encoder.encode(reader)
|
#expect(String(data: data, encoding: .utf8) == jsonData)
|
||||||
XCTAssertEqual(String(data: data, encoding: .utf8), jsonData)
|
|
||||||
} catch {
|
|
||||||
XCTFail(error.localizedDescription)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonData: String {
|
var jsonData: String {
|
||||||
|
|||||||
@@ -14,12 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import XCTest
|
import Testing
|
||||||
|
|
||||||
@testable import FlatBuffers
|
@testable import FlatBuffers
|
||||||
|
|
||||||
final class FlatBuffersVectors: XCTestCase {
|
struct FlatBuffersVectors {
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreatingTwoCountries() {
|
func testCreatingTwoCountries() {
|
||||||
let norway = "Norway"
|
let norway = "Norway"
|
||||||
let denmark = "Denmark"
|
let denmark = "Denmark"
|
||||||
@@ -40,8 +41,8 @@ final class FlatBuffersVectors: XCTestCase {
|
|||||||
let vectorOffset = b.createVector(ofOffsets: vector)
|
let vectorOffset = b.createVector(ofOffsets: vector)
|
||||||
b.finish(offset: vectorOffset)
|
b.finish(offset: vectorOffset)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
b.sizedByteArray,
|
b.sizedByteArray ==
|
||||||
[
|
[
|
||||||
4, 0, 0, 0, 2, 0, 0, 0, 48, 0, 0, 0, 16, 0, 0, 0, 0, 0, 10, 0, 18, 0, 4, 0, 8, 0, 12, 0, 10,
|
4, 0, 0, 0, 2, 0, 0, 0, 48, 0, 0, 0, 16, 0, 0, 0, 0, 0, 10, 0, 18, 0, 4, 0, 8, 0, 12, 0, 10,
|
||||||
0, 0, 0, 40, 0, 0, 0, 100, 0, 0, 0, 200, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 8, 0, 12, 0, 10,
|
0, 0, 0, 40, 0, 0, 0, 100, 0, 0, 0, 200, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 8, 0, 12, 0, 10,
|
||||||
@@ -51,18 +52,20 @@ final class FlatBuffersVectors: XCTestCase {
|
|||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateIntArray() {
|
func testCreateIntArray() {
|
||||||
let numbers: [Int32] = [1, 2, 3, 4, 5]
|
let numbers: [Int32] = [1, 2, 3, 4, 5]
|
||||||
var b = FlatBufferBuilder(initialSize: 20)
|
var b = FlatBufferBuilder(initialSize: 20)
|
||||||
let o = b.createVector(numbers, size: numbers.count)
|
let o = b.createVector(numbers, size: numbers.count)
|
||||||
b.finish(offset: o)
|
b.finish(offset: o)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
b.sizedByteArray,
|
b.sizedByteArray ==
|
||||||
[4, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0])
|
[4, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0])
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateStructArray() {
|
func testCreateStructArray() {
|
||||||
struct Vec: NativeStruct {
|
struct Vec: NativeStruct {
|
||||||
let x, y, z: Float32
|
let x, y, z: Float32
|
||||||
@@ -76,8 +79,8 @@ final class FlatBuffersVectors: XCTestCase {
|
|||||||
let o = b.createVector(ofStructs: vector)
|
let o = b.createVector(ofStructs: vector)
|
||||||
b.finish(offset: o)
|
b.finish(offset: o)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
b.sizedByteArray,
|
b.sizedByteArray ==
|
||||||
[
|
[
|
||||||
4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 128, 64, 0, 0, 160,
|
4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 128, 64, 0, 0, 160,
|
||||||
64, 0, 0, 192, 64, 0, 0, 224, 64, 0, 0, 0, 65, 0, 0, 16, 65,
|
64, 0, 0, 192, 64, 0, 0, 224, 64, 0, 0, 0, 65, 0, 0, 16, 65,
|
||||||
@@ -85,28 +88,31 @@ final class FlatBuffersVectors: XCTestCase {
|
|||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateEmptyIntArray() {
|
func testCreateEmptyIntArray() {
|
||||||
let numbers: [Int32] = []
|
let numbers: [Int32] = []
|
||||||
var b = FlatBufferBuilder(initialSize: 20)
|
var b = FlatBufferBuilder(initialSize: 20)
|
||||||
let o = b.createVector(numbers, size: numbers.count)
|
let o = b.createVector(numbers, size: numbers.count)
|
||||||
b.finish(offset: o)
|
b.finish(offset: o)
|
||||||
XCTAssertEqual(b.sizedByteArray, [4, 0, 0, 0, 0, 0, 0, 0])
|
#expect(b.sizedByteArray == [4, 0, 0, 0, 0, 0, 0, 0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateVectorOfStrings() {
|
func testCreateVectorOfStrings() {
|
||||||
let strs = ["Denmark", "Norway"]
|
let strs = ["Denmark", "Norway"]
|
||||||
var b = FlatBufferBuilder(initialSize: 20)
|
var b = FlatBufferBuilder(initialSize: 20)
|
||||||
let o = b.createVector(ofStrings: strs)
|
let o = b.createVector(ofStrings: strs)
|
||||||
b.finish(offset: o)
|
b.finish(offset: o)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
b.sizedByteArray,
|
b.sizedByteArray ==
|
||||||
[
|
[
|
||||||
4, 0, 0, 0, 2, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0,
|
4, 0, 0, 0, 2, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0,
|
||||||
0, 7, 0, 0, 0, 68, 101, 110, 109, 97, 114, 107, 0,
|
0, 7, 0, 0, 0, 68, 101, 110, 109, 97, 114, 107, 0,
|
||||||
])
|
])
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
func testCreateSharedStringVector() {
|
func testCreateSharedStringVector() {
|
||||||
let norway = "Norway"
|
let norway = "Norway"
|
||||||
let denmark = "Denmark"
|
let denmark = "Denmark"
|
||||||
@@ -119,8 +125,8 @@ final class FlatBuffersVectors: XCTestCase {
|
|||||||
let end = b.createVector(ofOffsets: v)
|
let end = b.createVector(ofOffsets: v)
|
||||||
b.finish(offset: end)
|
b.finish(offset: end)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
b.sizedByteArray,
|
b.sizedByteArray ==
|
||||||
[
|
[
|
||||||
4, 0, 0, 0, 4, 0, 0, 0, 28, 0, 0, 0, 12, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 68,
|
4, 0, 0, 0, 4, 0, 0, 0, 28, 0, 0, 0, 12, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 68,
|
||||||
101, 110, 109, 97, 114, 107, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0,
|
101, 110, 109, 97, 114, 107, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0,
|
||||||
@@ -128,6 +134,7 @@ final class FlatBuffersVectors: XCTestCase {
|
|||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadInt32Array() {
|
func testReadInt32Array() {
|
||||||
let data: [Int32] = [1, 2, 3, 4, 5]
|
let data: [Int32] = [1, 2, 3, 4, 5]
|
||||||
var b = FlatBufferBuilder(initialSize: 20)
|
var b = FlatBufferBuilder(initialSize: 20)
|
||||||
@@ -136,10 +143,11 @@ final class FlatBuffersVectors: XCTestCase {
|
|||||||
b.finish(offset: end)
|
b.finish(offset: end)
|
||||||
let number = Numbers.getRootAsNumbers(ByteBuffer(bytes: b.sizedByteArray))
|
let number = Numbers.getRootAsNumbers(ByteBuffer(bytes: b.sizedByteArray))
|
||||||
for (index, num) in number.vArrayInt32.enumerated() {
|
for (index, num) in number.vArrayInt32.enumerated() {
|
||||||
XCTAssertEqual(num, data[index])
|
#expect(num == data[index])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadDoubleArray() {
|
func testReadDoubleArray() {
|
||||||
let data: [Double] = [1, 2, 3, 4, 5]
|
let data: [Double] = [1, 2, 3, 4, 5]
|
||||||
var b = FlatBufferBuilder(initialSize: 20)
|
var b = FlatBufferBuilder(initialSize: 20)
|
||||||
@@ -148,10 +156,11 @@ final class FlatBuffersVectors: XCTestCase {
|
|||||||
b.finish(offset: end)
|
b.finish(offset: end)
|
||||||
let number = Numbers.getRootAsNumbers(ByteBuffer(bytes: b.sizedByteArray))
|
let number = Numbers.getRootAsNumbers(ByteBuffer(bytes: b.sizedByteArray))
|
||||||
for (index, num) in number.vArrayDouble.enumerated() {
|
for (index, num) in number.vArrayDouble.enumerated() {
|
||||||
XCTAssertEqual(num, data[index])
|
#expect(num == data[index])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testHasForArray() {
|
func testHasForArray() {
|
||||||
var builder = FlatBufferBuilder(initialSize: 20)
|
var builder = FlatBufferBuilder(initialSize: 20)
|
||||||
let emptyVector = [UInt8]()
|
let emptyVector = [UInt8]()
|
||||||
@@ -166,14 +175,14 @@ final class FlatBuffersVectors: XCTestCase {
|
|||||||
|
|
||||||
var byteBuffer = ByteBuffer(bytes: builder.sizedByteArray)
|
var byteBuffer = ByteBuffer(bytes: builder.sizedByteArray)
|
||||||
let msg: Swift_Tests_Vectors = getRoot(byteBuffer: &byteBuffer)
|
let msg: Swift_Tests_Vectors = getRoot(byteBuffer: &byteBuffer)
|
||||||
XCTAssertEqual(msg.none_.isEmpty, true)
|
#expect(msg.none_.isEmpty == true)
|
||||||
XCTAssertEqual(msg.empty.isEmpty, true)
|
#expect(msg.empty.isEmpty == true)
|
||||||
XCTAssertEqual(msg.empty.count, 0)
|
#expect(msg.empty.count == 0)
|
||||||
XCTAssertEqual(msg.array.isEmpty, false)
|
#expect(msg.array.isEmpty == false)
|
||||||
XCTAssertEqual(msg.array.count, 3)
|
#expect(msg.array.count == 3)
|
||||||
|
|
||||||
for i in msg.array.startIndex..<msg.array.endIndex {
|
for i in msg.array.startIndex..<msg.array.endIndex {
|
||||||
XCTAssertEqual(msg.array[i], 1 + UInt64(i))
|
#expect(msg.array[i] == 1 + UInt64(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
let array = msg.withUnsafePointerToArray { ptr, count in
|
let array = msg.withUnsafePointerToArray { ptr, count in
|
||||||
@@ -185,7 +194,7 @@ final class FlatBuffersVectors: XCTestCase {
|
|||||||
return Array(ptr)
|
return Array(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(array, [1, 2, 3])
|
#expect(array == [1, 2, 3])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,14 +14,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import XCTest
|
import Testing
|
||||||
|
|
||||||
@testable import FlatBuffers
|
@testable import FlatBuffers
|
||||||
|
|
||||||
final class FlatBuffersDoubleTests: XCTestCase {
|
struct FlatBuffersDoubleTests {
|
||||||
|
|
||||||
let country = "Norway"
|
let country = "Norway"
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateFinish() {
|
func testCreateFinish() {
|
||||||
var b = FlatBufferBuilder(initialSize: 16)
|
var b = FlatBufferBuilder(initialSize: 16)
|
||||||
let countryOff = CountryDouble.createCountry(
|
let countryOff = CountryDouble.createCountry(
|
||||||
@@ -38,9 +39,10 @@ final class FlatBuffersDoubleTests: XCTestCase {
|
|||||||
97, 121, 0, 0,
|
97, 121, 0, 0,
|
||||||
]
|
]
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
XCTAssertEqual(b.sizedByteArray, v)
|
#expect(b.sizedByteArray == v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateFinishWithPrefix() {
|
func testCreateFinishWithPrefix() {
|
||||||
var b = FlatBufferBuilder(initialSize: 16)
|
var b = FlatBufferBuilder(initialSize: 16)
|
||||||
let countryOff = CountryDouble.createCountry(
|
let countryOff = CountryDouble.createCountry(
|
||||||
@@ -57,7 +59,7 @@ final class FlatBuffersDoubleTests: XCTestCase {
|
|||||||
0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0,
|
0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0,
|
||||||
]
|
]
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
XCTAssertEqual(b.sizedByteArray, v)
|
#expect(b.sizedByteArray == v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,11 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import XCTest
|
import Testing
|
||||||
|
|
||||||
@testable import FlatBuffers
|
@testable import FlatBuffers
|
||||||
|
|
||||||
class FlatBuffersMoreDefaults: XCTestCase {
|
struct FlatBuffersMoreDefaults {
|
||||||
|
|
||||||
func testFlatbuffersObject() {
|
func testFlatbuffersObject() {
|
||||||
var fbb = FlatBufferBuilder()
|
var fbb = FlatBufferBuilder()
|
||||||
@@ -27,61 +27,58 @@ class FlatBuffersMoreDefaults: XCTestCase {
|
|||||||
fbb.finish(offset: root)
|
fbb.finish(offset: root)
|
||||||
var byteBuffer = fbb.sizedBuffer
|
var byteBuffer = fbb.sizedBuffer
|
||||||
let defaults: MoreDefaults = getRoot(byteBuffer: &byteBuffer)
|
let defaults: MoreDefaults = getRoot(byteBuffer: &byteBuffer)
|
||||||
XCTAssertEqual(defaults.emptyString, "")
|
#expect(defaults.emptyString == "")
|
||||||
XCTAssertEqual(defaults.someString, "some")
|
#expect(defaults.someString == "some")
|
||||||
XCTAssertEqual(defaults.ints.isEmpty, true)
|
#expect(defaults.ints.isEmpty == true)
|
||||||
XCTAssertEqual(defaults.floats.isEmpty, true)
|
#expect(defaults.floats.isEmpty == true)
|
||||||
XCTAssertEqual(defaults.bools.isEmpty, true)
|
#expect(defaults.bools.isEmpty == true)
|
||||||
XCTAssertEqual(defaults.ints.count, 0)
|
#expect(defaults.ints.count == 0)
|
||||||
XCTAssertEqual(defaults.floats.count, 0)
|
#expect(defaults.floats.count == 0)
|
||||||
XCTAssertEqual(defaults.abcs.count, 0)
|
#expect(defaults.abcs.count == 0)
|
||||||
XCTAssertEqual(defaults.bools.count, 0)
|
#expect(defaults.bools.count == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testFlatbuffersObjectAPI() {
|
func testFlatbuffersObjectAPI() {
|
||||||
var fbb = FlatBufferBuilder()
|
var fbb = FlatBufferBuilder()
|
||||||
let defaults = MoreDefaultsT()
|
let defaults = MoreDefaultsT()
|
||||||
XCTAssertEqual(defaults.emptyString, "")
|
#expect(defaults.emptyString == "")
|
||||||
XCTAssertEqual(defaults.someString, "some")
|
#expect(defaults.someString == "some")
|
||||||
XCTAssertEqual(defaults.ints, [])
|
#expect(defaults.ints == [])
|
||||||
XCTAssertEqual(defaults.floats, [])
|
#expect(defaults.floats == [])
|
||||||
XCTAssertEqual(defaults.abcs, [])
|
#expect(defaults.abcs == [])
|
||||||
XCTAssertEqual(defaults.bools, [])
|
#expect(defaults.bools == [])
|
||||||
|
|
||||||
var buffer = defaults.serialize(builder: &fbb, type: MoreDefaults.self)
|
var buffer = defaults.serialize(builder: &fbb, type: MoreDefaults.self)
|
||||||
let fDefaults: MoreDefaults = getRoot(byteBuffer: &buffer)
|
let fDefaults: MoreDefaults = getRoot(byteBuffer: &buffer)
|
||||||
XCTAssertEqual(fDefaults.emptyString, "")
|
#expect(fDefaults.emptyString == "")
|
||||||
XCTAssertEqual(fDefaults.someString, "some")
|
#expect(fDefaults.someString == "some")
|
||||||
XCTAssertEqual(fDefaults.ints.isEmpty, true)
|
#expect(fDefaults.ints.isEmpty == true)
|
||||||
XCTAssertEqual(fDefaults.floats.isEmpty, true)
|
#expect(fDefaults.floats.isEmpty == true)
|
||||||
XCTAssertEqual(fDefaults.ints.count, 0)
|
#expect(fDefaults.ints.count == 0)
|
||||||
XCTAssertEqual(fDefaults.floats.count, 0)
|
#expect(fDefaults.floats.count == 0)
|
||||||
XCTAssertEqual(fDefaults.abcs.count, 0)
|
#expect(fDefaults.abcs.count == 0)
|
||||||
XCTAssertEqual(fDefaults.bools.count, 0)
|
#expect(fDefaults.bools.count == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEncoding() {
|
@Test
|
||||||
|
func testEncoding() throws {
|
||||||
var fbb = FlatBufferBuilder()
|
var fbb = FlatBufferBuilder()
|
||||||
let root = MoreDefaults.createMoreDefaults(&fbb)
|
let root = MoreDefaults.createMoreDefaults(&fbb)
|
||||||
fbb.finish(offset: root)
|
fbb.finish(offset: root)
|
||||||
var sizedBuffer = fbb.sizedBuffer
|
var sizedBuffer = fbb.sizedBuffer
|
||||||
do {
|
struct Test: Decodable {
|
||||||
struct Test: Decodable {
|
var emptyString: String
|
||||||
var emptyString: String
|
var someString: String
|
||||||
var someString: String
|
|
||||||
}
|
|
||||||
let reader: MoreDefaults = try getCheckedRoot(byteBuffer: &sizedBuffer)
|
|
||||||
let encoder = JSONEncoder()
|
|
||||||
encoder.keyEncodingStrategy = .convertToSnakeCase
|
|
||||||
let data = try encoder.encode(reader)
|
|
||||||
let decoder = JSONDecoder()
|
|
||||||
decoder.keyDecodingStrategy = .convertFromSnakeCase
|
|
||||||
let value = try decoder.decode(Test.self, from: data)
|
|
||||||
XCTAssertEqual(value.someString, "some")
|
|
||||||
XCTAssertEqual(value.emptyString, "")
|
|
||||||
} catch {
|
|
||||||
XCTFail(error.localizedDescription)
|
|
||||||
}
|
}
|
||||||
|
let reader: MoreDefaults = try getCheckedRoot(byteBuffer: &sizedBuffer)
|
||||||
|
let encoder = JSONEncoder()
|
||||||
|
encoder.keyEncodingStrategy = .convertToSnakeCase
|
||||||
|
let data = try encoder.encode(reader)
|
||||||
|
let decoder = JSONDecoder()
|
||||||
|
decoder.keyDecodingStrategy = .convertFromSnakeCase
|
||||||
|
let value = try decoder.decode(Test.self, from: data)
|
||||||
|
#expect(value.someString == "some")
|
||||||
|
#expect(value.emptyString == "")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,25 +14,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import XCTest
|
import Testing
|
||||||
|
|
||||||
@testable import FlatBuffers
|
@testable import FlatBuffers
|
||||||
|
|
||||||
final class FlatbuffersVerifierTests: XCTestCase {
|
final class FlatbuffersVerifierTests {
|
||||||
|
|
||||||
var buffer: ByteBuffer!
|
private var buffer: ByteBuffer
|
||||||
var validFlatbuffersObject: ByteBuffer!
|
private var validFlatbuffersObject: ByteBuffer
|
||||||
var invalidFlatbuffersObject: ByteBuffer!
|
private var invalidFlatbuffersObject: ByteBuffer
|
||||||
var invalidFlatbuffersObject2: ByteBuffer!
|
private var invalidFlatbuffersObject2: ByteBuffer
|
||||||
var invalidFlatbuffersObject3: ByteBuffer!
|
private var invalidFlatbuffersObject3: ByteBuffer
|
||||||
|
|
||||||
override func setUp() {
|
init() {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
let memory = UnsafeMutableRawPointer.allocate(byteCount: 32, alignment: 1)
|
|
||||||
buffer = ByteBuffer(assumingMemoryBound: memory, capacity: 32)
|
|
||||||
add(buffer: &buffer, v: 4, p: 16)
|
|
||||||
add(buffer: &buffer, v: 4, p: 20)
|
|
||||||
|
|
||||||
validFlatbuffersObject = ByteBuffer(bytes: [
|
validFlatbuffersObject = ByteBuffer(bytes: [
|
||||||
48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 0,
|
48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 0,
|
||||||
0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0, 0, 0,
|
0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0, 0, 0,
|
||||||
@@ -94,186 +89,250 @@ final class FlatbuffersVerifierTests: XCTestCase {
|
|||||||
109, 97, 0, 0, 0, 6, 0, 0, 0, 66, 97, 114, 110, 101, 121, 0, 0, 5, 0, 0, 0, 70, 114, 111, 100,
|
109, 97, 0, 0, 0, 6, 0, 0, 0, 66, 97, 114, 110, 101, 121, 0, 0, 5, 0, 0, 0, 70, 114, 111, 100,
|
||||||
0x00, 111, 0, 0, 0,
|
0x00, 111, 0, 0, 0,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
let memory = UnsafeMutableRawPointer.allocate(byteCount: 32, alignment: 1)
|
||||||
|
buffer = ByteBuffer(assumingMemoryBound: memory, capacity: 32)
|
||||||
|
|
||||||
|
add(buffer: &buffer, v: 4, p: 16)
|
||||||
|
add(buffer: &buffer, v: 4, p: 20)
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
|
|
||||||
func testVeriferInitPassing() {
|
@Test
|
||||||
|
func testVeriferInitPassing() throws {
|
||||||
let memory = UnsafeMutableRawPointer.allocate(byteCount: 8, alignment: 1)
|
let memory = UnsafeMutableRawPointer.allocate(byteCount: 8, alignment: 1)
|
||||||
var buffer = ByteBuffer(
|
var buffer = ByteBuffer(
|
||||||
assumingMemoryBound: memory,
|
assumingMemoryBound: memory,
|
||||||
capacity: Int(FlatBufferMaxSize) - 1)
|
capacity: Int(FlatBufferMaxSize) - 1)
|
||||||
XCTAssertNoThrow(try Verifier(buffer: &buffer))
|
_ = try Verifier(buffer: &buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testVeriferInitFailing() {
|
func testVeriferInitFailing() {
|
||||||
let memory = UnsafeMutableRawPointer.allocate(byteCount: 8, alignment: 1)
|
let memory = UnsafeMutableRawPointer.allocate(byteCount: 8, alignment: 1)
|
||||||
var buffer = ByteBuffer(
|
var buffer = ByteBuffer(
|
||||||
assumingMemoryBound: memory,
|
assumingMemoryBound: memory,
|
||||||
capacity: Int(FlatBufferMaxSize) + 1)
|
capacity: Int(FlatBufferMaxSize) + 1)
|
||||||
XCTAssertThrowsError(try Verifier(buffer: &buffer))
|
#expect(throws: FlatbuffersErrors.exceedsMaxSizeAllowed) {
|
||||||
|
try Verifier(buffer: &buffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testFailingID() {
|
func testFailingID() {
|
||||||
let dutData: [UInt8] = [1, 2, 3, 4, 5, 6, 7]
|
let dutData: [UInt8] = [1, 2, 3, 4, 5, 6, 7]
|
||||||
var buff = ByteBuffer(bytes: dutData)
|
var buff = ByteBuffer(bytes: dutData)
|
||||||
do {
|
#expect(throws: FlatbuffersErrors.bufferDoesntContainID) {
|
||||||
let _: Monster = try getCheckedRoot(byteBuffer: &buff, fileId: "ABCD")
|
let _: Monster = try getCheckedRoot(byteBuffer: &buff, fileId: "ABCD")
|
||||||
XCTFail("This should always fail")
|
|
||||||
} catch {
|
|
||||||
XCTAssertEqual(error as? FlatbuffersErrors, .bufferDoesntContainID)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testVerifierCheckAlignment() {
|
@Test
|
||||||
|
func testVerifierCheckAlignment() throws {
|
||||||
let verifier = try! Verifier(buffer: &buffer)
|
let verifier = try! Verifier(buffer: &buffer)
|
||||||
do {
|
#expect(throws: FlatbuffersErrors.missAlignedPointer(
|
||||||
|
position: 20,
|
||||||
|
type: "Int"))
|
||||||
|
{
|
||||||
try verifier.isAligned(position: 20, type: Int.self)
|
try verifier.isAligned(position: 20, type: Int.self)
|
||||||
} catch {
|
|
||||||
XCTAssertEqual(
|
|
||||||
error as? FlatbuffersErrors,
|
|
||||||
.missAlignedPointer(position: 20, type: "Int"))
|
|
||||||
}
|
}
|
||||||
XCTAssertNoThrow(try verifier.isAligned(position: 16, type: Int.self))
|
|
||||||
|
try verifier.isAligned(position: 16, type: Int.self)
|
||||||
|
|
||||||
let newVerifer = try! Verifier(buffer: &buffer, checkAlignment: false)
|
let newVerifer = try! Verifier(buffer: &buffer, checkAlignment: false)
|
||||||
XCTAssertNoThrow(try newVerifer.isAligned(position: 16, type: Int.self))
|
try newVerifer.isAligned(position: 16, type: Int.self)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRangeInBuffer() {
|
@Test
|
||||||
|
func testRangeInBuffer() throws {
|
||||||
var verifier = try! Verifier(buffer: &buffer)
|
var verifier = try! Verifier(buffer: &buffer)
|
||||||
let size = MemoryLayout<Int64>.size
|
let size = MemoryLayout<Int64>.size
|
||||||
XCTAssertNoThrow(try verifier.rangeInBuffer(position: 24, size: size))
|
try verifier.rangeInBuffer(position: 24, size: size)
|
||||||
XCTAssertThrowsError(try verifier.rangeInBuffer(position: 26, size: size))
|
#expect(throws: FlatbuffersErrors.outOfBounds(position: 34, end: 32)) {
|
||||||
XCTAssertThrowsError(try verifier.rangeInBuffer(position: 26, size: size))
|
try verifier.rangeInBuffer(position: 26, size: size)
|
||||||
XCTAssertThrowsError(try verifier.rangeInBuffer(position: 30, size: size))
|
}
|
||||||
XCTAssertThrowsError(try verifier.rangeInBuffer(position: 32, size: size))
|
#expect(throws: FlatbuffersErrors.outOfBounds(position: 34, end: 32)) {
|
||||||
XCTAssertThrowsError(try verifier.rangeInBuffer(position: 34, size: size))
|
try verifier.rangeInBuffer(
|
||||||
|
position: 26,
|
||||||
|
size: size)
|
||||||
|
}
|
||||||
|
#expect(throws: FlatbuffersErrors.outOfBounds(position: 38, end: 32)) {
|
||||||
|
try verifier.rangeInBuffer(
|
||||||
|
position: 30,
|
||||||
|
size: size)
|
||||||
|
}
|
||||||
|
#expect(throws: FlatbuffersErrors.outOfBounds(position: 40, end: 32)) {
|
||||||
|
try verifier.rangeInBuffer(
|
||||||
|
position: 32,
|
||||||
|
size: size)
|
||||||
|
}
|
||||||
|
#expect(throws: FlatbuffersErrors.outOfBounds(position: 42, end: 32)) {
|
||||||
|
try verifier.rangeInBuffer(
|
||||||
|
position: 34,
|
||||||
|
size: size)
|
||||||
|
}
|
||||||
|
|
||||||
verifier = try! Verifier(
|
verifier = try! Verifier(
|
||||||
buffer: &buffer,
|
buffer: &buffer,
|
||||||
options: .init(maxDepth: 0, maxTableCount: 0, maxApparentSize: 4))
|
options: .init(maxDepth: 0, maxTableCount: 0, maxApparentSize: 4))
|
||||||
do {
|
|
||||||
|
#expect(throws: FlatbuffersErrors.apparentSizeTooLarge) {
|
||||||
try verifier.rangeInBuffer(position: 24, size: size)
|
try verifier.rangeInBuffer(position: 24, size: size)
|
||||||
} catch {
|
|
||||||
XCTAssertEqual(
|
|
||||||
error as! FlatbuffersErrors,
|
|
||||||
.apparentSizeTooLarge)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testPositionInBuffer() {
|
@Test
|
||||||
|
func testPositionInBuffer() throws {
|
||||||
let verifier = try! Verifier(buffer: &buffer)
|
let verifier = try! Verifier(buffer: &buffer)
|
||||||
XCTAssertNoThrow(try verifier.inBuffer(position: 0, of: Int64.self))
|
try verifier.inBuffer(position: 0, of: Int64.self)
|
||||||
XCTAssertNoThrow(try verifier.inBuffer(position: 24, of: Int64.self))
|
try verifier.inBuffer(position: 24, of: Int64.self)
|
||||||
XCTAssertThrowsError(try verifier.inBuffer(position: -9, of: Int64.self))
|
|
||||||
XCTAssertThrowsError(try verifier.inBuffer(position: 25, of: Int64.self))
|
#expect(
|
||||||
XCTAssertThrowsError(try verifier.inBuffer(position: 26, of: Int32.self))
|
throws: FlatbuffersErrors.missAlignedPointer(
|
||||||
XCTAssertThrowsError(try verifier.inBuffer(position: 26, of: Int64.self))
|
position: -9,
|
||||||
XCTAssertThrowsError(try verifier.inBuffer(position: 30, of: Int64.self))
|
type: "Int64"))
|
||||||
XCTAssertThrowsError(try verifier.inBuffer(position: 32, of: Int64.self))
|
{
|
||||||
XCTAssertThrowsError(try verifier.inBuffer(position: 34, of: Int64.self))
|
try verifier.inBuffer(position: -9, of: Int64.self)
|
||||||
|
}
|
||||||
|
#expect(
|
||||||
|
throws: FlatbuffersErrors.missAlignedPointer(
|
||||||
|
position: 25,
|
||||||
|
type: "Int64"))
|
||||||
|
{
|
||||||
|
try verifier.inBuffer(position: 25, of: Int64.self)
|
||||||
|
}
|
||||||
|
#expect(
|
||||||
|
throws: FlatbuffersErrors.missAlignedPointer(
|
||||||
|
position: 26,
|
||||||
|
type: "Int32"))
|
||||||
|
{
|
||||||
|
try verifier.inBuffer(position: 26, of: Int32.self)
|
||||||
|
}
|
||||||
|
#expect(
|
||||||
|
throws: FlatbuffersErrors.missAlignedPointer(
|
||||||
|
position: 26,
|
||||||
|
type: "Int64"))
|
||||||
|
{
|
||||||
|
try verifier.inBuffer(position: 26, of: Int64.self)
|
||||||
|
}
|
||||||
|
#expect(
|
||||||
|
throws: FlatbuffersErrors.missAlignedPointer(
|
||||||
|
position: 30,
|
||||||
|
type: "Int64"))
|
||||||
|
{
|
||||||
|
try verifier.inBuffer(position: 30, of: Int64.self)
|
||||||
|
}
|
||||||
|
#expect(throws: FlatbuffersErrors.outOfBounds(position: 40, end: 32)) {
|
||||||
|
try verifier.inBuffer(
|
||||||
|
position: 32,
|
||||||
|
of: Int64.self)
|
||||||
|
}
|
||||||
|
#expect(
|
||||||
|
throws: FlatbuffersErrors.missAlignedPointer(
|
||||||
|
position: 34,
|
||||||
|
type: "Int64"))
|
||||||
|
{
|
||||||
|
try verifier.inBuffer(position: 34, of: Int64.self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testVisitTable() {
|
@Test
|
||||||
|
func testVisitTable() throws {
|
||||||
var verifier = try! Verifier(buffer: &validFlatbuffersObject)
|
var verifier = try! Verifier(buffer: &validFlatbuffersObject)
|
||||||
XCTAssertNoThrow(try verifier.visitTable(at: 48))
|
_ = try verifier.visitTable(at: 48)
|
||||||
verifier.reset()
|
verifier.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTableVerifier() {
|
@Test
|
||||||
|
func testTableVerifier() throws {
|
||||||
var verifier = try! Verifier(buffer: &validFlatbuffersObject)
|
var verifier = try! Verifier(buffer: &validFlatbuffersObject)
|
||||||
|
|
||||||
var tableVerifer = try! verifier.visitTable(at: 48)
|
var tableVerifer = try! verifier.visitTable(at: 48)
|
||||||
XCTAssertEqual(verifier.depth, 1)
|
#expect(verifier.depth == 1)
|
||||||
XCTAssertEqual(verifier.tableCount, 1)
|
#expect(verifier.tableCount == 1)
|
||||||
|
|
||||||
XCTAssertNoThrow(
|
try tableVerifer.visit(
|
||||||
try tableVerifer.visit(
|
field: 4,
|
||||||
field: 4,
|
fieldName: "Vec",
|
||||||
fieldName: "Vec",
|
required: false,
|
||||||
required: false,
|
type: Vec3.self)
|
||||||
type: Vec3.self))
|
|
||||||
XCTAssertNoThrow(
|
|
||||||
try tableVerifer.visit(
|
|
||||||
field: 8,
|
|
||||||
fieldName: "hp",
|
|
||||||
required: false,
|
|
||||||
type: Int16.self))
|
|
||||||
|
|
||||||
XCTAssertNoThrow(
|
try tableVerifer.visit(
|
||||||
try tableVerifer.visit(
|
field: 8,
|
||||||
field: 10,
|
fieldName: "hp",
|
||||||
fieldName: "name",
|
required: false,
|
||||||
required: true,
|
type: Int16.self)
|
||||||
type: ForwardOffset<String>.self))
|
|
||||||
|
|
||||||
XCTAssertNoThrow(
|
try tableVerifer.visit(
|
||||||
try tableVerifer.visit(
|
field: 10,
|
||||||
field: 14,
|
fieldName: "name",
|
||||||
fieldName: "inventory",
|
required: true,
|
||||||
required: false,
|
type: ForwardOffset<String>.self)
|
||||||
type: ForwardOffset<Vector<UInt8, UInt8>>.self))
|
|
||||||
|
|
||||||
XCTAssertNoThrow(
|
try tableVerifer.visit(
|
||||||
try tableVerifer.visit(
|
field: 14,
|
||||||
field: 22,
|
fieldName: "inventory",
|
||||||
fieldName: "test4",
|
required: false,
|
||||||
required: false,
|
type: ForwardOffset<Vector<UInt8, UInt8>>.self)
|
||||||
type: ForwardOffset<Vector<MyGame_Example_Test, MyGame_Example_Test>>
|
|
||||||
.self))
|
|
||||||
|
|
||||||
XCTAssertNoThrow(
|
try tableVerifer.visit(
|
||||||
try tableVerifer.visit(
|
field: 22,
|
||||||
field: 24,
|
fieldName: "test4",
|
||||||
fieldName: "Vector of strings",
|
required: false,
|
||||||
required: false,
|
type: ForwardOffset<Vector<MyGame_Example_Test, MyGame_Example_Test>>
|
||||||
type: ForwardOffset<Vector<ForwardOffset<String>, String>>.self))
|
.self)
|
||||||
|
|
||||||
do {
|
try tableVerifer.visit(
|
||||||
|
field: 24,
|
||||||
|
fieldName: "Vector of strings",
|
||||||
|
required: false,
|
||||||
|
type: ForwardOffset<Vector<ForwardOffset<String>, String>>.self)
|
||||||
|
|
||||||
|
#expect(throws: FlatbuffersErrors.missAlignedPointer(
|
||||||
|
position: 25,
|
||||||
|
type: "UInt16"))
|
||||||
|
{
|
||||||
try tableVerifer.visit(
|
try tableVerifer.visit(
|
||||||
field: 13,
|
field: 13,
|
||||||
fieldName: "notvalid",
|
fieldName: "notvalid",
|
||||||
required: false,
|
required: false,
|
||||||
type: Int16.self)
|
type: Int16.self)
|
||||||
} catch {
|
|
||||||
XCTAssertEqual(
|
|
||||||
error as! FlatbuffersErrors,
|
|
||||||
.missAlignedPointer(position: 25, type: "UInt16"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
try tableVerifer.visit(
|
||||||
try tableVerifer.visit(
|
unionKey: 18,
|
||||||
unionKey: 18,
|
unionField: 20,
|
||||||
unionField: 20,
|
unionKeyName: "testType",
|
||||||
unionKeyName: "testType",
|
fieldName: "test",
|
||||||
fieldName: "test",
|
required: false,
|
||||||
required: false,
|
completion: { (verifier, key: MyGame_Example_Any_, pos) in
|
||||||
completion: { (verifier, key: MyGame_Example_Any_, pos) in
|
switch key {
|
||||||
switch key {
|
case .none_:
|
||||||
case .none_:
|
break // NOTE - SWIFT doesnt support none
|
||||||
break
|
case .monster:
|
||||||
case .monster:
|
try ForwardOffset<MyGame_Example_Monster>.verify(
|
||||||
try ForwardOffset<MyGame_Example_Monster>.verify(
|
&verifier,
|
||||||
&verifier,
|
at: pos,
|
||||||
at: pos,
|
of: MyGame_Example_Monster.self)
|
||||||
of: MyGame_Example_Monster.self)
|
case .testsimpletablewithenum:
|
||||||
|
try ForwardOffset<MyGame_Example_TestSimpleTableWithEnum>.verify(
|
||||||
|
&verifier,
|
||||||
|
at: pos,
|
||||||
|
of: MyGame_Example_TestSimpleTableWithEnum.self)
|
||||||
|
case .mygameExample2Monster:
|
||||||
|
try ForwardOffset<MyGame_Example2_Monster>.verify(
|
||||||
|
&verifier,
|
||||||
|
at: pos,
|
||||||
|
of: MyGame_Example2_Monster.self)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
case .testsimpletablewithenum:
|
|
||||||
break
|
|
||||||
case .mygameExample2Monster:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} catch {
|
|
||||||
XCTAssertEqual(
|
|
||||||
error as! FlatbuffersErrors,
|
|
||||||
.missAlignedPointer(position: 25, type: "UInt16"))
|
|
||||||
}
|
|
||||||
tableVerifer.finish()
|
tableVerifer.finish()
|
||||||
XCTAssertEqual(verifier.depth, 0)
|
#expect(verifier.depth == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testVerifyUnionVectors() {
|
@Test
|
||||||
|
func testVerifyUnionVectors() throws {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
var byteBuffer = ByteBuffer(bytes: [
|
var byteBuffer = ByteBuffer(bytes: [
|
||||||
20, 0, 0, 0, 77, 79, 86, 73, 12, 0, 12, 0, 0, 0, 0, 0, 8, 0, 4, 0, 12, 0, 0, 0, 8, 0, 0, 0,
|
20, 0, 0, 0, 77, 79, 86, 73, 12, 0, 12, 0, 0, 0, 0, 0, 8, 0, 4, 0, 12, 0, 0, 0, 8, 0, 0, 0,
|
||||||
@@ -281,10 +340,11 @@ final class FlatbuffersVerifierTests: XCTestCase {
|
|||||||
0, 0, 7, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 8, 0, 0, 0,
|
0, 0, 7, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 8, 0, 0, 0,
|
||||||
])
|
])
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
XCTAssertNoThrow(try getCheckedRoot(byteBuffer: &byteBuffer) as Movie)
|
_ = try getCheckedRoot(byteBuffer: &byteBuffer) as Movie
|
||||||
}
|
}
|
||||||
|
|
||||||
func testErrorWrongFileId() {
|
@Test
|
||||||
|
func testErrorWrongFileId() throws{
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
var byteBuffer = ByteBuffer(bytes: [
|
var byteBuffer = ByteBuffer(bytes: [
|
||||||
20, 0, 0, 0, 77, 79, 86, 73, 12, 0, 12, 0, 0, 0, 0, 0, 8, 0, 4, 0, 12, 0, 0, 0, 8, 0, 0, 0,
|
20, 0, 0, 0, 77, 79, 86, 73, 12, 0, 12, 0, 0, 0, 0, 0, 8, 0, 4, 0, 12, 0, 0, 0, 8, 0, 0, 0,
|
||||||
@@ -292,12 +352,14 @@ final class FlatbuffersVerifierTests: XCTestCase {
|
|||||||
0, 0, 7, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 8, 0, 0, 0,
|
0, 0, 7, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 8, 0, 0, 0,
|
||||||
])
|
])
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
XCTAssertThrowsError(
|
#expect(throws: FlatbuffersErrors.bufferIdDidntMatchPassedId) {
|
||||||
try getCheckedRoot(
|
try getCheckedRoot(
|
||||||
byteBuffer: &byteBuffer,
|
byteBuffer: &byteBuffer,
|
||||||
fileId: "FLEX") as Movie)
|
fileId: "FLEX") as Movie
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testVerifyPrefixedBuffer() {
|
func testVerifyPrefixedBuffer() {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
var byteBuffer = ByteBuffer(bytes: [
|
var byteBuffer = ByteBuffer(bytes: [
|
||||||
@@ -306,41 +368,71 @@ final class FlatbuffersVerifierTests: XCTestCase {
|
|||||||
0, 2, 0, 0, 0, 7, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 8, 0, 0, 0,
|
0, 2, 0, 0, 0, 7, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 8, 0, 0, 0,
|
||||||
])
|
])
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
XCTAssertThrowsError(
|
#expect(throws: FlatbuffersErrors.prefixedSizeNotEqualToBufferSize) {
|
||||||
try getCheckedPrefixedSizeRoot(byteBuffer: &byteBuffer) as Movie)
|
try getCheckedPrefixedSizeRoot(byteBuffer: &byteBuffer) as Movie
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testFullVerifier() {
|
@Test
|
||||||
XCTAssertNoThrow(
|
func testFullVerifier() throws {
|
||||||
|
_ =
|
||||||
try getCheckedRoot(
|
try getCheckedRoot(
|
||||||
byteBuffer: &validFlatbuffersObject) as MyGame_Example_Monster)
|
byteBuffer: &validFlatbuffersObject) as MyGame_Example_Monster
|
||||||
}
|
}
|
||||||
|
|
||||||
func testFullVerifierWithFileId() {
|
@Test
|
||||||
XCTAssertNoThrow(
|
func testFullVerifierWithFileId() throws {
|
||||||
try getCheckedRoot(
|
_ = try getCheckedRoot(
|
||||||
byteBuffer: &validFlatbuffersObject,
|
byteBuffer: &validFlatbuffersObject,
|
||||||
fileId: MyGame_Example_Monster.id) as MyGame_Example_Monster)
|
fileId: MyGame_Example_Monster.id) as MyGame_Example_Monster
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testInvalidBuffer() {
|
func testInvalidBuffer() {
|
||||||
XCTAssertThrowsError(
|
#expect(throws: FlatbuffersErrors.self) {
|
||||||
try getCheckedRoot(
|
try getCheckedRoot(
|
||||||
byteBuffer: &invalidFlatbuffersObject) as MyGame_Example_Monster)
|
byteBuffer: &self.invalidFlatbuffersObject) as MyGame_Example_Monster
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testInvalidBuffer2() {
|
func testInvalidBuffer2() {
|
||||||
XCTAssertThrowsError(
|
#expect(throws: FlatbuffersErrors.self) {
|
||||||
try getCheckedRoot(
|
try getCheckedRoot(
|
||||||
byteBuffer: &invalidFlatbuffersObject2) as MyGame_Example_Monster)
|
byteBuffer: &self.invalidFlatbuffersObject2) as MyGame_Example_Monster
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testInvalidBuffer3() {
|
func testInvalidBuffer3() {
|
||||||
XCTAssertThrowsError(
|
#expect(throws: FlatbuffersErrors.self) {
|
||||||
try getCheckedRoot(
|
try getCheckedRoot(
|
||||||
byteBuffer: &invalidFlatbuffersObject3) as MyGame_Example_Monster)
|
byteBuffer: &self.invalidFlatbuffersObject3) as MyGame_Example_Monster
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(.bug("https://github.com/google/flatbuffers/issues/9082"))
|
||||||
|
func testRejectsTruncatedScalarVector() {
|
||||||
|
// swiftformat:disable all
|
||||||
|
var byteBuffer = ByteBuffer(bytes: [
|
||||||
|
16, 0, 0, 0,
|
||||||
|
6, 0, 8, 0,
|
||||||
|
4, 0, 0, 0,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
12, 0, 0, 0,
|
||||||
|
8, 0, 0, 0,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
2, 0, 0, 0,
|
||||||
|
65, 66,
|
||||||
|
])
|
||||||
|
// swiftformat:enable all
|
||||||
|
|
||||||
|
#expect(throws: FlatbuffersErrors.self) {
|
||||||
|
try getCheckedRoot(byteBuffer: &byteBuffer) as Swift_Tests_Vectors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testValidUnionBuffer() {
|
func testValidUnionBuffer() {
|
||||||
let string = "Awesome \\\\t\t\nstring!"
|
let string = "Awesome \\\\t\t\nstring!"
|
||||||
var fb = FlatBufferBuilder()
|
var fb = FlatBufferBuilder()
|
||||||
@@ -362,9 +454,14 @@ final class FlatbuffersVerifierTests: XCTestCase {
|
|||||||
charactersVectorOffset: characterVector)
|
charactersVectorOffset: characterVector)
|
||||||
Movie.finish(&fb, end: end)
|
Movie.finish(&fb, end: end)
|
||||||
var buf = fb.sizedBuffer
|
var buf = fb.sizedBuffer
|
||||||
XCTAssertNoThrow(try getCheckedRoot(byteBuffer: &buf) as Movie)
|
do {
|
||||||
|
_ = try getCheckedRoot(byteBuffer: &buf) as Movie
|
||||||
|
} catch {
|
||||||
|
Issue.record(error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testNestedTables() throws {
|
func testNestedTables() throws {
|
||||||
var builder = FlatBufferBuilder()
|
var builder = FlatBufferBuilder()
|
||||||
let name = builder.create(string: "Monster")
|
let name = builder.create(string: "Monster")
|
||||||
@@ -383,22 +480,22 @@ final class FlatbuffersVerifierTests: XCTestCase {
|
|||||||
var verifier = try! Verifier(buffer: &sizedBuffer)
|
var verifier = try! Verifier(buffer: &sizedBuffer)
|
||||||
var tableVerifer = try! verifier.visitTable(
|
var tableVerifer = try! verifier.visitTable(
|
||||||
at: try getOffset(at: 0, within: verifier))
|
at: try getOffset(at: 0, within: verifier))
|
||||||
XCTAssertEqual(verifier.depth, 1)
|
#expect(verifier.depth == 1)
|
||||||
XCTAssertEqual(verifier.tableCount, 1)
|
#expect(verifier.tableCount == 1)
|
||||||
|
|
||||||
let position = try tableVerifer.dereference(28)!
|
let position = try tableVerifer.dereference(28)!
|
||||||
|
|
||||||
var nestedTable = try verifier.visitTable(
|
var nestedTable = try verifier.visitTable(
|
||||||
at: try getOffset(at: position, within: verifier))
|
at: try getOffset(at: position, within: verifier))
|
||||||
|
|
||||||
XCTAssertEqual(verifier.depth, 2)
|
#expect(verifier.depth == 2)
|
||||||
XCTAssertEqual(verifier.tableCount, 2)
|
#expect(verifier.tableCount == 2)
|
||||||
nestedTable.finish()
|
nestedTable.finish()
|
||||||
XCTAssertEqual(verifier.depth, 1)
|
#expect(verifier.depth == 1)
|
||||||
XCTAssertEqual(verifier.tableCount, 2)
|
#expect(verifier.tableCount == 2)
|
||||||
tableVerifer.finish()
|
tableVerifer.finish()
|
||||||
XCTAssertEqual(verifier.depth, 0)
|
#expect(verifier.depth == 0)
|
||||||
XCTAssertEqual(verifier.tableCount, 2)
|
#expect(verifier.tableCount == 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func add(buffer: inout ByteBuffer, v: Int32, p: Int) {
|
func add(buffer: inout ByteBuffer, v: Int32, p: Int) {
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public struct Property_Mutable: FlatBufferStruct, FlatbuffersVectorInitializable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct TestMutatingBool: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct TestMutatingBool: 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 }
|
||||||
|
|||||||
@@ -398,7 +398,7 @@ public struct MyGame_Example_LargeArrayStruct_Mutable: FlatBufferStruct, Flatbuf
|
|||||||
}
|
}
|
||||||
|
|
||||||
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *)
|
@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *)
|
||||||
public struct MyGame_Example_ArrayTable: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Example_ArrayTable: 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 }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import Common
|
|||||||
|
|
||||||
import FlatBuffers
|
import FlatBuffers
|
||||||
|
|
||||||
public struct DataModel_A: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct DataModel_A: 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 }
|
||||||
|
|||||||
@@ -5,206 +5,568 @@
|
|||||||
// swiftlint:disable all
|
// swiftlint:disable all
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
|
|
||||||
#if !os(Windows)
|
#if !os(Windows) && compiler(>=6.0)
|
||||||
import Foundation
|
|
||||||
import GRPC
|
|
||||||
import NIO
|
|
||||||
import NIOHTTP1
|
|
||||||
import FlatBuffers
|
import FlatBuffers
|
||||||
|
import Foundation
|
||||||
|
import GRPCCore
|
||||||
|
import GRPCNIOTransportCore
|
||||||
|
|
||||||
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 MyGame_Example_MonsterStorageServiceClient, then call methods of this protocol to make API calls.
|
/// Usage: instantiate MyGame.Example.MonsterStorageServiceClient, then call methods of this protocol to make API calls.
|
||||||
public protocol MyGame_Example_MonsterStorageClientProtocol: GRPCClient {
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension FlatBuffersMessageSerializer: MessageSerializer {
|
||||||
var serviceName: String { get }
|
public func serialize<Bytes>(_ message: Message) throws -> Bytes where Bytes : GRPCCore.GRPCContiguousBytes {
|
||||||
|
do {
|
||||||
var interceptors: MyGame_Example_MonsterStorageClientInterceptorFactoryProtocol? { get }
|
return try self.serialize(message: message) { GRPCNIOTransportBytes($0) } as! Bytes
|
||||||
|
} catch let error {
|
||||||
func Store(
|
throw RPCError(
|
||||||
_ request: Message<MyGame_Example_Monster>
|
code: .invalidArgument,
|
||||||
, callOptions: CallOptions?
|
message: "Can't serialize message",
|
||||||
) -> UnaryCall<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>
|
cause: error
|
||||||
|
)
|
||||||
func Retrieve(
|
|
||||||
_ request: Message<MyGame_Example_Stat>
|
|
||||||
, callOptions: CallOptions?,
|
|
||||||
handler: @escaping (Message<MyGame_Example_Monster>) -> Void
|
|
||||||
) -> ServerStreamingCall<Message<MyGame_Example_Stat>, Message<MyGame_Example_Monster>>
|
|
||||||
|
|
||||||
func GetMaxHitPoint(
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> ClientStreamingCall<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>
|
|
||||||
|
|
||||||
func GetMinMaxHitPoints(
|
|
||||||
callOptions: CallOptions?,
|
|
||||||
handler: @escaping (Message<MyGame_Example_Stat> ) -> Void
|
|
||||||
) -> BidirectionalStreamingCall<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension MyGame_Example_MonsterStorageClientProtocol {
|
|
||||||
|
|
||||||
public var serviceName: String { "MyGame.Example.MonsterStorage" }
|
|
||||||
|
|
||||||
public func Store(
|
|
||||||
_ request: Message<MyGame_Example_Monster>
|
|
||||||
, callOptions: CallOptions? = nil
|
|
||||||
) -> UnaryCall<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>> {
|
|
||||||
return self.makeUnaryCall(
|
|
||||||
path: "/MyGame.Example.MonsterStorage/Store",
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeStoreInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func Retrieve(
|
|
||||||
_ request: Message<MyGame_Example_Stat>
|
|
||||||
, callOptions: CallOptions? = nil,
|
|
||||||
handler: @escaping (Message<MyGame_Example_Monster>) -> Void
|
|
||||||
) -> ServerStreamingCall<Message<MyGame_Example_Stat>, Message<MyGame_Example_Monster>> {
|
|
||||||
return self.makeServerStreamingCall(
|
|
||||||
path: "/MyGame.Example.MonsterStorage/Retrieve",
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeRetrieveInterceptors() ?? [],
|
|
||||||
handler: handler
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func GetMaxHitPoint(
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> ClientStreamingCall<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>> {
|
|
||||||
return self.makeClientStreamingCall(
|
|
||||||
path: "/MyGame.Example.MonsterStorage/GetMaxHitPoint",
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeGetMaxHitPointInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func GetMinMaxHitPoints(
|
|
||||||
callOptions: CallOptions? = nil,
|
|
||||||
handler: @escaping (Message<MyGame_Example_Stat> ) -> Void
|
|
||||||
) -> BidirectionalStreamingCall<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>> {
|
|
||||||
return self.makeBidirectionalStreamingCall(
|
|
||||||
path: "/MyGame.Example.MonsterStorage/GetMinMaxHitPoints",
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeGetMinMaxHitPointsInterceptors() ?? [],
|
|
||||||
handler: handler
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public protocol MyGame_Example_MonsterStorageClientInterceptorFactoryProtocol {
|
|
||||||
/// - Returns: Interceptors to use when invoking 'Store'.
|
|
||||||
func makeStoreInterceptors() -> [ClientInterceptor<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>]
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when invoking 'Retrieve'.
|
|
||||||
func makeRetrieveInterceptors() -> [ClientInterceptor<Message<MyGame_Example_Stat>, Message<MyGame_Example_Monster>>]
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when invoking 'GetMaxHitPoint'.
|
|
||||||
func makeGetMaxHitPointInterceptors() -> [ClientInterceptor<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>]
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when invoking 'GetMinMaxHitPoints'.
|
|
||||||
func makeGetMinMaxHitPointsInterceptors() -> [ClientInterceptor<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class MyGame_Example_MonsterStorageServiceClient: MyGame_Example_MonsterStorageClientProtocol {
|
|
||||||
public let channel: GRPCChannel
|
|
||||||
public var defaultCallOptions: CallOptions
|
|
||||||
public var interceptors: MyGame_Example_MonsterStorageClientInterceptorFactoryProtocol?
|
|
||||||
|
|
||||||
public init(
|
|
||||||
channel: GRPCChannel,
|
|
||||||
defaultCallOptions: CallOptions = CallOptions(),
|
|
||||||
interceptors: MyGame_Example_MonsterStorageClientInterceptorFactoryProtocol? = nil
|
|
||||||
) {
|
|
||||||
self.channel = channel
|
|
||||||
self.defaultCallOptions = defaultCallOptions
|
|
||||||
self.interceptors = interceptors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public protocol MyGame_Example_MonsterStorageProvider: CallHandlerProvider {
|
|
||||||
var interceptors: MyGame_Example_MonsterStorageServerInterceptorFactoryProtocol? { get }
|
|
||||||
func Store(request: Message<MyGame_Example_Monster>, context: StatusOnlyCallContext) -> EventLoopFuture<Message<MyGame_Example_Stat>>
|
|
||||||
func Retrieve(request: Message<MyGame_Example_Stat>, context: StreamingResponseCallContext<Message<MyGame_Example_Monster>>) -> EventLoopFuture<GRPCStatus>
|
|
||||||
func GetMaxHitPoint(context: UnaryResponseCallContext<Message<MyGame_Example_Stat>>) -> EventLoopFuture<(StreamEvent<Message<MyGame_Example_Monster>>) -> Void>
|
|
||||||
func GetMinMaxHitPoints(context: StreamingResponseCallContext<Message<MyGame_Example_Stat>>) -> EventLoopFuture<(StreamEvent<Message<MyGame_Example_Monster>>) -> Void>
|
|
||||||
}
|
|
||||||
|
|
||||||
public extension MyGame_Example_MonsterStorageProvider {
|
|
||||||
|
|
||||||
var serviceName: Substring { return "MyGame.Example.MonsterStorage" }
|
|
||||||
|
|
||||||
func handle(method name: Substring, context: CallHandlerContext) -> GRPCServerHandlerProtocol? {
|
|
||||||
switch name {
|
|
||||||
case "Store":
|
|
||||||
return UnaryServerHandler(
|
|
||||||
context: context,
|
|
||||||
requestDeserializer: GRPCPayloadDeserializer<Message<MyGame_Example_Monster>>(),
|
|
||||||
responseSerializer: GRPCPayloadSerializer<Message<MyGame_Example_Stat>>(),
|
|
||||||
interceptors: self.interceptors?.makeStoreInterceptors() ?? [],
|
|
||||||
userFunction: self.Store(request:context:))
|
|
||||||
|
|
||||||
case "Retrieve":
|
|
||||||
return ServerStreamingServerHandler(
|
|
||||||
context: context,
|
|
||||||
requestDeserializer: GRPCPayloadDeserializer<Message<MyGame_Example_Stat>>(),
|
|
||||||
responseSerializer: GRPCPayloadSerializer<Message<MyGame_Example_Monster>>(),
|
|
||||||
interceptors: self.interceptors?.makeRetrieveInterceptors() ?? [],
|
|
||||||
userFunction: self.Retrieve(request:context:))
|
|
||||||
|
|
||||||
case "GetMaxHitPoint":
|
|
||||||
return ClientStreamingServerHandler(
|
|
||||||
context: context,
|
|
||||||
requestDeserializer: GRPCPayloadDeserializer<Message<MyGame_Example_Monster>>(),
|
|
||||||
responseSerializer: GRPCPayloadSerializer<Message<MyGame_Example_Stat>>(),
|
|
||||||
interceptors: self.interceptors?.makeGetMaxHitPointInterceptors() ?? [],
|
|
||||||
observerFactory: self.GetMaxHitPoint(context:))
|
|
||||||
|
|
||||||
case "GetMinMaxHitPoints":
|
|
||||||
return BidirectionalStreamingServerHandler(
|
|
||||||
context: context,
|
|
||||||
requestDeserializer: GRPCPayloadDeserializer<Message<MyGame_Example_Monster>>(),
|
|
||||||
responseSerializer: GRPCPayloadSerializer<Message<MyGame_Example_Stat>>(),
|
|
||||||
interceptors: self.interceptors?.makeGetMinMaxHitPointsInterceptors() ?? [],
|
|
||||||
observerFactory: self.GetMinMaxHitPoints(context:))
|
|
||||||
|
|
||||||
default: return nil;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 MyGame_Example_MonsterStorage: Sendable {
|
||||||
|
public static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "MyGame.Example.MonsterStorage")
|
||||||
|
public enum Method: Sendable {
|
||||||
|
public enum Store: Sendable {
|
||||||
|
public typealias Input = FlatBufferBuilder
|
||||||
|
public typealias Output = MyGame_Example_Stat
|
||||||
|
public static let descriptor = GRPCCore.MethodDescriptor(
|
||||||
|
service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "MyGame.Example.MonsterStorage"),
|
||||||
|
method: "Store"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public enum Retrieve: Sendable {
|
||||||
|
public typealias Input = FlatBufferBuilder
|
||||||
|
public typealias Output = MyGame_Example_Monster
|
||||||
|
public static let descriptor = GRPCCore.MethodDescriptor(
|
||||||
|
service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "MyGame.Example.MonsterStorage"),
|
||||||
|
method: "Retrieve"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public enum GetMaxHitPoint: Sendable {
|
||||||
|
public typealias Input = FlatBufferBuilder
|
||||||
|
public typealias Output = MyGame_Example_Stat
|
||||||
|
public static let descriptor = GRPCCore.MethodDescriptor(
|
||||||
|
service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "MyGame.Example.MonsterStorage"),
|
||||||
|
method: "GetMaxHitPoint"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public enum GetMinMaxHitPoints: Sendable {
|
||||||
|
public typealias Input = FlatBufferBuilder
|
||||||
|
public typealias Output = MyGame_Example_Stat
|
||||||
|
public static let descriptor = GRPCCore.MethodDescriptor(
|
||||||
|
service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "MyGame.Example.MonsterStorage"),
|
||||||
|
method: "GetMinMaxHitPoints"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public static let descriptors: [GRPCCore.MethodDescriptor] = [
|
||||||
|
Store.descriptor,
|
||||||
|
Retrieve.descriptor,
|
||||||
|
GetMaxHitPoint.descriptor,
|
||||||
|
GetMinMaxHitPoints.descriptor,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension GRPCCore.ServiceDescriptor {
|
||||||
|
public static let MyGame_Example_MonsterStorage = GRPCCore.ServiceDescriptor(fullyQualifiedService: "MyGame.Example.MonsterStorage")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: MyGame.Example.MonsterStorage Server
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension MyGame_Example_MonsterStorage {
|
||||||
|
public protocol StreamingServiceProtocol: GRPCCore.RegistrableRPCService {
|
||||||
|
func Store(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>>
|
||||||
|
|
||||||
|
func Retrieve(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Monster>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Monster>>
|
||||||
|
|
||||||
|
func GetMaxHitPoint(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>>
|
||||||
|
|
||||||
|
func GetMinMaxHitPoints(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol ServiceProtocol: MyGame_Example_MonsterStorage.StreamingServiceProtocol {
|
||||||
|
func Store(
|
||||||
|
request: GRPCCore.ServerRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.ServerResponse<GRPCMessage<MyGame_Example_Stat>>
|
||||||
|
|
||||||
|
func Retrieve(
|
||||||
|
request: GRPCCore.ServerRequest<GRPCMessage<MyGame_Example_Monster>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Monster>>
|
||||||
|
|
||||||
|
func GetMaxHitPoint(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.ServerResponse<GRPCMessage<MyGame_Example_Stat>>
|
||||||
|
|
||||||
|
func GetMinMaxHitPoints(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol SimpleServiceProtocol: MyGame_Example_MonsterStorage.ServiceProtocol {
|
||||||
|
func Store(
|
||||||
|
request: GRPCMessage<MyGame_Example_Stat>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCMessage<MyGame_Example_Stat>
|
||||||
|
|
||||||
|
func Retrieve(
|
||||||
|
request: GRPCMessage<MyGame_Example_Monster>,
|
||||||
|
response: GRPCCore.RPCWriter<GRPCMessage<MyGame_Example_Monster>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws
|
||||||
|
|
||||||
|
func GetMaxHitPoint(
|
||||||
|
request: GRPCCore.RPCAsyncSequence<GRPCMessage<MyGame_Example_Stat>, any Swift.Error>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCMessage<MyGame_Example_Stat>
|
||||||
|
|
||||||
|
func GetMinMaxHitPoints(
|
||||||
|
request: GRPCCore.RPCAsyncSequence<GRPCMessage<MyGame_Example_Stat>, any Swift.Error>,
|
||||||
|
response: GRPCCore.RPCWriter<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension MyGame_Example_MonsterStorage.StreamingServiceProtocol {
|
||||||
|
public func registerMethods<Transport>(with router: inout GRPCCore.RPCRouter<Transport>) where Transport: GRPCCore.ServerTransport {
|
||||||
|
router.registerHandler(
|
||||||
|
forMethod: MyGame_Example_MonsterStorage.Method.Store.descriptor,
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Stat>>(),
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Stat>>(),
|
||||||
|
handler: { request, context in
|
||||||
|
try await self.Store(
|
||||||
|
request: request,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
router.registerHandler(
|
||||||
|
forMethod: MyGame_Example_MonsterStorage.Method.Retrieve.descriptor,
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Monster>>(),
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Monster>>(),
|
||||||
|
handler: { request, context in
|
||||||
|
try await self.Retrieve(
|
||||||
|
request: request,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
router.registerHandler(
|
||||||
|
forMethod: MyGame_Example_MonsterStorage.Method.GetMaxHitPoint.descriptor,
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Stat>>(),
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Stat>>(),
|
||||||
|
handler: { request, context in
|
||||||
|
try await self.GetMaxHitPoint(
|
||||||
|
request: request,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
router.registerHandler(
|
||||||
|
forMethod: MyGame_Example_MonsterStorage.Method.GetMinMaxHitPoints.descriptor,
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Stat>>(),
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Stat>>(),
|
||||||
|
handler: { request, context in
|
||||||
|
try await self.GetMinMaxHitPoints(
|
||||||
|
request: request,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension MyGame_Example_MonsterStorage.ServiceProtocol {
|
||||||
|
public func Store(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>> {
|
||||||
|
let response = try await self.Store(
|
||||||
|
request: GRPCCore.ServerRequest(stream: request),
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
return GRPCCore.StreamingServerResponse(single: response)
|
||||||
|
}
|
||||||
|
public func Retrieve(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Monster>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Monster>> {
|
||||||
|
let response = try await self.Retrieve(
|
||||||
|
request: GRPCCore.ServerRequest(stream: request),
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
public func GetMaxHitPoint(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>> {
|
||||||
|
let response = try await self.GetMaxHitPoint(
|
||||||
|
request: request,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
return GRPCCore.StreamingServerResponse(single: response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension MyGame_Example_MonsterStorage.SimpleServiceProtocol {
|
||||||
|
public func Store(
|
||||||
|
request: GRPCCore.ServerRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.ServerResponse<GRPCMessage<MyGame_Example_Stat>> {
|
||||||
|
return GRPCCore.ServerResponse<GRPCMessage<MyGame_Example_Stat>>(
|
||||||
|
message: try await self.Store(
|
||||||
|
request: request.message,
|
||||||
|
context: context
|
||||||
|
),
|
||||||
|
metadata: [:]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public func Retrieve(
|
||||||
|
request: GRPCCore.ServerRequest<GRPCMessage<MyGame_Example_Monster>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Monster>> {
|
||||||
|
return GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Monster>>(
|
||||||
|
metadata: [:],
|
||||||
|
producer: { writer in
|
||||||
|
try await self.Retrieve(
|
||||||
|
request: request.message,
|
||||||
|
response: writer,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
return [:]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public func GetMaxHitPoint(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.ServerResponse<GRPCMessage<MyGame_Example_Stat>> {
|
||||||
|
return GRPCCore.ServerResponse<GRPCMessage<MyGame_Example_Stat>>(
|
||||||
|
message: try await self.GetMaxHitPoint(
|
||||||
|
request: request.messages,
|
||||||
|
context: context
|
||||||
|
),
|
||||||
|
metadata: [:]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public func GetMinMaxHitPoints(
|
||||||
|
request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
context: GRPCCore.ServerContext
|
||||||
|
) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>> {
|
||||||
|
return GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>>(
|
||||||
|
metadata: [:],
|
||||||
|
producer: { writer in
|
||||||
|
try await self.GetMinMaxHitPoints(
|
||||||
|
request: request.messages,
|
||||||
|
response: writer,
|
||||||
|
context: context
|
||||||
|
)
|
||||||
|
return [:]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: MyGame.Example.MonsterStorage Client
|
||||||
|
|
||||||
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
|
extension MyGame_Example_MonsterStorage {
|
||||||
|
public protocol ClientProtocol: Sendable {
|
||||||
|
func Store<Result>(
|
||||||
|
request: GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
options: GRPCCore.CallOptions,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable
|
||||||
|
|
||||||
|
func Retrieve<Result>(
|
||||||
|
request: GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Monster>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Monster>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Monster>>,
|
||||||
|
options: GRPCCore.CallOptions,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Monster>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable
|
||||||
|
|
||||||
|
func GetMaxHitPoint<Result>(
|
||||||
|
request: GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
options: GRPCCore.CallOptions,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable
|
||||||
|
|
||||||
|
func GetMinMaxHitPoints<Result>(
|
||||||
|
request: GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
options: GRPCCore.CallOptions,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Stat>>) 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 MyGame_Example_MonsterStorage {
|
||||||
|
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 Store<Result>(
|
||||||
|
request: GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result = { response in try response.message }
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.client.unary(
|
||||||
|
request: request,
|
||||||
|
descriptor: MyGame_Example_MonsterStorage.Method.Store.descriptor,
|
||||||
|
serializer: serializer,
|
||||||
|
deserializer: deserializer,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func Retrieve<Result>(
|
||||||
|
request: GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Monster>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Monster>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Monster>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Monster>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.client.serverStreaming(
|
||||||
|
request: request,
|
||||||
|
descriptor: MyGame_Example_MonsterStorage.Method.Retrieve.descriptor,
|
||||||
|
serializer: serializer,
|
||||||
|
deserializer: deserializer,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func GetMaxHitPoint<Result>(
|
||||||
|
request: GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result = { response in try response.message }
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.client.clientStreaming(
|
||||||
|
request: request,
|
||||||
|
descriptor: MyGame_Example_MonsterStorage.Method.GetMaxHitPoint.descriptor,
|
||||||
|
serializer: serializer,
|
||||||
|
deserializer: deserializer,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func GetMinMaxHitPoints<Result>(
|
||||||
|
request: GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.client.bidirectionalStreaming(
|
||||||
|
request: request,
|
||||||
|
descriptor: MyGame_Example_MonsterStorage.Method.GetMinMaxHitPoints.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 MyGame_Example_MonsterStorage.ClientProtocol {
|
||||||
|
public func Store<Result>(
|
||||||
|
request: GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result = { response in try response.message }
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.Store(
|
||||||
|
request: request,
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Stat>>(),
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Stat>>(),
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func Retrieve<Result>(
|
||||||
|
request: GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Monster>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Monster>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.Retrieve(
|
||||||
|
request: request,
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Monster>>(),
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Monster>>(),
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func GetMaxHitPoint<Result>(
|
||||||
|
request: GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result = { response in try response.message }
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.GetMaxHitPoint(
|
||||||
|
request: request,
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Stat>>(),
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Stat>>(),
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func GetMinMaxHitPoints<Result>(
|
||||||
|
request: GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>,
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
try await self.GetMinMaxHitPoints(
|
||||||
|
request: request,
|
||||||
|
serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Stat>>(),
|
||||||
|
deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Stat>>(),
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol MyGame_Example_MonsterStorageServerInterceptorFactoryProtocol {
|
@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
|
||||||
/// - Returns: Interceptors to use when handling 'Store'.
|
extension MyGame_Example_MonsterStorage.ClientProtocol {
|
||||||
/// Defaults to calling `self.makeInterceptors()`.
|
public func Store<Result>(
|
||||||
func makeStoreInterceptors() -> [ServerInterceptor<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>]
|
_ message: GRPCMessage<MyGame_Example_Stat>,
|
||||||
|
metadata: GRPCCore.Metadata = [:],
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result = { try $0.message }
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
let request = GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Stat>>(
|
||||||
|
message: message,
|
||||||
|
metadata: metadata
|
||||||
|
)
|
||||||
|
return try await self.Store(
|
||||||
|
request: request,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when handling 'Retrieve'.
|
public func Retrieve<Result>(
|
||||||
/// Defaults to calling `self.makeInterceptors()`.
|
_ message: GRPCMessage<MyGame_Example_Monster>,
|
||||||
func makeRetrieveInterceptors() -> [ServerInterceptor<Message<MyGame_Example_Stat>, Message<MyGame_Example_Monster>>]
|
metadata: GRPCCore.Metadata = [:],
|
||||||
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Monster>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
let request = GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Monster>>(
|
||||||
|
message: message,
|
||||||
|
metadata: metadata
|
||||||
|
)
|
||||||
|
return try await self.Retrieve(
|
||||||
|
request: request,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when handling 'GetMaxHitPoint'.
|
public func GetMaxHitPoint<Result>(
|
||||||
/// Defaults to calling `self.makeInterceptors()`.
|
metadata: GRPCCore.Metadata = [:],
|
||||||
func makeGetMaxHitPointInterceptors() -> [ServerInterceptor<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>]
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter<GRPCMessage<MyGame_Example_Stat>>) async throws -> Void,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result = { try $0.message }
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
let request = GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>(
|
||||||
|
metadata: metadata,
|
||||||
|
producer: producer
|
||||||
|
)
|
||||||
|
return try await self.GetMaxHitPoint(
|
||||||
|
request: request,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when handling 'GetMinMaxHitPoints'.
|
public func GetMinMaxHitPoints<Result>(
|
||||||
/// Defaults to calling `self.makeInterceptors()`.
|
metadata: GRPCCore.Metadata = [:],
|
||||||
func makeGetMinMaxHitPointsInterceptors() -> [ServerInterceptor<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>]
|
options: GRPCCore.CallOptions = .defaults,
|
||||||
|
requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter<GRPCMessage<MyGame_Example_Stat>>) async throws -> Void,
|
||||||
|
onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result
|
||||||
|
) async throws -> Result where Result: Sendable {
|
||||||
|
let request = GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>(
|
||||||
|
metadata: metadata,
|
||||||
|
producer: producer
|
||||||
|
)
|
||||||
|
return try await self.GetMinMaxHitPoints(
|
||||||
|
request: request,
|
||||||
|
options: options,
|
||||||
|
onResponse: handleResponse
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -662,7 +662,7 @@ public struct MyGame_Example_StructOfStructsOfStructs_Mutable: FlatBufferStruct,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct MyGame_InParentNamespace: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_InParentNamespace: 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 }
|
||||||
@@ -712,7 +712,7 @@ public class MyGame_InParentNamespaceT: NativeObject {
|
|||||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_InParentNamespace.self) }
|
public func serialize() -> ByteBuffer { return serialize(type: MyGame_InParentNamespace.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct MyGame_Example2_Monster: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Example2_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 }
|
||||||
@@ -762,7 +762,7 @@ public class MyGame_Example2_MonsterT: NativeObject {
|
|||||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example2_Monster.self) }
|
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example2_Monster.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
internal struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
internal struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
||||||
internal var __buffer: ByteBuffer! { return _accessor.bb }
|
internal var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
@@ -840,7 +840,7 @@ internal class MyGame_Example_TestSimpleTableWithEnumT: NativeObject {
|
|||||||
internal func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_TestSimpleTableWithEnum.self) }
|
internal func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_TestSimpleTableWithEnum.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct MyGame_Example_Stat: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Example_Stat: 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 }
|
||||||
@@ -976,7 +976,7 @@ public class MyGame_Example_StatT: NativeObject {
|
|||||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Stat.self) }
|
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Stat.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct MyGame_Example_Referrable: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Example_Referrable: 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 }
|
||||||
@@ -1079,7 +1079,7 @@ public class MyGame_Example_ReferrableT: NativeObject {
|
|||||||
|
|
||||||
}
|
}
|
||||||
/// an example documentation comment: "monster object"
|
/// an example documentation comment: "monster object"
|
||||||
public struct MyGame_Example_Monster: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Example_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 }
|
||||||
@@ -2213,7 +2213,7 @@ public class MyGame_Example_MonsterT: NativeObject {
|
|||||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Monster.self) }
|
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Monster.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct MyGame_Example_TypeAliases: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Example_TypeAliases: 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 }
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ extension ABC: Encodable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct MoreDefaults: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MoreDefaults: 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 }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import Common
|
|||||||
|
|
||||||
import FlatBuffers
|
import FlatBuffers
|
||||||
|
|
||||||
public struct Swift_Tests_NanInfTable: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable {
|
public struct Swift_Tests_NanInfTable: 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 }
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ extension optional_scalars_OptionalByte: Encodable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct optional_scalars_ScalarStuff: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable {
|
public struct optional_scalars_ScalarStuff: 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 }
|
||||||
|
|||||||
@@ -320,7 +320,7 @@ public struct FallingTub_Mutable: FlatBufferStruct, FlatbuffersVectorInitializab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct Attacker: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct Attacker: 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 }
|
||||||
@@ -398,7 +398,7 @@ public class AttackerT: NativeObject {
|
|||||||
public func serialize() -> ByteBuffer { return serialize(type: Attacker.self) }
|
public func serialize() -> ByteBuffer { return serialize(type: Attacker.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct HandFan: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct HandFan: 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 }
|
||||||
@@ -476,7 +476,7 @@ public class HandFanT: NativeObject {
|
|||||||
public func serialize() -> ByteBuffer { return serialize(type: HandFan.self) }
|
public func serialize() -> ByteBuffer { return serialize(type: HandFan.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct Movie: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct Movie: 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 }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import Common
|
|||||||
|
|
||||||
import FlatBuffers
|
import FlatBuffers
|
||||||
|
|
||||||
public struct Swift_Tests_Vectors: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable {
|
public struct Swift_Tests_Vectors: 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 }
|
||||||
|
|||||||
@@ -16,17 +16,19 @@
|
|||||||
|
|
||||||
import Common
|
import Common
|
||||||
import FlexBuffers
|
import FlexBuffers
|
||||||
import XCTest
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
|
||||||
final class FlexBuffersJSONTests: XCTestCase {
|
struct FlexBuffersJSONTests {
|
||||||
|
@Test
|
||||||
func testEncodingJSON() throws {
|
func testEncodingJSON() throws {
|
||||||
let buf: ByteBuffer = createProperBuffer().sizedByteBuffer
|
let buf: ByteBuffer = createProperBuffer().sizedByteBuffer
|
||||||
let reference = try getRoot(buffer: buf)!
|
let reference = try getRoot(buffer: buf)!
|
||||||
|
|
||||||
let json = reference.jsonString()
|
let json = reference.jsonString()
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
json,
|
json ==
|
||||||
"{\"bar\": [1, 2, 3], \"bar3\": [1, 2, 3], \"bool\": true, \"bools\": [true, false, true, false], \"foo\": 100.0, \"mymap\": {\"foo\": \"Fred\"}, \"vec\": [-100, \"Fred\", 4.0, \"M\", false, 4.0]}"
|
"{\"bar\": [1, 2, 3], \"bar3\": [1, 2, 3], \"bool\": true, \"bools\": [true, false, true, false], \"foo\": 100.0, \"mymap\": {\"foo\": \"Fred\"}, \"vec\": [-100, \"Fred\", 4.0, \"M\", false, 4.0]}"
|
||||||
)
|
)
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
@@ -37,15 +39,15 @@ final class FlexBuffersJSONTests: XCTestCase {
|
|||||||
with: data,
|
with: data,
|
||||||
options: []) as! [String: Any]
|
options: []) as! [String: Any]
|
||||||
|
|
||||||
XCTAssertEqual(decodedData["bar"] as! [Int], [1, 2, 3])
|
#expect(decodedData["bar"] as! [Int] == [1, 2, 3])
|
||||||
XCTAssertEqual(decodedData["bar3"] as! [Int], [1, 2, 3])
|
#expect(decodedData["bar3"] as! [Int] == [1, 2, 3])
|
||||||
|
|
||||||
let vec: [Any] = decodedData["vec"] as! [Any]
|
let vec: [Any] = decodedData["vec"] as! [Any]
|
||||||
XCTAssertEqual(vec[0] as! Int, -100)
|
#expect(vec[0] as! Int == -100)
|
||||||
XCTAssertEqual(vec[1] as! String, "Fred")
|
#expect(vec[1] as! String == "Fred")
|
||||||
XCTAssertEqual(vec[2] as! Double, 4.0)
|
#expect(vec[2] as! Double == 4.0)
|
||||||
XCTAssertEqual(vec[3] as! String, "M")
|
#expect(vec[3] as! String == "M")
|
||||||
XCTAssertEqual(vec[4] as! Bool, false)
|
#expect(vec[4] as! Bool == false)
|
||||||
XCTAssertEqual(vec[5] as! Double, 4.0)
|
#expect(vec[5] as! Double == 4.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,22 +15,26 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Common
|
import Common
|
||||||
import XCTest
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
|
||||||
@testable import FlexBuffers
|
@testable import FlexBuffers
|
||||||
|
|
||||||
final class FlexBuffersReaderTests: XCTestCase {
|
struct FlexBuffersReaderTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadingProperBuffer() throws {
|
func testReadingProperBuffer() throws {
|
||||||
let buf: ByteBuffer = createProperBuffer().byteBuffer
|
let buf: ByteBuffer = createProperBuffer().byteBuffer
|
||||||
try validate(buffer: buf)
|
try validate(buffer: buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadingSizedBuffer() throws {
|
func testReadingSizedBuffer() throws {
|
||||||
let buf: ByteBuffer = createSizedBuffer()
|
let buf: ByteBuffer = createSizedBuffer()
|
||||||
try validate(buffer: buf)
|
try validate(buffer: buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(.bug("https://github.com/google/flatbuffers/issues/8642"))
|
||||||
func testReset() throws {
|
func testReset() throws {
|
||||||
var fbx = FlexBuffersWriter(
|
var fbx = FlexBuffersWriter(
|
||||||
initialSize: 8,
|
initialSize: 8,
|
||||||
@@ -38,87 +42,87 @@ final class FlexBuffersReaderTests: XCTestCase {
|
|||||||
write(fbx: &fbx)
|
write(fbx: &fbx)
|
||||||
|
|
||||||
try validate(buffer: ByteBuffer(data: fbx.data))
|
try validate(buffer: ByteBuffer(data: fbx.data))
|
||||||
XCTAssertEqual(fbx.capacity, 512)
|
#expect(fbx.capacity == 512)
|
||||||
fbx.reset()
|
fbx.reset()
|
||||||
XCTAssertEqual(fbx.writerIndex, 0)
|
#expect(fbx.writerIndex == 0)
|
||||||
XCTAssertEqual(fbx.capacity, 8)
|
#expect(fbx.capacity == 8)
|
||||||
|
|
||||||
write(fbx: &fbx)
|
write(fbx: &fbx)
|
||||||
try validate(buffer: ByteBuffer(data: fbx.data))
|
try validate(buffer: ByteBuffer(data: fbx.data))
|
||||||
fbx.reset(keepingCapacity: true)
|
fbx.reset(keepingCapacity: true)
|
||||||
XCTAssertEqual(fbx.writerIndex, 0)
|
#expect(fbx.writerIndex == 0)
|
||||||
XCTAssertEqual(fbx.capacity, 512)
|
#expect(fbx.capacity == 512)
|
||||||
|
|
||||||
write(fbx: &fbx)
|
write(fbx: &fbx)
|
||||||
try validate(buffer: ByteBuffer(data: fbx.data))
|
try validate(buffer: ByteBuffer(data: fbx.data))
|
||||||
XCTAssertEqual(fbx.capacity, 512)
|
#expect(fbx.capacity == 512)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func validate(buffer buf: ByteBuffer) throws {
|
private func validate(buffer buf: ByteBuffer) throws {
|
||||||
let reference = try getRoot(buffer: buf)!
|
let reference = try getRoot(buffer: buf)!
|
||||||
XCTAssertEqual(reference.type, .map)
|
#expect(reference.type == .map)
|
||||||
let map = reference.map!
|
let map = reference.map!
|
||||||
XCTAssertEqual(map.count, 7)
|
#expect(map.count == 7)
|
||||||
let vecRef = map["vec"]!
|
let vecRef = map["vec"]!
|
||||||
XCTAssertEqual(vecRef.type, .vector)
|
#expect(vecRef.type == .vector)
|
||||||
let vec = vecRef.vector!
|
let vec = vecRef.vector!
|
||||||
XCTAssertEqual(vec.count, 6)
|
#expect(vec.count == 6)
|
||||||
XCTAssertEqual(vec[0]?.type, .int)
|
#expect(vec[0]?.type == .int)
|
||||||
XCTAssertEqual(vec[0]?.int, -100)
|
#expect(vec[0]?.int == -100)
|
||||||
XCTAssertEqual(vec[1]?.type, .string)
|
#expect(vec[1]?.type == .string)
|
||||||
XCTAssertEqual(vec[1]?.cString, "Fred")
|
#expect(vec[1]?.cString == "Fred")
|
||||||
XCTAssertNil(vec[1]?.int)
|
#expect(vec[1]?.int == nil)
|
||||||
XCTAssertEqual(vec[2]?.double, 4.0)
|
#expect(vec[2]?.double == 4.0)
|
||||||
XCTAssertTrue(vec[3]?.type == .blob)
|
#expect(vec[3]?.type == .blob)
|
||||||
|
|
||||||
let blob = vec[3]!.blob { pointer in
|
let blob = vec[3]!.blob { pointer in
|
||||||
Array(pointer)
|
Array(pointer)
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(blob?.count, 1)
|
#expect(blob?.count == 1)
|
||||||
XCTAssertEqual(blob?[0], 77)
|
#expect(blob?[0] == 77)
|
||||||
XCTAssertEqual(vec[4]?.type, .bool)
|
#expect(vec[4]?.type == .bool)
|
||||||
XCTAssertEqual(vec[4]?.bool, false)
|
#expect(vec[4]?.bool == false)
|
||||||
XCTAssertEqual(vec[5]?.double, 4.0) // Shared with vec[2]
|
#expect(vec[5]?.double == 4.0) // Shared with vec[2]
|
||||||
|
|
||||||
let barVec = map["bar"]!.typedVector!
|
let barVec = map["bar"]!.typedVector!
|
||||||
XCTAssertEqual(barVec.count, 3)
|
#expect(barVec.count == 3)
|
||||||
XCTAssertEqual(barVec[2]?.int, 3)
|
#expect(barVec[2]?.int == 3)
|
||||||
XCTAssertEqual(barVec[2]?.asInt(), UInt8(3))
|
#expect(barVec[2]?.asInt() == UInt8(3))
|
||||||
|
|
||||||
let fixedVec = map["bar3"]!.fixedTypedVector!
|
let fixedVec = map["bar3"]!.fixedTypedVector!
|
||||||
XCTAssertEqual(fixedVec.count, 3)
|
#expect(fixedVec.count == 3)
|
||||||
XCTAssertEqual(fixedVec[2]?.int, 3)
|
#expect(fixedVec[2]?.int == 3)
|
||||||
XCTAssertEqual(fixedVec[2]?.asInt(), UInt8(3))
|
#expect(fixedVec[2]?.asInt() == UInt8(3))
|
||||||
XCTAssertEqual(map["bool"]?.bool, true)
|
#expect(map["bool"]?.bool == true)
|
||||||
|
|
||||||
let boolsVector = map["bools"]!.typedVector!
|
let boolsVector = map["bools"]!.typedVector!
|
||||||
XCTAssertEqual(boolsVector.type, .bool)
|
#expect(boolsVector.type == .bool)
|
||||||
XCTAssertEqual(boolsVector[0]?.bool, true)
|
#expect(boolsVector[0]?.bool == true)
|
||||||
XCTAssertEqual(boolsVector[1]?.bool, false)
|
#expect(boolsVector[1]?.bool == false)
|
||||||
|
|
||||||
let bools = [true, false, true, false]
|
let bools = [true, false, true, false]
|
||||||
boolsVector.withUnsafeRawBufferPointer { buff in
|
boolsVector.withUnsafeRawBufferPointer { buff in
|
||||||
for i in 0..<boolsVector.count {
|
for i in 0..<boolsVector.count {
|
||||||
XCTAssertEqual(buff.load(fromByteOffset: i, as: Bool.self), bools[i])
|
#expect(buff.load(fromByteOffset: i, as: Bool.self) == bools[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XCTAssertEqual(map["foo"]?.double, 100)
|
#expect(map["foo"]?.double == 100)
|
||||||
XCTAssertNil(map["unknown"])
|
#expect(map["unknown"] == nil)
|
||||||
let mymap = map["mymap"]?.map
|
let mymap = map["mymap"]?.map
|
||||||
|
|
||||||
// Check if both addresses used are the same for keys and strings
|
// Check if both addresses used are the same for keys and strings
|
||||||
XCTAssertEqual(mymap?.keys[0]?.cString, map.keys[4]?.cString)
|
#expect(mymap?.keys[0]?.cString == map.keys[4]?.cString)
|
||||||
map.keys[4]?.withUnsafeRawPointer { pointer in
|
map.keys[4]?.withUnsafeRawPointer { pointer in
|
||||||
mymap?.keys[0]?.withUnsafeRawPointer { mymapPointer in
|
mymap?.keys[0]?.withUnsafeRawPointer { mymapPointer in
|
||||||
XCTAssertEqual(pointer, mymapPointer)
|
#expect(pointer == mymapPointer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(mymap?.values[0]?.cString, vec[1]?.cString)
|
#expect(mymap?.values[0]?.cString == vec[1]?.cString)
|
||||||
vec[1]?.withUnsafeRawPointer { pointer in
|
vec[1]?.withUnsafeRawPointer { pointer in
|
||||||
mymap?.values[0]?.withUnsafeRawPointer { mymapPointer in
|
mymap?.values[0]?.withUnsafeRawPointer { mymapPointer in
|
||||||
XCTAssertEqual(pointer, mymapPointer)
|
#expect(pointer == mymapPointer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,7 +131,7 @@ final class FlexBuffersReaderTests: XCTestCase {
|
|||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
// Gets the current path of this test file then
|
// Gets the current path of this test file then
|
||||||
// strips out the nested directories.
|
// strips out the nested directories.
|
||||||
let filePath = URL(filePath: #file)
|
let filePath = URL(filePath: #filePath)
|
||||||
.deletingLastPathComponent()
|
.deletingLastPathComponent()
|
||||||
.deletingLastPathComponent()
|
.deletingLastPathComponent()
|
||||||
.deletingLastPathComponent()
|
.deletingLastPathComponent()
|
||||||
@@ -136,5 +140,4 @@ final class FlexBuffersReaderTests: XCTestCase {
|
|||||||
return FileManager.default.currentDirectoryPath
|
return FileManager.default.currentDirectoryPath
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
|
|
||||||
import Common
|
import Common
|
||||||
import FlexBuffers
|
import FlexBuffers
|
||||||
import XCTest
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
|
||||||
final class FlexBuffersStringTests: XCTestCase {
|
struct FlexBuffersStringTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
func testEncodingUnicodeString() {
|
func testEncodingUnicodeString() {
|
||||||
let text = "プ画をみて✋"
|
let text = "プ画をみて✋"
|
||||||
|
|
||||||
@@ -38,6 +40,6 @@ final class FlexBuffersStringTests: XCTestCase {
|
|||||||
return String(data: data, encoding: .unicode)
|
return String(data: data, encoding: .unicode)
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(builtString, text)
|
#expect(builtString == text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
import Common
|
import Common
|
||||||
import FlexBuffers
|
import FlexBuffers
|
||||||
import XCTest
|
import Testing
|
||||||
|
|
||||||
final class FlexBuffersWriterTests: XCTestCase {
|
struct FlexBuffersWriterTests {
|
||||||
|
@Test
|
||||||
func testDeallocation() {
|
func testDeallocation() {
|
||||||
let buf: ByteBuffer = {
|
let buf: ByteBuffer = {
|
||||||
var fbx = FlexBuffersWriter()
|
var fbx = FlexBuffersWriter()
|
||||||
@@ -28,12 +29,13 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[5, 72, 101, 108, 108, 111, 0, 6, 20, 1])
|
[5, 72, 101, 108, 108, 111, 0, 6, 20, 1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testAddingVectorOfScalars() {
|
func testAddingVectorOfScalars() {
|
||||||
var fbx = FlexBuffersWriter()
|
var fbx = FlexBuffersWriter()
|
||||||
fbx.vector {
|
fbx.vector {
|
||||||
@@ -45,8 +47,8 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
|
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[
|
[
|
||||||
10, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0,
|
10, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0,
|
||||||
0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 20, 0, 0, 0, 1, 41, 46, 2, 40, 1,
|
0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 20, 0, 0, 0, 1, 41, 46, 2, 40, 1,
|
||||||
@@ -55,6 +57,7 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testAddingVectorOfUnsignedScalars() {
|
func testAddingVectorOfUnsignedScalars() {
|
||||||
var fbx = FlexBuffersWriter()
|
var fbx = FlexBuffersWriter()
|
||||||
fbx.vector {
|
fbx.vector {
|
||||||
@@ -66,8 +69,8 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
|
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[
|
[
|
||||||
10, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
|
10, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
|
||||||
0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
|
0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
|
||||||
@@ -78,6 +81,7 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testAddingVectorOfBools() {
|
func testAddingVectorOfBools() {
|
||||||
var fbx = FlexBuffersWriter()
|
var fbx = FlexBuffersWriter()
|
||||||
fbx.vector {
|
fbx.vector {
|
||||||
@@ -89,13 +93,14 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
|
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[4, 1, 0, 1, 0, 1, 5, 144, 2, 40, 1])
|
[4, 1, 0, 1, 0, 1, 5, 144, 2, 40, 1])
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testSortingWithinMap() {
|
func testSortingWithinMap() {
|
||||||
var fbx = FlexBuffersWriter()
|
var fbx = FlexBuffersWriter()
|
||||||
fbx.map {
|
fbx.map {
|
||||||
@@ -106,8 +111,8 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
let buf: ByteBuffer = fbx.sizedByteBuffer
|
let buf: ByteBuffer = fbx.sizedByteBuffer
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[
|
[
|
||||||
98, 111, 111, 108, 50, 0, 98, 111, 111, 108, 49, 0, 2, 7, 14, 2, 1, 2, 1, 0, 104, 104, 4,
|
98, 111, 111, 108, 50, 0, 98, 111, 111, 108, 49, 0, 2, 7, 14, 2, 1, 2, 1, 0, 104, 104, 4,
|
||||||
36, 1,
|
36, 1,
|
||||||
@@ -117,6 +122,7 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testSharingKeyWithinMap() {
|
func testSharingKeyWithinMap() {
|
||||||
var fbx = FlexBuffersWriter(initialSize: 1000, flags: .shareKeysAndStrings)
|
var fbx = FlexBuffersWriter(initialSize: 1000, flags: .shareKeysAndStrings)
|
||||||
fbx.map {
|
fbx.map {
|
||||||
@@ -128,8 +134,8 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
let buf: ByteBuffer = fbx.sizedByteBuffer
|
let buf: ByteBuffer = fbx.sizedByteBuffer
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[
|
[
|
||||||
119, 101, 108, 99, 111, 109, 101, 0, 7, 119, 101, 108, 99, 111, 109, 101, 0, 3, 18, 19,
|
119, 101, 108, 99, 111, 109, 101, 0, 7, 119, 101, 108, 99, 111, 109, 101, 0, 3, 18, 19,
|
||||||
20, 3, 1, 3, 15, 16, 17, 20, 20, 20, 6, 36, 1,
|
20, 3, 1, 3, 15, 16, 17, 20, 20, 20, 6, 36, 1,
|
||||||
@@ -139,19 +145,21 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testNestingVectorInMap() {
|
func testNestingVectorInMap() {
|
||||||
let buf: ByteBuffer = createSizedBuffer()
|
let buf: ByteBuffer = createSizedBuffer()
|
||||||
|
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
flexbufferGolden
|
flexbufferGolden
|
||||||
)
|
)
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testAddingNil() {
|
func testAddingNil() {
|
||||||
var fbx = FlexBuffersWriter(
|
var fbx = FlexBuffersWriter(
|
||||||
initialSize: 8,
|
initialSize: 8,
|
||||||
@@ -165,14 +173,15 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
let buf: ByteBuffer = fbx.sizedByteBuffer
|
let buf: ByteBuffer = fbx.sizedByteBuffer
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[118, 0, 1, 3, 1, 1, 1, 0, 0, 2, 36, 1]
|
[118, 0, 1, 3, 1, 1, 1, 0, 0, 2, 36, 1]
|
||||||
)
|
)
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testAddingManually() {
|
func testAddingManually() {
|
||||||
var fbx = FlexBuffersWriter(
|
var fbx = FlexBuffersWriter(
|
||||||
initialSize: 8,
|
initialSize: 8,
|
||||||
@@ -209,14 +218,15 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
let buf: ByteBuffer = fbx.sizedByteBuffer
|
let buf: ByteBuffer = fbx.sizedByteBuffer
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
flexbufferGolden
|
flexbufferGolden
|
||||||
)
|
)
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testEncodingAllTypes() {
|
func testEncodingAllTypes() {
|
||||||
var fbx = FlexBuffersWriter()
|
var fbx = FlexBuffersWriter()
|
||||||
fbx.vector {
|
fbx.vector {
|
||||||
@@ -240,8 +250,8 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
|
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
allTypesGolden)
|
allTypesGolden)
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import XCTest
|
import Testing
|
||||||
|
|
||||||
@testable import FlatBuffers
|
@testable import FlatBuffers
|
||||||
|
|
||||||
@@ -24,8 +24,9 @@ typealias Monster = MyGame_Example_Monster
|
|||||||
typealias Vec3 = MyGame_Example_Vec3
|
typealias Vec3 = MyGame_Example_Vec3
|
||||||
typealias Stat = MyGame_Example_Stat
|
typealias Stat = MyGame_Example_Stat
|
||||||
|
|
||||||
class FlatBuffersMonsterWriterTests: XCTestCase {
|
struct FlatBuffersMonsterWriterTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
func testData() {
|
func testData() {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
let data: [UInt8] = [
|
let data: [UInt8] = [
|
||||||
@@ -47,11 +48,12 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
readVerifiedMonster(fb: _data)
|
readVerifiedMonster(fb: _data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMonster() {
|
func testCreateMonster() {
|
||||||
let bytes = createMonster(withPrefix: false)
|
let bytes = createMonster(withPrefix: false)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
bytes.sizedByteArray,
|
bytes.sizedByteArray ==
|
||||||
[
|
[
|
||||||
48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28,
|
48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28,
|
||||||
0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0,
|
0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0,
|
||||||
@@ -75,11 +77,12 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
readMonster(monster: monster)
|
readMonster(monster: monster)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMonsterResizedBuffer() {
|
func testCreateMonsterResizedBuffer() {
|
||||||
let bytes = createMonster(withPrefix: false)
|
let bytes = createMonster(withPrefix: false)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
bytes.sizedByteArray,
|
bytes.sizedByteArray ==
|
||||||
[
|
[
|
||||||
48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28,
|
48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28,
|
||||||
0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0,
|
0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0,
|
||||||
@@ -98,11 +101,12 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
readVerifiedMonster(fb: bytes.sizedBuffer)
|
readVerifiedMonster(fb: bytes.sizedBuffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMonsterPrefixed() {
|
func testCreateMonsterPrefixed() {
|
||||||
let bytes = createMonster(withPrefix: true)
|
let bytes = createMonster(withPrefix: true)
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
bytes.sizedByteArray,
|
bytes.sizedByteArray ==
|
||||||
[
|
[
|
||||||
44, 1, 0, 0, 44, 0, 0, 0, 77, 79, 78, 83, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28,
|
44, 1, 0, 0, 44, 0, 0, 0, 77, 79, 78, 83, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28,
|
||||||
0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0,
|
0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0,
|
||||||
@@ -123,6 +127,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
readMonster(monster: getPrefixedSizeRoot(byteBuffer: &buffer))
|
readMonster(monster: getPrefixedSizeRoot(byteBuffer: &buffer))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMonsterUsingCreateMonsterMethodWithNilPos() {
|
func testCreateMonsterUsingCreateMonsterMethodWithNilPos() {
|
||||||
var fbb = FlatBufferBuilder(initialSize: 1)
|
var fbb = FlatBufferBuilder(initialSize: 1)
|
||||||
let name = fbb.create(string: "Frodo")
|
let name = fbb.create(string: "Frodo")
|
||||||
@@ -132,10 +137,11 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
fbb.finish(offset: root)
|
fbb.finish(offset: root)
|
||||||
var buffer = fbb.sizedBuffer
|
var buffer = fbb.sizedBuffer
|
||||||
let newMonster: Monster = getRoot(byteBuffer: &buffer)
|
let newMonster: Monster = getRoot(byteBuffer: &buffer)
|
||||||
XCTAssertNil(newMonster.pos)
|
#expect(newMonster.pos == nil)
|
||||||
XCTAssertEqual(newMonster.name, "Frodo")
|
#expect(newMonster.name == "Frodo")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testCreateMonsterUsingCreateMonsterMethodWithPosX() {
|
func testCreateMonsterUsingCreateMonsterMethodWithPosX() {
|
||||||
var fbb = FlatBufferBuilder(initialSize: 1)
|
var fbb = FlatBufferBuilder(initialSize: 1)
|
||||||
let name = fbb.create(string: "Barney")
|
let name = fbb.create(string: "Barney")
|
||||||
@@ -155,10 +161,11 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
|
|
||||||
var buffer = fbb.sizedBuffer
|
var buffer = fbb.sizedBuffer
|
||||||
let newMonster: Monster = getRoot(byteBuffer: &buffer)
|
let newMonster: Monster = getRoot(byteBuffer: &buffer)
|
||||||
XCTAssertEqual(newMonster.pos!.x, 10)
|
#expect(newMonster.pos!.x == 10)
|
||||||
XCTAssertEqual(newMonster.name, "Barney")
|
#expect(newMonster.name == "Barney")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadMonsterFromUnsafePointerWithoutCopying() {
|
func testReadMonsterFromUnsafePointerWithoutCopying() {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
var array: [UInt8] = [
|
var array: [UInt8] = [
|
||||||
@@ -190,6 +197,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
readObjectApi(monster: unpacked)
|
readObjectApi(monster: unpacked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testArrayOfBools() {
|
func testArrayOfBools() {
|
||||||
let boolArray = [false, true, false, true, false, true, false]
|
let boolArray = [false, true, false, true, false, true, false]
|
||||||
var fbb = FlatBufferBuilder(initialSize: 1)
|
var fbb = FlatBufferBuilder(initialSize: 1)
|
||||||
@@ -205,37 +213,41 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
let monster: Monster = getRoot(byteBuffer: &buffer)
|
let monster: Monster = getRoot(byteBuffer: &buffer)
|
||||||
let values = monster.testarrayofbools
|
let values = monster.testarrayofbools
|
||||||
|
|
||||||
XCTAssertEqual(boolArray.count, values.count)
|
#expect(boolArray.count == values.count)
|
||||||
|
|
||||||
for (index, bool) in monster.testarrayofbools.enumerated() {
|
for (index, bool) in monster.testarrayofbools.enumerated() {
|
||||||
XCTAssertEqual(bool, boolArray[index])
|
#expect(bool == boolArray[index])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readVerifiedMonster(fb: ByteBuffer) {
|
func readVerifiedMonster(fb: ByteBuffer) {
|
||||||
var byteBuffer = fb
|
var byteBuffer = fb
|
||||||
XCTAssertNoThrow(
|
do {
|
||||||
try readMonster(
|
try readMonster(
|
||||||
monster: getCheckedRoot(
|
monster: getCheckedRoot(
|
||||||
byteBuffer: &byteBuffer) as MyGame_Example_Monster))
|
byteBuffer: &byteBuffer) as MyGame_Example_Monster)
|
||||||
|
} catch {
|
||||||
|
Issue.record(error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(.bug("https://github.com/google/flatbuffers/issues/8133"))
|
||||||
func testUnalignedRead() {
|
func testUnalignedRead() {
|
||||||
// Aligned read
|
// Aligned read
|
||||||
let fbb = createMonster(withPrefix: false)
|
let fbb = createMonster(withPrefix: false)
|
||||||
let testAligned: () -> Bool = {
|
let testAligned: () -> Bool = {
|
||||||
var buffer = fbb.sizedBuffer
|
var buffer = fbb.sizedBuffer
|
||||||
var monster: Monster = getRoot(byteBuffer: &buffer)
|
var monster: Monster = getRoot(byteBuffer: &buffer)
|
||||||
self.readFlatbufferMonster(monster: &monster)
|
readFlatbufferMonster(monster: &monster)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
XCTAssertEqual(testAligned(), true)
|
#expect(testAligned() == true)
|
||||||
let testUnaligned: () -> Bool = {
|
let testUnaligned: () -> Bool = {
|
||||||
var bytes: [UInt8] = [0x00]
|
var bytes: [UInt8] = [0x00]
|
||||||
bytes.append(contentsOf: fbb.sizedByteArray)
|
bytes.append(contentsOf: fbb.sizedByteArray)
|
||||||
return bytes.withUnsafeMutableBytes { ptr in
|
return bytes.withUnsafeMutableBytes { ptr in
|
||||||
guard var baseAddress = ptr.baseAddress else {
|
guard var baseAddress = ptr.baseAddress else {
|
||||||
XCTFail("Base pointer is not defined")
|
Issue.record("Base pointer is not defined")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
baseAddress = baseAddress.advanced(by: 1)
|
baseAddress = baseAddress.advanced(by: 1)
|
||||||
@@ -244,13 +256,14 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
assumingMemoryBound: unlignedPtr,
|
assumingMemoryBound: unlignedPtr,
|
||||||
capacity: ptr.count - 1)
|
capacity: ptr.count - 1)
|
||||||
var monster: Monster = getRoot(byteBuffer: &bytes)
|
var monster: Monster = getRoot(byteBuffer: &bytes)
|
||||||
self.readFlatbufferMonster(monster: &monster)
|
readFlatbufferMonster(monster: &monster)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XCTAssertEqual(testUnaligned(), true)
|
#expect(testUnaligned() == true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadingRemovedSizeUnalignedBuffer() {
|
func testReadingRemovedSizeUnalignedBuffer() {
|
||||||
// Aligned read
|
// Aligned read
|
||||||
let fbb = createMonster(withPrefix: true)
|
let fbb = createMonster(withPrefix: true)
|
||||||
@@ -259,7 +272,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
bytes.append(contentsOf: fbb.sizedByteArray)
|
bytes.append(contentsOf: fbb.sizedByteArray)
|
||||||
return bytes.withUnsafeMutableBytes { ptr in
|
return bytes.withUnsafeMutableBytes { ptr in
|
||||||
guard var baseAddress = ptr.baseAddress else {
|
guard var baseAddress = ptr.baseAddress else {
|
||||||
XCTFail("Base pointer is not defined")
|
Issue.record("Base pointer is not defined")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
baseAddress = baseAddress.advanced(by: 1)
|
baseAddress = baseAddress.advanced(by: 1)
|
||||||
@@ -269,13 +282,14 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
capacity: ptr.count - 1)
|
capacity: ptr.count - 1)
|
||||||
var newBuf = FlatBuffersUtils.removeSizePrefix(bb: bytes)
|
var newBuf = FlatBuffersUtils.removeSizePrefix(bb: bytes)
|
||||||
var monster: Monster = getRoot(byteBuffer: &newBuf)
|
var monster: Monster = getRoot(byteBuffer: &newBuf)
|
||||||
self.readFlatbufferMonster(monster: &monster)
|
readFlatbufferMonster(monster: &monster)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XCTAssertEqual(testUnaligned(), true)
|
#expect(testUnaligned() == true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testForceRetainedObject() {
|
func testForceRetainedObject() {
|
||||||
let byteBuffer = {
|
let byteBuffer = {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
@@ -381,95 +395,95 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
var fb = fb
|
var fb = fb
|
||||||
|
|
||||||
let monster: Monster = getRoot(byteBuffer: &fb)
|
let monster: Monster = getRoot(byteBuffer: &fb)
|
||||||
XCTAssertFalse(monster.mutate(mana: 10))
|
#expect(monster.mutate(mana: 10) == false)
|
||||||
XCTAssertEqual(monster.testarrayoftables[0].name, "Barney")
|
#expect(monster.testarrayoftables[0].name == "Barney")
|
||||||
XCTAssertEqual(monster.testarrayoftables[1].name, "Frodo")
|
#expect(monster.testarrayoftables[1].name == "Frodo")
|
||||||
XCTAssertEqual(monster.testarrayoftables[2].name, "Wilma")
|
#expect(monster.testarrayoftables[2].name == "Wilma")
|
||||||
|
|
||||||
// Example of searching for a table by the key
|
// Example of searching for a table by the key
|
||||||
XCTAssertNotNil(monster.testarrayoftablesBy(key: "Frodo"))
|
#expect(monster.testarrayoftablesBy(key: "Frodo") != nil)
|
||||||
XCTAssertNotNil(monster.testarrayoftablesBy(key: "Barney"))
|
#expect(monster.testarrayoftablesBy(key: "Barney") != nil)
|
||||||
XCTAssertNotNil(monster.testarrayoftablesBy(key: "Wilma"))
|
#expect(monster.testarrayoftablesBy(key: "Wilma") != nil)
|
||||||
|
|
||||||
XCTAssertEqual(monster.testType, .monster)
|
#expect(monster.testType == .monster)
|
||||||
|
|
||||||
XCTAssertEqual(monster.mutate(inventory: 1, at: 0), true)
|
#expect(monster.mutate(inventory: 1, at: 0) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 2, at: 1), true)
|
#expect(monster.mutate(inventory: 2, at: 1) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 3, at: 2), true)
|
#expect(monster.mutate(inventory: 3, at: 2) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 4, at: 3), true)
|
#expect(monster.mutate(inventory: 4, at: 3) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 5, at: 4), true)
|
#expect(monster.mutate(inventory: 5, at: 4) == true)
|
||||||
|
|
||||||
for i in 0..<monster.inventory.count {
|
for i in 0..<monster.inventory.count {
|
||||||
XCTAssertEqual(monster.inventory[i], Byte(i + 1))
|
#expect(monster.inventory[i] == Byte(i + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(monster.mutate(inventory: 0, at: 0), true)
|
#expect(monster.mutate(inventory: 0, at: 0) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 1, at: 1), true)
|
#expect(monster.mutate(inventory: 1, at: 1) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 2, at: 2), true)
|
#expect(monster.mutate(inventory: 2, at: 2) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 3, at: 3), true)
|
#expect(monster.mutate(inventory: 3, at: 3) == true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 4, at: 4), true)
|
#expect(monster.mutate(inventory: 4, at: 4) == true)
|
||||||
|
|
||||||
let vec = monster.mutablePos
|
let vec = monster.mutablePos
|
||||||
XCTAssertEqual(vec?.x, 1)
|
#expect(vec?.x == 1)
|
||||||
XCTAssertTrue(vec?.mutate(x: 55.0) ?? false)
|
#expect(vec?.mutate(x: 55.0) == true)
|
||||||
XCTAssertTrue(vec?.mutate(test1: 55) ?? false)
|
#expect(vec?.mutate(test1: 55) == true)
|
||||||
XCTAssertEqual(vec?.x, 55.0)
|
#expect(vec?.x == 55.0)
|
||||||
XCTAssertEqual(vec?.test1, 55.0)
|
#expect(vec?.test1 == 55.0)
|
||||||
XCTAssertTrue(vec?.mutate(x: 1) ?? false)
|
#expect(vec?.mutate(x: 1) == true)
|
||||||
XCTAssertEqual(vec?.x, 1)
|
#expect(vec?.x == 1)
|
||||||
XCTAssertTrue(vec?.mutate(test1: 3) ?? false)
|
#expect(vec?.mutate(test1: 3) == true)
|
||||||
|
|
||||||
let mutableTest4 = monster.mutableTest4
|
let mutableTest4 = monster.mutableTest4
|
||||||
let orignalValues = mutableTest4[0].a
|
let orignalValues = mutableTest4[0].a
|
||||||
XCTAssertEqual(mutableTest4[0].mutate(a: 100), true)
|
#expect(mutableTest4[0].mutate(a: 100) == true)
|
||||||
XCTAssertNotEqual(monster.test4[0].a, orignalValues)
|
#expect(monster.test4[0].a != orignalValues)
|
||||||
XCTAssertEqual(monster.test4[0].a, 100)
|
#expect(monster.test4[0].a == 100)
|
||||||
XCTAssertEqual(mutableTest4[0].mutate(a: orignalValues), true)
|
#expect(mutableTest4[0].mutate(a: orignalValues) == true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readFlatbufferMonster(monster: inout MyGame_Example_Monster) {
|
func readFlatbufferMonster(monster: inout MyGame_Example_Monster) {
|
||||||
XCTAssertEqual(monster.hp, 80)
|
#expect(monster.hp == 80)
|
||||||
XCTAssertEqual(monster.mana, 150)
|
#expect(monster.mana == 150)
|
||||||
XCTAssertEqual(monster.name, "MyMonster")
|
#expect(monster.name == "MyMonster")
|
||||||
let pos = monster.pos
|
let pos = monster.pos
|
||||||
XCTAssertEqual(pos?.x, 1)
|
#expect(pos?.x == 1)
|
||||||
XCTAssertEqual(pos?.y, 2)
|
#expect(pos?.y == 2)
|
||||||
XCTAssertEqual(pos?.z, 3)
|
#expect(pos?.z == 3)
|
||||||
XCTAssertEqual(pos?.test1, 3)
|
#expect(pos?.test1 == 3)
|
||||||
XCTAssertEqual(pos?.test2, .green)
|
#expect(pos?.test2 == .green)
|
||||||
let test = pos?.test3
|
let test = pos?.test3
|
||||||
XCTAssertEqual(test?.a, 5)
|
#expect(test?.a == 5)
|
||||||
XCTAssertEqual(test?.b, 6)
|
#expect(test?.b == 6)
|
||||||
XCTAssertEqual(monster.testType, .monster)
|
#expect(monster.testType == .monster)
|
||||||
let monster2 = monster.test(type: Monster.self)
|
let monster2 = monster.test(type: Monster.self)
|
||||||
XCTAssertEqual(monster2?.name, "Fred")
|
#expect(monster2?.name == "Fred")
|
||||||
|
|
||||||
XCTAssertEqual(monster.mutate(mana: 10), false)
|
#expect(monster.mutate(mana: 10) == false)
|
||||||
|
|
||||||
XCTAssertEqual(monster.mana, 150)
|
#expect(monster.mana == 150)
|
||||||
XCTAssertEqual(monster.inventory.count, 5)
|
#expect(monster.inventory.count == 5)
|
||||||
var sum: Byte = 0
|
var sum: Byte = 0
|
||||||
for inventory in monster.inventory {
|
for inventory in monster.inventory {
|
||||||
sum += inventory
|
sum += inventory
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum, 10)
|
#expect(sum == 10)
|
||||||
|
|
||||||
monster.withUnsafePointerToInventory { ptr, count in
|
monster.withUnsafePointerToInventory { ptr, count in
|
||||||
var sum: UInt8 = 0
|
var sum: UInt8 = 0
|
||||||
for pointee in ptr.startIndex..<ptr.endIndex {
|
for pointee in ptr.startIndex..<ptr.endIndex {
|
||||||
sum += ptr[pointee]
|
sum += ptr[pointee]
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum, 10)
|
#expect(sum == 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(monster.test4.count, 2)
|
#expect(monster.test4.count == 2)
|
||||||
|
|
||||||
let test4 = monster.test4
|
let test4 = monster.test4
|
||||||
var sum0 = 0
|
var sum0 = 0
|
||||||
for test0 in test4 {
|
for test0 in test4 {
|
||||||
sum0 += Int(test0.a) + Int(test0.b)
|
sum0 += Int(test0.a) + Int(test0.b)
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum0, 100)
|
#expect(sum0 == 100)
|
||||||
|
|
||||||
monster.withUnsafePointerToTest4 { ptr, count in
|
monster.withUnsafePointerToTest4 { ptr, count in
|
||||||
guard let ptr = ptr.baseAddress else { return }
|
guard let ptr = ptr.baseAddress else { return }
|
||||||
@@ -485,7 +499,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
pointerSum += Int(bindedMemory[pointee].a) +
|
pointerSum += Int(bindedMemory[pointee].a) +
|
||||||
Int(bindedMemory[pointee].b)
|
Int(bindedMemory[pointee].b)
|
||||||
}
|
}
|
||||||
XCTAssertEqual(pointerSum, 100)
|
#expect(pointerSum == 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
let mutableTest4 = monster.mutableTest4
|
let mutableTest4 = monster.mutableTest4
|
||||||
@@ -493,87 +507,84 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
for test0 in mutableTest4 {
|
for test0 in mutableTest4 {
|
||||||
sum2 += Int(test0.a) + Int(test0.b)
|
sum2 += Int(test0.a) + Int(test0.b)
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum2, 100)
|
#expect(sum2 == 100)
|
||||||
|
|
||||||
let stringArray = monster.testarrayofstring
|
let stringArray = monster.testarrayofstring
|
||||||
XCTAssertEqual(stringArray.count, 2)
|
#expect(stringArray.count == 2)
|
||||||
XCTAssertEqual(stringArray[0], "test1")
|
#expect(stringArray[0] == "test1")
|
||||||
XCTAssertEqual(stringArray[1], "test2")
|
#expect(stringArray[1] == "test2")
|
||||||
XCTAssertEqual(monster.testbool, true)
|
#expect(monster.testbool == true)
|
||||||
|
|
||||||
let array = monster.nameSegmentArray
|
let array = monster.nameSegmentArray
|
||||||
XCTAssertEqual(String(bytes: array ?? [], encoding: .utf8), "MyMonster")
|
#expect(String(bytes: array ?? [], encoding: .utf8) == "MyMonster")
|
||||||
|
|
||||||
if 0 == monster.testarrayofbools.count {
|
if 0 == monster.testarrayofbools.count {
|
||||||
XCTAssertEqual(monster.testarrayofbools.isEmpty, true)
|
#expect(monster.testarrayofbools.isEmpty == true)
|
||||||
} else {
|
} else {
|
||||||
XCTAssertEqual(monster.testarrayofbools.isEmpty, false)
|
#expect(monster.testarrayofbools.isEmpty == false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readObjectApi(monster: MyGame_Example_MonsterT) {
|
func readObjectApi(monster: MyGame_Example_MonsterT) {
|
||||||
XCTAssertEqual(monster.hp, 80)
|
#expect(monster.hp == 80)
|
||||||
XCTAssertEqual(monster.mana, 150)
|
#expect(monster.mana == 150)
|
||||||
XCTAssertEqual(monster.name, "MyMonster")
|
#expect(monster.name == "MyMonster")
|
||||||
let pos = monster.pos
|
let pos = monster.pos
|
||||||
XCTAssertEqual(pos?.x, 1)
|
#expect(pos?.x == 1)
|
||||||
XCTAssertEqual(pos?.y, 2)
|
#expect(pos?.y == 2)
|
||||||
XCTAssertEqual(pos?.z, 3)
|
#expect(pos?.z == 3)
|
||||||
XCTAssertEqual(pos?.test1, 3)
|
#expect(pos?.test1 == 3)
|
||||||
XCTAssertEqual(pos?.test2, .green)
|
#expect(pos?.test2 == .green)
|
||||||
let test = pos?.test3
|
let test = pos?.test3
|
||||||
XCTAssertEqual(test?.a, 5)
|
#expect(test?.a == 5)
|
||||||
XCTAssertEqual(test?.b, 6)
|
#expect(test?.b == 6)
|
||||||
let monster2 = monster.test?.value as? MyGame_Example_MonsterT
|
let monster2 = monster.test?.value as? MyGame_Example_MonsterT
|
||||||
XCTAssertEqual(monster2?.name, "Fred")
|
#expect(monster2?.name == "Fred")
|
||||||
XCTAssertEqual(monster.mana, 150)
|
#expect(monster.mana == 150)
|
||||||
monster.mana = 10
|
monster.mana = 10
|
||||||
XCTAssertEqual(monster.mana, 10)
|
#expect(monster.mana == 10)
|
||||||
monster.mana = 150
|
monster.mana = 150
|
||||||
XCTAssertEqual(monster.mana, 150)
|
#expect(monster.mana == 150)
|
||||||
|
|
||||||
XCTAssertEqual(monster.inventory.count, 5)
|
#expect(monster.inventory.count == 5)
|
||||||
var sum: Byte = 0
|
var sum: Byte = 0
|
||||||
for i in monster.inventory {
|
for i in monster.inventory {
|
||||||
sum += i
|
sum += i
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum, 10)
|
#expect(sum == 10)
|
||||||
XCTAssertEqual(monster.test4.count, 2)
|
#expect(monster.test4.count == 2)
|
||||||
var sum0 = 0
|
var sum0 = 0
|
||||||
for test in monster.test4 {
|
for test in monster.test4 {
|
||||||
sum0 += Int(test.a) + Int(test.b)
|
sum0 += Int(test.a) + Int(test.b)
|
||||||
}
|
}
|
||||||
XCTAssertEqual(sum0, 100)
|
#expect(sum0 == 100)
|
||||||
XCTAssertEqual(monster.testbool, true)
|
#expect(monster.testbool == true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEncoding() {
|
@Test
|
||||||
|
func testEncoding() throws {
|
||||||
let fbb = createMonster(withPrefix: false)
|
let fbb = createMonster(withPrefix: false)
|
||||||
var sizedBuffer = fbb.sizedBuffer
|
var sizedBuffer = fbb.sizedBuffer
|
||||||
do {
|
struct Test: Decodable {
|
||||||
struct Test: Decodable {
|
struct Pos: Decodable {
|
||||||
struct Pos: Decodable {
|
let x, y, z: Int
|
||||||
let x, y, z: Int
|
|
||||||
}
|
|
||||||
let hp: Int
|
|
||||||
let inventory: [UInt8]
|
|
||||||
let name: String
|
|
||||||
let pos: Pos
|
|
||||||
}
|
}
|
||||||
let reader: Monster = try getCheckedRoot(byteBuffer: &sizedBuffer)
|
let hp: Int
|
||||||
let encoder = JSONEncoder()
|
let inventory: [UInt8]
|
||||||
encoder.keyEncodingStrategy = .convertToSnakeCase
|
let name: String
|
||||||
let data = try encoder.encode(reader)
|
let pos: Pos
|
||||||
let decoder = JSONDecoder()
|
|
||||||
decoder.keyDecodingStrategy = .convertFromSnakeCase
|
|
||||||
let value = try decoder.decode(Test.self, from: data)
|
|
||||||
XCTAssertEqual(value.name, "MyMonster")
|
|
||||||
XCTAssertEqual(value.pos.x, 1)
|
|
||||||
XCTAssertEqual(value.pos.y, 2)
|
|
||||||
XCTAssertEqual(value.pos.z, 3)
|
|
||||||
} catch {
|
|
||||||
XCTFail(error.localizedDescription)
|
|
||||||
}
|
}
|
||||||
|
let reader: Monster = try getCheckedRoot(byteBuffer: &sizedBuffer)
|
||||||
|
let encoder = JSONEncoder()
|
||||||
|
encoder.keyEncodingStrategy = .convertToSnakeCase
|
||||||
|
let data = try encoder.encode(reader)
|
||||||
|
let decoder = JSONDecoder()
|
||||||
|
decoder.keyDecodingStrategy = .convertFromSnakeCase
|
||||||
|
let value = try decoder.decode(Test.self, from: data)
|
||||||
|
#expect(value.name == "MyMonster")
|
||||||
|
#expect(value.pos.x == 1)
|
||||||
|
#expect(value.pos.y == 2)
|
||||||
|
#expect(value.pos.z == 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonData: String {
|
var jsonData: String {
|
||||||
|
|||||||
@@ -662,7 +662,7 @@ public struct MyGame_Example_StructOfStructsOfStructs_Mutable: FlatBufferStruct,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct MyGame_InParentNamespace: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_InParentNamespace: 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 }
|
||||||
@@ -712,7 +712,7 @@ public class MyGame_InParentNamespaceT: NativeObject {
|
|||||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_InParentNamespace.self) }
|
public func serialize() -> ByteBuffer { return serialize(type: MyGame_InParentNamespace.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct MyGame_Example2_Monster: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Example2_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 }
|
||||||
@@ -762,7 +762,7 @@ public class MyGame_Example2_MonsterT: NativeObject {
|
|||||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example2_Monster.self) }
|
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example2_Monster.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
internal struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
internal struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
||||||
internal var __buffer: ByteBuffer! { return _accessor.bb }
|
internal var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
@@ -840,7 +840,7 @@ internal class MyGame_Example_TestSimpleTableWithEnumT: NativeObject {
|
|||||||
internal func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_TestSimpleTableWithEnum.self) }
|
internal func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_TestSimpleTableWithEnum.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct MyGame_Example_Stat: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Example_Stat: 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 }
|
||||||
@@ -976,7 +976,7 @@ public class MyGame_Example_StatT: NativeObject {
|
|||||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Stat.self) }
|
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Stat.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct MyGame_Example_Referrable: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Example_Referrable: 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 }
|
||||||
@@ -1079,7 +1079,7 @@ public class MyGame_Example_ReferrableT: NativeObject {
|
|||||||
|
|
||||||
}
|
}
|
||||||
/// an example documentation comment: "monster object"
|
/// an example documentation comment: "monster object"
|
||||||
public struct MyGame_Example_Monster: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Example_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 }
|
||||||
@@ -2213,7 +2213,7 @@ public class MyGame_Example_MonsterT: NativeObject {
|
|||||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Monster.self) }
|
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Monster.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct MyGame_Example_TypeAliases: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct MyGame_Example_TypeAliases: 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 }
|
||||||
|
|||||||
@@ -16,17 +16,19 @@
|
|||||||
|
|
||||||
import Common
|
import Common
|
||||||
import FlexBuffers
|
import FlexBuffers
|
||||||
import XCTest
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
|
||||||
final class FlexBuffersJSONTests: XCTestCase {
|
struct FlexBuffersJSONTests {
|
||||||
|
@Test
|
||||||
func testEncodingJSON() throws {
|
func testEncodingJSON() throws {
|
||||||
let buf: ByteBuffer = createProperBuffer().sizedByteBuffer
|
let buf: ByteBuffer = createProperBuffer().sizedByteBuffer
|
||||||
let reference = try getRoot(buffer: buf)!
|
let reference = try getRoot(buffer: buf)!
|
||||||
|
|
||||||
let json = reference.jsonString()
|
let json = reference.jsonString()
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
json,
|
json ==
|
||||||
"{\"bar\": [1, 2, 3], \"bar3\": [1, 2, 3], \"bool\": true, \"bools\": [true, false, true, false], \"foo\": 100.0, \"mymap\": {\"foo\": \"Fred\"}, \"vec\": [-100, \"Fred\", 4.0, \"M\", false, 4.0]}"
|
"{\"bar\": [1, 2, 3], \"bar3\": [1, 2, 3], \"bool\": true, \"bools\": [true, false, true, false], \"foo\": 100.0, \"mymap\": {\"foo\": \"Fred\"}, \"vec\": [-100, \"Fred\", 4.0, \"M\", false, 4.0]}"
|
||||||
)
|
)
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
@@ -37,15 +39,15 @@ final class FlexBuffersJSONTests: XCTestCase {
|
|||||||
with: data,
|
with: data,
|
||||||
options: []) as! [String: Any]
|
options: []) as! [String: Any]
|
||||||
|
|
||||||
XCTAssertEqual(decodedData["bar"] as! [Int], [1, 2, 3])
|
#expect(decodedData["bar"] as! [Int] == [1, 2, 3])
|
||||||
XCTAssertEqual(decodedData["bar3"] as! [Int], [1, 2, 3])
|
#expect(decodedData["bar3"] as! [Int] == [1, 2, 3])
|
||||||
|
|
||||||
let vec: [Any] = decodedData["vec"] as! [Any]
|
let vec: [Any] = decodedData["vec"] as! [Any]
|
||||||
XCTAssertEqual(vec[0] as! Int, -100)
|
#expect(vec[0] as! Int == -100)
|
||||||
XCTAssertEqual(vec[1] as! String, "Fred")
|
#expect(vec[1] as! String == "Fred")
|
||||||
XCTAssertEqual(vec[2] as! Double, 4.0)
|
#expect(vec[2] as! Double == 4.0)
|
||||||
XCTAssertEqual(vec[3] as! String, "M")
|
#expect(vec[3] as! String == "M")
|
||||||
XCTAssertEqual(vec[4] as! Bool, false)
|
#expect(vec[4] as! Bool == false)
|
||||||
XCTAssertEqual(vec[5] as! Double, 4.0)
|
#expect(vec[5] as! Double == 4.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,22 +15,26 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Common
|
import Common
|
||||||
import XCTest
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
|
||||||
@testable import FlexBuffers
|
@testable import FlexBuffers
|
||||||
|
|
||||||
final class FlexBuffersReaderTests: XCTestCase {
|
struct FlexBuffersReaderTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadingProperBuffer() throws {
|
func testReadingProperBuffer() throws {
|
||||||
let buf: ByteBuffer = createProperBuffer().byteBuffer
|
let buf: ByteBuffer = createProperBuffer().byteBuffer
|
||||||
try validate(buffer: buf)
|
try validate(buffer: buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testReadingSizedBuffer() throws {
|
func testReadingSizedBuffer() throws {
|
||||||
let buf: ByteBuffer = createSizedBuffer()
|
let buf: ByteBuffer = createSizedBuffer()
|
||||||
try validate(buffer: buf)
|
try validate(buffer: buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(.bug("https://github.com/google/flatbuffers/issues/8642"))
|
||||||
func testReset() throws {
|
func testReset() throws {
|
||||||
var fbx = FlexBuffersWriter(
|
var fbx = FlexBuffersWriter(
|
||||||
initialSize: 8,
|
initialSize: 8,
|
||||||
@@ -38,87 +42,87 @@ final class FlexBuffersReaderTests: XCTestCase {
|
|||||||
write(fbx: &fbx)
|
write(fbx: &fbx)
|
||||||
|
|
||||||
try validate(buffer: ByteBuffer(bytes: fbx.sizedByteArray))
|
try validate(buffer: ByteBuffer(bytes: fbx.sizedByteArray))
|
||||||
XCTAssertEqual(fbx.capacity, 512)
|
#expect(fbx.capacity == 512)
|
||||||
fbx.reset()
|
fbx.reset()
|
||||||
XCTAssertEqual(fbx.writerIndex, 0)
|
#expect(fbx.writerIndex == 0)
|
||||||
XCTAssertEqual(fbx.capacity, 8)
|
#expect(fbx.capacity == 8)
|
||||||
|
|
||||||
write(fbx: &fbx)
|
write(fbx: &fbx)
|
||||||
try validate(buffer: ByteBuffer(bytes: fbx.sizedByteArray))
|
try validate(buffer: ByteBuffer(bytes: fbx.sizedByteArray))
|
||||||
fbx.reset(keepingCapacity: true)
|
fbx.reset(keepingCapacity: true)
|
||||||
XCTAssertEqual(fbx.writerIndex, 0)
|
#expect(fbx.writerIndex == 0)
|
||||||
XCTAssertEqual(fbx.capacity, 512)
|
#expect(fbx.capacity == 512)
|
||||||
|
|
||||||
write(fbx: &fbx)
|
write(fbx: &fbx)
|
||||||
try validate(buffer: ByteBuffer(bytes: fbx.sizedByteArray))
|
try validate(buffer: ByteBuffer(bytes: fbx.sizedByteArray))
|
||||||
XCTAssertEqual(fbx.capacity, 512)
|
#expect(fbx.capacity == 512)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func validate(buffer buf: ByteBuffer) throws {
|
private func validate(buffer buf: ByteBuffer) throws {
|
||||||
let reference = try getRoot(buffer: buf)!
|
let reference = try getRoot(buffer: buf)!
|
||||||
XCTAssertEqual(reference.type, .map)
|
#expect(reference.type == .map)
|
||||||
let map = reference.map!
|
let map = reference.map!
|
||||||
XCTAssertEqual(map.count, 7)
|
#expect(map.count == 7)
|
||||||
let vecRef = map["vec"]!
|
let vecRef = map["vec"]!
|
||||||
XCTAssertEqual(vecRef.type, .vector)
|
#expect(vecRef.type == .vector)
|
||||||
let vec = vecRef.vector!
|
let vec = vecRef.vector!
|
||||||
XCTAssertEqual(vec.count, 6)
|
#expect(vec.count == 6)
|
||||||
XCTAssertEqual(vec[0]?.type, .int)
|
#expect(vec[0]?.type == .int)
|
||||||
XCTAssertEqual(vec[0]?.int, -100)
|
#expect(vec[0]?.int == -100)
|
||||||
XCTAssertEqual(vec[1]?.type, .string)
|
#expect(vec[1]?.type == .string)
|
||||||
XCTAssertEqual(vec[1]?.cString, "Fred")
|
#expect(vec[1]?.cString == "Fred")
|
||||||
XCTAssertNil(vec[1]?.int)
|
#expect(vec[1]?.int == nil)
|
||||||
XCTAssertEqual(vec[2]?.double, 4.0)
|
#expect(vec[2]?.double == 4.0)
|
||||||
XCTAssertTrue(vec[3]?.type == .blob)
|
#expect(vec[3]?.type == .blob)
|
||||||
|
|
||||||
let blob = vec[3]!.blob { pointer in
|
let blob = vec[3]!.blob { pointer in
|
||||||
Array(pointer)
|
Array(pointer)
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(blob?.count, 1)
|
#expect(blob?.count == 1)
|
||||||
XCTAssertEqual(blob?[0], 77)
|
#expect(blob?[0] == 77)
|
||||||
XCTAssertEqual(vec[4]?.type, .bool)
|
#expect(vec[4]?.type == .bool)
|
||||||
XCTAssertEqual(vec[4]?.bool, false)
|
#expect(vec[4]?.bool == false)
|
||||||
XCTAssertEqual(vec[5]?.double, 4.0) // Shared with vec[2]
|
#expect(vec[5]?.double == 4.0) // Shared with vec[2]
|
||||||
|
|
||||||
let barVec = map["bar"]!.typedVector!
|
let barVec = map["bar"]!.typedVector!
|
||||||
XCTAssertEqual(barVec.count, 3)
|
#expect(barVec.count == 3)
|
||||||
XCTAssertEqual(barVec[2]?.int, 3)
|
#expect(barVec[2]?.int == 3)
|
||||||
XCTAssertEqual(barVec[2]?.asInt(), UInt8(3))
|
#expect(barVec[2]?.asInt() == UInt8(3))
|
||||||
|
|
||||||
let fixedVec = map["bar3"]!.fixedTypedVector!
|
let fixedVec = map["bar3"]!.fixedTypedVector!
|
||||||
XCTAssertEqual(fixedVec.count, 3)
|
#expect(fixedVec.count == 3)
|
||||||
XCTAssertEqual(fixedVec[2]?.int, 3)
|
#expect(fixedVec[2]?.int == 3)
|
||||||
XCTAssertEqual(fixedVec[2]?.asInt(), UInt8(3))
|
#expect(fixedVec[2]?.asInt() == UInt8(3))
|
||||||
XCTAssertEqual(map["bool"]?.bool, true)
|
#expect(map["bool"]?.bool == true)
|
||||||
|
|
||||||
let boolsVector = map["bools"]!.typedVector!
|
let boolsVector = map["bools"]!.typedVector!
|
||||||
XCTAssertEqual(boolsVector.type, .bool)
|
#expect(boolsVector.type == .bool)
|
||||||
XCTAssertEqual(boolsVector[0]?.bool, true)
|
#expect(boolsVector[0]?.bool == true)
|
||||||
XCTAssertEqual(boolsVector[1]?.bool, false)
|
#expect(boolsVector[1]?.bool == false)
|
||||||
|
|
||||||
let bools = [true, false, true, false]
|
let bools = [true, false, true, false]
|
||||||
boolsVector.withUnsafeRawBufferPointer { buff in
|
boolsVector.withUnsafeRawBufferPointer { buff in
|
||||||
for i in 0..<boolsVector.count {
|
for i in 0..<boolsVector.count {
|
||||||
XCTAssertEqual(buff.load(fromByteOffset: i, as: Bool.self), bools[i])
|
#expect(buff.load(fromByteOffset: i, as: Bool.self) == bools[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XCTAssertEqual(map["foo"]?.double, 100)
|
#expect(map["foo"]?.double == 100)
|
||||||
XCTAssertNil(map["unknown"])
|
#expect(map["unknown"] == nil)
|
||||||
let mymap = map["mymap"]?.map
|
let mymap = map["mymap"]?.map
|
||||||
|
|
||||||
// Check if both addresses used are the same for keys and strings
|
// Check if both addresses used are the same for keys and strings
|
||||||
XCTAssertEqual(mymap?.keys[0]?.cString, map.keys[4]?.cString)
|
#expect(mymap?.keys[0]?.cString == map.keys[4]?.cString)
|
||||||
map.keys[4]?.withUnsafeRawPointer { pointer in
|
map.keys[4]?.withUnsafeRawPointer { pointer in
|
||||||
mymap?.keys[0]?.withUnsafeRawPointer { mymapPointer in
|
mymap?.keys[0]?.withUnsafeRawPointer { mymapPointer in
|
||||||
XCTAssertEqual(pointer, mymapPointer)
|
#expect(pointer == mymapPointer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(mymap?.values[0]?.cString, vec[1]?.cString)
|
#expect(mymap?.values[0]?.cString == vec[1]?.cString)
|
||||||
vec[1]?.withUnsafeRawPointer { pointer in
|
vec[1]?.withUnsafeRawPointer { pointer in
|
||||||
mymap?.values[0]?.withUnsafeRawPointer { mymapPointer in
|
mymap?.values[0]?.withUnsafeRawPointer { mymapPointer in
|
||||||
XCTAssertEqual(pointer, mymapPointer)
|
#expect(pointer == mymapPointer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,7 +131,7 @@ final class FlexBuffersReaderTests: XCTestCase {
|
|||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
// Gets the current path of this test file then
|
// Gets the current path of this test file then
|
||||||
// strips out the nested directories.
|
// strips out the nested directories.
|
||||||
let filePath = URL(filePath: #file)
|
let filePath = URL(filePath: #filePath)
|
||||||
.deletingLastPathComponent()
|
.deletingLastPathComponent()
|
||||||
.deletingLastPathComponent()
|
.deletingLastPathComponent()
|
||||||
.deletingLastPathComponent()
|
.deletingLastPathComponent()
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
|
|
||||||
import Common
|
import Common
|
||||||
import FlexBuffers
|
import FlexBuffers
|
||||||
import XCTest
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
|
||||||
final class FlexBuffersStringTests: XCTestCase {
|
struct FlexBuffersStringTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
func testEncodingUnicodeString() {
|
func testEncodingUnicodeString() {
|
||||||
let text = "プ画をみて✋"
|
let text = "プ画をみて✋"
|
||||||
|
|
||||||
@@ -38,6 +40,6 @@ final class FlexBuffersStringTests: XCTestCase {
|
|||||||
return String(data: data, encoding: .unicode)
|
return String(data: data, encoding: .unicode)
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(builtString, text)
|
#expect(builtString == text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
import Common
|
import Common
|
||||||
import FlexBuffers
|
import FlexBuffers
|
||||||
import XCTest
|
import Testing
|
||||||
|
|
||||||
final class FlexBuffersWriterTests: XCTestCase {
|
struct FlexBuffersWriterTests {
|
||||||
|
@Test
|
||||||
func testDeallocation() {
|
func testDeallocation() {
|
||||||
let buf: ByteBuffer = {
|
let buf: ByteBuffer = {
|
||||||
var fbx = FlexBuffersWriter()
|
var fbx = FlexBuffersWriter()
|
||||||
@@ -28,12 +29,13 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[5, 72, 101, 108, 108, 111, 0, 6, 20, 1])
|
[5, 72, 101, 108, 108, 111, 0, 6, 20, 1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testAddingVectorOfScalars() {
|
func testAddingVectorOfScalars() {
|
||||||
var fbx = FlexBuffersWriter()
|
var fbx = FlexBuffersWriter()
|
||||||
fbx.vector {
|
fbx.vector {
|
||||||
@@ -45,8 +47,8 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
|
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[
|
[
|
||||||
10, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0,
|
10, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0,
|
||||||
0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 20, 0, 0, 0, 1, 41, 46, 2, 40, 1,
|
0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 20, 0, 0, 0, 1, 41, 46, 2, 40, 1,
|
||||||
@@ -55,6 +57,7 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testAddingVectorOfUnsignedScalars() {
|
func testAddingVectorOfUnsignedScalars() {
|
||||||
var fbx = FlexBuffersWriter()
|
var fbx = FlexBuffersWriter()
|
||||||
fbx.vector {
|
fbx.vector {
|
||||||
@@ -66,8 +69,8 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
|
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[
|
[
|
||||||
10, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
|
10, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
|
||||||
0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
|
0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
|
||||||
@@ -78,6 +81,7 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testAddingVectorOfBools() {
|
func testAddingVectorOfBools() {
|
||||||
var fbx = FlexBuffersWriter()
|
var fbx = FlexBuffersWriter()
|
||||||
fbx.vector {
|
fbx.vector {
|
||||||
@@ -89,13 +93,14 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
|
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[4, 1, 0, 1, 0, 1, 5, 144, 2, 40, 1])
|
[4, 1, 0, 1, 0, 1, 5, 144, 2, 40, 1])
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testSortingWithinMap() {
|
func testSortingWithinMap() {
|
||||||
var fbx = FlexBuffersWriter()
|
var fbx = FlexBuffersWriter()
|
||||||
fbx.map {
|
fbx.map {
|
||||||
@@ -106,8 +111,8 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
let buf: ByteBuffer = fbx.sizedByteBuffer
|
let buf: ByteBuffer = fbx.sizedByteBuffer
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[
|
[
|
||||||
98, 111, 111, 108, 50, 0, 98, 111, 111, 108, 49, 0, 2, 7, 14, 2, 1, 2, 1, 0, 104, 104, 4,
|
98, 111, 111, 108, 50, 0, 98, 111, 111, 108, 49, 0, 2, 7, 14, 2, 1, 2, 1, 0, 104, 104, 4,
|
||||||
36, 1,
|
36, 1,
|
||||||
@@ -117,6 +122,7 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testSharingKeyWithinMap() {
|
func testSharingKeyWithinMap() {
|
||||||
var fbx = FlexBuffersWriter(initialSize: 1000, flags: .shareKeysAndStrings)
|
var fbx = FlexBuffersWriter(initialSize: 1000, flags: .shareKeysAndStrings)
|
||||||
fbx.map {
|
fbx.map {
|
||||||
@@ -128,8 +134,8 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
let buf: ByteBuffer = fbx.sizedByteBuffer
|
let buf: ByteBuffer = fbx.sizedByteBuffer
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[
|
[
|
||||||
119, 101, 108, 99, 111, 109, 101, 0, 7, 119, 101, 108, 99, 111, 109, 101, 0, 3, 18, 19,
|
119, 101, 108, 99, 111, 109, 101, 0, 7, 119, 101, 108, 99, 111, 109, 101, 0, 3, 18, 19,
|
||||||
20, 3, 1, 3, 15, 16, 17, 20, 20, 20, 6, 36, 1,
|
20, 3, 1, 3, 15, 16, 17, 20, 20, 20, 6, 36, 1,
|
||||||
@@ -139,19 +145,21 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testNestingVectorInMap() {
|
func testNestingVectorInMap() {
|
||||||
let buf: ByteBuffer = createSizedBuffer()
|
let buf: ByteBuffer = createSizedBuffer()
|
||||||
|
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
flexbufferGolden
|
flexbufferGolden
|
||||||
)
|
)
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testAddingNil() {
|
func testAddingNil() {
|
||||||
var fbx = FlexBuffersWriter(
|
var fbx = FlexBuffersWriter(
|
||||||
initialSize: 8,
|
initialSize: 8,
|
||||||
@@ -165,14 +173,15 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
let buf: ByteBuffer = fbx.sizedByteBuffer
|
let buf: ByteBuffer = fbx.sizedByteBuffer
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
[118, 0, 1, 3, 1, 1, 1, 0, 0, 2, 36, 1]
|
[118, 0, 1, 3, 1, 1, 1, 0, 0, 2, 36, 1]
|
||||||
)
|
)
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testAddingManually() {
|
func testAddingManually() {
|
||||||
var fbx = FlexBuffersWriter(
|
var fbx = FlexBuffersWriter(
|
||||||
initialSize: 8,
|
initialSize: 8,
|
||||||
@@ -209,14 +218,15 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
let buf: ByteBuffer = fbx.sizedByteBuffer
|
let buf: ByteBuffer = fbx.sizedByteBuffer
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
flexbufferGolden
|
flexbufferGolden
|
||||||
)
|
)
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
func testEncodingAllTypes() {
|
func testEncodingAllTypes() {
|
||||||
var fbx = FlexBuffersWriter()
|
var fbx = FlexBuffersWriter()
|
||||||
fbx.vector {
|
fbx.vector {
|
||||||
@@ -240,8 +250,8 @@ final class FlexBuffersWriterTests: XCTestCase {
|
|||||||
|
|
||||||
buf.withUnsafeBytes {
|
buf.withUnsafeBytes {
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
XCTAssertEqual(
|
#expect(
|
||||||
Array($0),
|
Array($0) ==
|
||||||
allTypesGolden)
|
allTypesGolden)
|
||||||
// swiftformat:enable all
|
// swiftformat:enable all
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
|
|
||||||
#if canImport(Common)
|
#if canImport(Common)
|
||||||
@_implementationOnly import Common
|
internal import Common
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@_implementationOnly import FlatBuffers
|
internal import FlatBuffers
|
||||||
|
|
||||||
internal struct Message: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
internal struct Message: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
||||||
internal var __buffer: ByteBuffer! { return _accessor.bb }
|
internal var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public struct BytesCount_Mutable: FlatBufferStruct, FlatbuffersVectorInitializab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct InternalMessage: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct InternalMessage: 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 }
|
||||||
@@ -148,7 +148,7 @@ public class InternalMessageT: NativeObject {
|
|||||||
public func serialize() -> ByteBuffer { return serialize(type: InternalMessage.self) }
|
public func serialize() -> ByteBuffer { return serialize(type: InternalMessage.self) }
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct Message: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {
|
public struct Message: 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 }
|
||||||
|
|||||||
@@ -1774,6 +1774,7 @@ int FlatBufferTests(const std::string& tests_data_path) {
|
|||||||
FixedLengthArrayJsonTest(tests_data_path, false);
|
FixedLengthArrayJsonTest(tests_data_path, false);
|
||||||
FixedLengthArrayJsonTest(tests_data_path, true);
|
FixedLengthArrayJsonTest(tests_data_path, true);
|
||||||
ReflectionTest(tests_data_path, flatbuf.data(), flatbuf.size());
|
ReflectionTest(tests_data_path, flatbuf.data(), flatbuf.size());
|
||||||
|
ForAllFieldsReverseTest(tests_data_path);
|
||||||
ParseProtoTest(tests_data_path);
|
ParseProtoTest(tests_data_path);
|
||||||
EvolutionTest(tests_data_path);
|
EvolutionTest(tests_data_path);
|
||||||
UnionDeprecationTest(tests_data_path);
|
UnionDeprecationTest(tests_data_path);
|
||||||
|
|||||||
@@ -62,16 +62,10 @@ def flatc(
|
|||||||
|
|
||||||
# Execute esbuild with the specified parameters
|
# Execute esbuild with the specified parameters
|
||||||
def esbuild(input, output):
|
def esbuild(input, output):
|
||||||
cmd = ["esbuild", input, "--outfile=" + output]
|
cmd = ["../../node_modules/.bin/esbuild", input, "--outfile=" + output]
|
||||||
cmd += ["--format=cjs", "--bundle", "--external:flatbuffers"]
|
cmd += ["--format=cjs", "--bundle", "--external:flatbuffers"]
|
||||||
check_call(cmd)
|
check_call(cmd)
|
||||||
|
|
||||||
|
|
||||||
print("Removing node_modules/ directory...")
|
|
||||||
shutil.rmtree(Path(tests_path, "node_modules"), ignore_errors=True)
|
|
||||||
|
|
||||||
check_call(["npm", "install", "--silent"])
|
|
||||||
|
|
||||||
flatc(
|
flatc(
|
||||||
options=[
|
options=[
|
||||||
"--ts",
|
"--ts",
|
||||||
@@ -228,12 +222,12 @@ flatc(
|
|||||||
)
|
)
|
||||||
|
|
||||||
print("Running TypeScript Compiler...")
|
print("Running TypeScript Compiler...")
|
||||||
check_call(["tsc"])
|
check_call(["../../node_modules/.bin/tsc"])
|
||||||
print(
|
print(
|
||||||
"Running TypeScript Compiler in old node resolution mode for"
|
"Running TypeScript Compiler in old node resolution mode for"
|
||||||
" no_import_ext..."
|
" no_import_ext..."
|
||||||
)
|
)
|
||||||
check_call(["tsc", "-p", "./tsconfig.node.json"])
|
check_call(["../../node_modules/.bin/tsc", "-p", "./tsconfig.node.json"])
|
||||||
|
|
||||||
NODE_CMD = ["node"]
|
NODE_CMD = ["node"]
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"flatbuffers": "../../"
|
"flatbuffers": "workspace:*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
tests/ts/pnpm-lock.yaml
generated
10
tests/ts/pnpm-lock.yaml
generated
@@ -1,10 +0,0 @@
|
|||||||
lockfileVersion: '6.0'
|
|
||||||
|
|
||||||
settings:
|
|
||||||
autoInstallPeers: true
|
|
||||||
excludeLinksFromLockfile: false
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
flatbuffers:
|
|
||||||
specifier: ../../
|
|
||||||
version: link:../..
|
|
||||||
Reference in New Issue
Block a user