forked from BigfootDev/flatbuffers
Compare commits
56
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d239f8942c | ||
|
|
4bd1e24e75 | ||
|
|
5761d6e67a | ||
|
|
81edeb17d9 | ||
|
|
5982eb6495 | ||
|
|
38df29380a | ||
|
|
1f438bd40f | ||
|
|
392165432a | ||
|
|
e6bbb3d22e | ||
|
|
a6979fe14a | ||
|
|
bab10754d9 | ||
|
|
ac7ef1176a | ||
|
|
d6444fb7fc | ||
|
|
e223d69b36 | ||
|
|
05cc7a2eff | ||
|
|
8a12183c3b | ||
|
|
21b706b62d | ||
|
|
c5f151ab33 | ||
|
|
3860f1cf7f | ||
|
|
4e582b0c1d | ||
|
|
8396e00dd8 | ||
|
|
48babd417d | ||
|
|
22770f7e85 | ||
|
|
21b033227e | ||
|
|
93f587a6d3 | ||
|
|
8afb68f074 | ||
|
|
2e07f269b9 | ||
|
|
10c994155c | ||
|
|
fc9909c30a | ||
|
|
e35817577c | ||
|
|
9e3fe5d3f6 | ||
|
|
dc9217347e | ||
|
|
a7fed2ce67 | ||
|
|
de3b97355d | ||
|
|
8aa7084f01 | ||
|
|
0f469cad54 | ||
|
|
72e51c61f7 | ||
|
|
31590a8a3b | ||
|
|
24c2432d99 | ||
|
|
292870612c | ||
|
|
57659d9f38 | ||
|
|
2b8e4d3af0 | ||
|
|
08b6372a36 | ||
|
|
9c383559e0 | ||
|
|
c13c3bf956 | ||
|
|
47eeb8f4e9 | ||
|
|
e7c6874192 | ||
|
|
8d2c333b36 | ||
|
|
abc9bfebff | ||
|
|
94d6b8086b | ||
|
|
fa709636b4 | ||
|
|
60463e25a8 | ||
|
|
b8e3d215b8 | ||
|
|
d71c0ab4ac | ||
|
|
fcf75449b8 | ||
|
|
c21bda1649 |
@@ -0,0 +1,6 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
@@ -238,8 +238,15 @@ set(FlatBuffers_Tests_SRCS
|
||||
tests/util_test.cpp
|
||||
tests/vector_table_naked_ptr_test.h
|
||||
tests/vector_table_naked_ptr_test.cpp
|
||||
tests/test_vector_type.h
|
||||
tests/cpp_vector_type_test.h
|
||||
tests/cpp_vector_type_test.cpp
|
||||
tests/native_type_test_impl.h
|
||||
tests/native_type_test_impl.cpp
|
||||
tests/bigfoot_ref_test_impl.h
|
||||
tests/bigfoot_ref_test_impl.cpp
|
||||
tests/required_table_default_test.h
|
||||
tests/required_table_default_test.cpp
|
||||
tests/alignment_test.h
|
||||
tests/alignment_test.cpp
|
||||
tests/64bit/offset64_test.h
|
||||
@@ -548,17 +555,21 @@ if(FLATBUFFERS_BUILD_TESTS)
|
||||
# The flattest target needs some generated files
|
||||
SET(FLATC_OPT_COMP --cpp --gen-compare --gen-mutable --gen-object-api --reflect-names)
|
||||
SET(FLATC_OPT_SCOPED_ENUMS ${FLATC_OPT_COMP};--scoped-enums)
|
||||
SET(FLATC_OPT_CPP_VECTOR_TYPE ${FLATC_OPT_COMP};--cpp-include;test_vector_type.h;--cpp-vector-type;::flatbuffers::tests::CustomVector)
|
||||
|
||||
compile_schema_for_test(tests/alignment_test.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test_fbsh(tests/default_vectors_strings_test.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/arrays_test.fbs "${FLATC_OPT_SCOPED_ENUMS}")
|
||||
compile_schema_for_test(tests/native_inline_table_test.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/native_type_test.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/bigfoot_ref_test.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/required_table_default_test.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/key_field/key_field_sample.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/64bit/test_64bit.fbs "${FLATC_OPT_COMP};--bfbs-gen-embed")
|
||||
compile_schema_for_test(tests/64bit/evolution/v1.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/64bit/evolution/v2.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/union_underlying_type_test.fbs "${FLATC_OPT_SCOPED_ENUMS}")
|
||||
compile_schema_for_test(tests/cpp_vector_type.fbs "${FLATC_OPT_CPP_VECTOR_TYPE}")
|
||||
|
||||
if(FLATBUFFERS_CODE_SANITIZE)
|
||||
add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2024 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Benchmark
|
||||
import FlexBuffers
|
||||
import Foundation
|
||||
|
||||
let benchmarks = {
|
||||
let data = {
|
||||
var array = [8888.88, 8888.88]
|
||||
var data = Data()
|
||||
array.withUnsafeBytes { ptr in
|
||||
data.append(contentsOf: ptr)
|
||||
}
|
||||
return data
|
||||
}()
|
||||
let ints: [Int32] = Array(repeating: 42, count: 100)
|
||||
let str10 = (0...9).map { _ -> String in "x" }.joined()
|
||||
let str100 = (0...99).map { _ -> String in "x" }.joined()
|
||||
|
||||
// A representative map: 50 keyed scalars, a keyed string and a keyed vector
|
||||
// of 100 scalars. Used for the realistic decode benchmarks.
|
||||
let mapBuffer: ByteBuffer = {
|
||||
var fbx = FlexBuffersWriter(initialSize: 1 << 16)
|
||||
fbx.map {
|
||||
for i in 0..<50 { $0.add(int: i, key: "i\(i)") }
|
||||
$0.add(string: "hello world", key: "s")
|
||||
$0.vector(key: "v") { v in
|
||||
for x in 0..<100 { v.add(int: x) }
|
||||
}
|
||||
}
|
||||
fbx.finish()
|
||||
return fbx.sizedByteBuffer
|
||||
}()
|
||||
|
||||
let metrics: [BenchmarkMetric] = [
|
||||
.cpuTotal,
|
||||
.wallClock,
|
||||
.mallocCountTotal,
|
||||
.releaseCount,
|
||||
.peakMemoryResident,
|
||||
]
|
||||
let maxIterations = 1_000_000
|
||||
let maxDuration: Duration = .seconds(3)
|
||||
let megaConfiguration: Benchmark.Configuration = .init(
|
||||
metrics: metrics,
|
||||
warmupIterations: 1,
|
||||
scalingFactor: .mega,
|
||||
maxDuration: maxDuration,
|
||||
maxIterations: maxIterations)
|
||||
|
||||
Benchmark.defaultConfiguration = megaConfiguration
|
||||
|
||||
// Decode (read path)
|
||||
|
||||
// Raw scalar read: isolates `read<T: BitwiseCopyable>` and the `let` blob.
|
||||
Benchmark("Reading Doubles") { benchmark in
|
||||
let byteBuffer = ByteBuffer(data: data)
|
||||
benchmark.startMeasurement()
|
||||
for _ in benchmark.scaledIterations {
|
||||
blackHole(byteBuffer.read(def: Double.self, position: 0))
|
||||
}
|
||||
benchmark.stopMeasurement()
|
||||
}
|
||||
|
||||
// Realistic decode: resolve root map and read a keyed scalar.
|
||||
Benchmark("Decode Map Scalar") { benchmark in
|
||||
benchmark.startMeasurement()
|
||||
for _ in benchmark.scaledIterations {
|
||||
let map = try! getRoot(buffer: mapBuffer)!.map!
|
||||
blackHole(map["i25"]?.int)
|
||||
}
|
||||
benchmark.stopMeasurement()
|
||||
}
|
||||
|
||||
// Realistic decode: resolve root map and read a keyed string.
|
||||
Benchmark("Decode Map String") { benchmark in
|
||||
benchmark.startMeasurement()
|
||||
for _ in benchmark.scaledIterations {
|
||||
let map = try! getRoot(buffer: mapBuffer)!.map!
|
||||
blackHole(map["s"]?.string())
|
||||
}
|
||||
benchmark.stopMeasurement()
|
||||
}
|
||||
|
||||
// Realistic decode: resolve a nested vector and sum its scalars.
|
||||
Benchmark("Decode Vector") { benchmark in
|
||||
benchmark.startMeasurement()
|
||||
for _ in benchmark.scaledIterations {
|
||||
let map = try! getRoot(buffer: mapBuffer)!.map!
|
||||
let vector = map["v"]!.vector!
|
||||
var sum: Int64 = 0
|
||||
for i in 0..<vector.count {
|
||||
sum &+= vector[i]?.int ?? 0
|
||||
}
|
||||
blackHole(sum)
|
||||
}
|
||||
benchmark.stopMeasurement()
|
||||
}
|
||||
|
||||
// Encode (write path)
|
||||
// Writers are reused with `reset(keepingCapacity:)` so per-iteration
|
||||
// allocation does not dominate and mask the write-path cost (which is what
|
||||
// the `@exclusivity(unchecked)` storage pointer affects).
|
||||
|
||||
Benchmark("Strings 10") { benchmark in
|
||||
var fbx = FlexBuffersWriter(initialSize: 1 << 20)
|
||||
benchmark.startMeasurement()
|
||||
for _ in benchmark.scaledIterations {
|
||||
fbx.add(string: str10)
|
||||
fbx.finish()
|
||||
blackHole(fbx.sizedByteBuffer)
|
||||
fbx.reset(keepingCapacity: true)
|
||||
}
|
||||
benchmark.stopMeasurement()
|
||||
}
|
||||
|
||||
Benchmark("Strings 100") { benchmark in
|
||||
var fbx = FlexBuffersWriter(initialSize: 1 << 20)
|
||||
benchmark.startMeasurement()
|
||||
for _ in benchmark.scaledIterations {
|
||||
fbx.add(string: str100)
|
||||
fbx.finish()
|
||||
blackHole(fbx.sizedByteBuffer)
|
||||
fbx.reset(keepingCapacity: true)
|
||||
}
|
||||
benchmark.stopMeasurement()
|
||||
}
|
||||
|
||||
Benchmark("Encoding Vector Of Ints") { benchmark in
|
||||
var fbx = FlexBuffersWriter(initialSize: 1 << 20)
|
||||
benchmark.startMeasurement()
|
||||
for _ in benchmark.scaledIterations {
|
||||
fbx.vector {
|
||||
$0.create(vector: ints)
|
||||
}
|
||||
fbx.finish()
|
||||
blackHole(fbx.sizedByteBuffer)
|
||||
fbx.reset(keepingCapacity: true)
|
||||
}
|
||||
benchmark.stopMeasurement()
|
||||
}
|
||||
|
||||
Benchmark("Encoding Map") { benchmark in
|
||||
var fbx = FlexBuffersWriter(initialSize: 1 << 20)
|
||||
benchmark.startMeasurement()
|
||||
for _ in benchmark.scaledIterations {
|
||||
fbx.map {
|
||||
for i in 0..<50 { $0.add(int: i, key: "i\(i)") }
|
||||
$0.add(string: "hello world", key: "s")
|
||||
$0.vector(key: "v") { v in
|
||||
for x in 0..<100 { v.add(int: x) }
|
||||
}
|
||||
}
|
||||
fbx.finish()
|
||||
blackHole(fbx.sizedByteBuffer)
|
||||
fbx.reset(keepingCapacity: true)
|
||||
}
|
||||
benchmark.stopMeasurement()
|
||||
}
|
||||
}
|
||||
@@ -168,6 +168,12 @@ list of `FILES...`.
|
||||
std::string from Flatbuffers, but (char* + length). This allows efficient
|
||||
construction of custom string types, including zero-copy construction.
|
||||
|
||||
- `--cpp-vector-type T` : Set object API vector type (default std::vector).
|
||||
T must be a template taking a single element type argument and support
|
||||
resize(), reserve(), size(), data(), operator[], emplace_back() and
|
||||
begin()/end(), matching the subset of std::vector's interface generated
|
||||
code relies on.
|
||||
|
||||
- `--no-cpp-direct-copy` : Don't generate direct copy methods for C++
|
||||
object-based API.
|
||||
|
||||
|
||||
@@ -242,6 +242,42 @@ provide the following functions to aide in the serialization process:
|
||||
}
|
||||
```
|
||||
|
||||
- `bigfoot_ref_wrapper("type")` (on a struct) together with `bigfoot_ref("type")`
|
||||
(on a field of that struct type): Bigfoot-specific sugar for a
|
||||
UUID-addressed reference to another native type. `bigfoot_ref_wrapper`
|
||||
marks a struct as a reference-wrapper template (e.g. Bigfoot's
|
||||
`HardReference`/`SoftReference`); `bigfoot_ref` on a field of that type
|
||||
names the referenced native type, e.g. `bigfoot_ref: "::Bigfoot::AssetA"`
|
||||
on a `HardReference`-typed field with `bigfoot_ref_wrapper:
|
||||
"::Bigfoot::HardReference"` produces the field's native type
|
||||
`::Bigfoot::HardReference<::Bigfoot::AssetA>` (auto-deriving a
|
||||
`native_type_pack_name` of `HardReferenceAssetA`, same short-name
|
||||
convention as `native_type_pack_name`). Unlike a hand-written
|
||||
`native_type`, `bigfoot_ref` also emits, directly into the generated
|
||||
header:
|
||||
- a forward declaration of the referenced type (so the referencing
|
||||
schema's generated header never needs that type's real definition -
|
||||
only the wrapper template's constructor and a `GetUUID()` accessor
|
||||
are used, and those don't require the referenced type to be
|
||||
complete), and
|
||||
- `inline` `Pack<Name>`/`UnPack<Name>` definitions for it (so no
|
||||
hand-written implementation is required anywhere).
|
||||
|
||||
```cpp
|
||||
struct HardReference (bigfoot_ref_wrapper: "::Bigfoot::HardReference") {
|
||||
uuid: UUID;
|
||||
}
|
||||
|
||||
table AssetB {
|
||||
ref_a: HardReference (bigfoot_ref: "::Bigfoot::AssetA");
|
||||
}
|
||||
```
|
||||
|
||||
is enough on its own - no forward declaration of `::Bigfoot::AssetA` and
|
||||
no `flatbuffers::Pack/UnPackHardReferenceAssetA` implementation need to
|
||||
be written by hand. `bigfoot_ref` is only valid on fields whose type is a
|
||||
struct (or vector of structs) that declares `bigfoot_ref_wrapper`.
|
||||
|
||||
- `native_type("type")` (on a table): Tables can also be represented with
|
||||
native types. For example, the following schema:
|
||||
|
||||
@@ -337,6 +373,27 @@ constructor in the following format: `custom_str_class(const char *, size_t)`.
|
||||
Please note that the character array is not guaranteed to be NULL terminated,
|
||||
you should always use the provided size to determine end of string.
|
||||
|
||||
## Using different vector type
|
||||
|
||||
By default the object tree's vector fields are built out of `std::vector`,
|
||||
but you can influence this either globally (using the `--cpp-vector-type`
|
||||
argument to `flatc`) or per field using the `cpp_vector_type` attribute, to
|
||||
use any other vector-like template type (e.g. `eastl::vector`).
|
||||
|
||||
The type must be a template taking a single element type argument
|
||||
(`my_vector<T>`), and must support the following member functions:
|
||||
`resize()`, `reserve()`, `size()`, `data()`, `operator[]`, `emplace_back()`,
|
||||
and `begin()`/`end()`. This matches the subset of `std::vector`'s interface
|
||||
that generated code relies on.
|
||||
|
||||
Note that unlike `std::vector<bool>`, the custom vector type must not use a
|
||||
bit-packed specialization for `bool` elements, since generated code accesses
|
||||
`data()` as a contiguous `bool` array.
|
||||
|
||||
As with custom string types, the header defining the custom vector type is
|
||||
not automatically included; use `--cpp-include` to add the necessary
|
||||
`#include`.
|
||||
|
||||
## Reflection (& Resizing)
|
||||
|
||||
There is experimental support for reflection in FlatBuffers, allowing you to
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
// swiftlint:disable all
|
||||
// swiftformat:disable all
|
||||
|
||||
#if canImport(Common)
|
||||
import Common
|
||||
#endif
|
||||
|
||||
import FlatBuffers
|
||||
|
||||
public struct models_HelloResponse: FlatBufferVerifiableTable, FlatbuffersVectorInitializable {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
private var _accessor: Table
|
||||
|
||||
private init(_ t: Table) { _accessor = t }
|
||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||
|
||||
private struct VT {
|
||||
static let message: VOffset = 4
|
||||
}
|
||||
|
||||
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 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 endHelloResponse(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
|
||||
public static func createHelloResponse(
|
||||
_ fbb: inout FlatBufferBuilder,
|
||||
messageOffset message: Offset = Offset()
|
||||
) -> Offset {
|
||||
let __start = models_HelloResponse.startHelloResponse(&fbb)
|
||||
models_HelloResponse.add(message: message, &fbb)
|
||||
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 {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VT.message, fieldName: "message", required: false, type: ForwardOffset<String>.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
extension models_HelloResponse: Encodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case message = "message"
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeIfPresent(message, forKey: .message)
|
||||
}
|
||||
}
|
||||
|
||||
public struct models_HelloRequest: FlatBufferVerifiableTable, FlatbuffersVectorInitializable {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
private var _accessor: Table
|
||||
|
||||
private init(_ t: Table) { _accessor = t }
|
||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||
|
||||
private struct VT {
|
||||
static let name: VOffset = 4
|
||||
}
|
||||
|
||||
public var name: String? { let o = _accessor.offset(VT.name); return o == 0 ? nil : _accessor.string(at: o) }
|
||||
public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: VT.name) }
|
||||
public static func startHelloRequest(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
||||
public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VT.name) }
|
||||
public static func endHelloRequest(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
|
||||
public static func createHelloRequest(
|
||||
_ fbb: inout FlatBufferBuilder,
|
||||
nameOffset name: Offset = Offset()
|
||||
) -> Offset {
|
||||
let __start = models_HelloRequest.startHelloRequest(&fbb)
|
||||
models_HelloRequest.add(name: name, &fbb)
|
||||
return models_HelloRequest.endHelloRequest(&fbb, start: __start)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VT.name, fieldName: "name", required: false, type: ForwardOffset<String>.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
extension models_HelloRequest: Encodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case name = "name"
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeIfPresent(name, forKey: .name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +142,19 @@
|
||||
#define FLATBUFFERS_VERSION_MAJOR 25
|
||||
#define FLATBUFFERS_VERSION_MINOR 12
|
||||
#define FLATBUFFERS_VERSION_REVISION 19
|
||||
|
||||
// Identifies this header as Bigfoot's fork of flatbuffers, and versions the
|
||||
// fork's own generated-code-affecting changes independently of the upstream
|
||||
// FLATBUFFERS_VERSION_* triplet above (which just tracks the upstream
|
||||
// version this fork is based on, and would still match an unforked, stock
|
||||
// flatbuffers install of the same version). Generated headers assert on
|
||||
// this - see GenFlatbuffersVersionCheck() in idl_gen_cpp.cpp - so building
|
||||
// Bigfoot-generated code against stock flatbuffers, or a differently
|
||||
// versioned Bigfoot fork, fails to compile immediately instead of silently
|
||||
// miscompiling. Bump this whenever a change here affects what generated
|
||||
// code assumes about this header (e.g. adding bigfoot_ref/bigfoot_ref_wrapper).
|
||||
#define FLATBUFFERS_BIGFOOT_VERSION 1
|
||||
|
||||
#define FLATBUFFERS_STRING_EXPAND(X) #X
|
||||
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
|
||||
namespace flatbuffers {
|
||||
|
||||
@@ -677,6 +677,7 @@ struct IDLOptions {
|
||||
std::string cpp_object_api_pointer_type;
|
||||
std::string cpp_object_api_string_type;
|
||||
bool cpp_object_api_string_flexible_constructor;
|
||||
std::string cpp_object_api_vector_type;
|
||||
CaseStyle cpp_object_api_field_case_style;
|
||||
bool cpp_direct_copy;
|
||||
bool gen_nullable;
|
||||
@@ -1012,10 +1013,13 @@ class Parser : public ParserState {
|
||||
known_attributes_["cpp_ptr_type_get"] = true;
|
||||
known_attributes_["cpp_str_type"] = true;
|
||||
known_attributes_["cpp_str_flex_ctor"] = true;
|
||||
known_attributes_["cpp_vector_type"] = true;
|
||||
known_attributes_["native_inline"] = true;
|
||||
known_attributes_["native_custom_alloc"] = true;
|
||||
known_attributes_["native_type"] = true;
|
||||
known_attributes_["native_type_pack_name"] = true;
|
||||
known_attributes_["bigfoot_ref_wrapper"] = true;
|
||||
known_attributes_["bigfoot_ref"] = true;
|
||||
known_attributes_["native_default"] = true;
|
||||
known_attributes_["flexbuffer"] = true;
|
||||
known_attributes_["private"] = true;
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
packages:
|
||||
- tests/ts
|
||||
@@ -251,6 +251,21 @@ flatc(
|
||||
schema="vector_table_naked_ptr.fbs",
|
||||
)
|
||||
|
||||
flatc(
|
||||
[
|
||||
"--cpp",
|
||||
"--gen-compare",
|
||||
"--gen-mutable",
|
||||
"--gen-object-api",
|
||||
"--reflect-names",
|
||||
"--cpp-include",
|
||||
"test_vector_type.h",
|
||||
"--cpp-vector-type",
|
||||
"::flatbuffers::tests::CustomVector",
|
||||
],
|
||||
schema="cpp_vector_type.fbs",
|
||||
)
|
||||
|
||||
flatc(
|
||||
BASE_OPTS + CPP_OPTS + CS_OPTS + JAVA_OPTS + KOTLIN_OPTS + PHP_OPTS,
|
||||
prefix="union_vector",
|
||||
|
||||
@@ -145,6 +145,12 @@ const static FlatCOption flatc_options[] = {
|
||||
{"", "cpp-str-flex-ctor", "",
|
||||
"Don't construct custom string types by passing std::string from "
|
||||
"Flatbuffers, but (char* + length)."},
|
||||
{"", "cpp-vector-type", "T",
|
||||
"Set object API vector type (default std::vector). T must be a "
|
||||
"template taking a single element type argument and support "
|
||||
"resize(), reserve(), size(), data(), operator[], emplace_back(), and "
|
||||
"begin()/end(). The custom type also needs its own header to be "
|
||||
"included via --cpp-include."},
|
||||
{"", "cpp-field-case-style", "STYLE",
|
||||
"Generate C++ fields using selected case style. Supported STYLE values: * "
|
||||
"'unchanged' - leave unchanged (default) * 'upper' - schema snake_case "
|
||||
@@ -545,6 +551,9 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
|
||||
opts.cpp_object_api_string_type = argv[argi];
|
||||
} else if (arg == "--cpp-str-flex-ctor") {
|
||||
opts.cpp_object_api_string_flexible_constructor = true;
|
||||
} else if (arg == "--cpp-vector-type") {
|
||||
if (++argi >= argc) Error("missing type following: " + arg, true);
|
||||
opts.cpp_object_api_vector_type = argv[argi];
|
||||
} else if (arg == "--no-cpp-direct-copy") {
|
||||
opts.cpp_direct_copy = false;
|
||||
} else if (arg == "--cpp-field-case-style") {
|
||||
|
||||
+288
-27
@@ -257,6 +257,19 @@ class CppGenerator : public BaseGenerator {
|
||||
code_ += " FLATBUFFERS_VERSION_REVISION == " +
|
||||
std::to_string(FLATBUFFERS_VERSION_REVISION) + ",";
|
||||
code_ += " \"Non-compatible flatbuffers version included\");";
|
||||
|
||||
code_ += "// Ensure the included flatbuffers.h is Bigfoot's fork - stock";
|
||||
code_ += "// flatbuffers (or a differently versioned Bigfoot fork) is not compatible.";
|
||||
code_ += "#ifndef FLATBUFFERS_BIGFOOT_VERSION";
|
||||
code_ +=
|
||||
"#error \"This file requires Bigfoot's flatbuffers fork - stock "
|
||||
"flatbuffers is not compatible\"";
|
||||
code_ += "#endif";
|
||||
code_ += "static_assert(FLATBUFFERS_BIGFOOT_VERSION == " +
|
||||
std::to_string(FLATBUFFERS_BIGFOOT_VERSION) + ",";
|
||||
code_ +=
|
||||
" \"Non-compatible Bigfoot flatbuffers fork version "
|
||||
"included\");";
|
||||
}
|
||||
|
||||
void GenIncludeDependencies() {
|
||||
@@ -529,6 +542,8 @@ class CppGenerator : public BaseGenerator {
|
||||
code_ += "";
|
||||
}
|
||||
|
||||
GenerateBigfootRefForwardDecls();
|
||||
|
||||
// Generate preablmle code for mini reflection.
|
||||
if (opts_.mini_reflect != IDLOptions::kNone) {
|
||||
// To break cyclic dependencies, first pre-declare all tables/structs.
|
||||
@@ -758,6 +773,8 @@ class CppGenerator : public BaseGenerator {
|
||||
|
||||
if (cur_name_space_) SetNameSpace(nullptr);
|
||||
|
||||
GenerateBigfootRefImpls();
|
||||
|
||||
// Close the include guard.
|
||||
code_ += "#endif // " + include_guard;
|
||||
|
||||
@@ -892,6 +909,24 @@ class CppGenerator : public BaseGenerator {
|
||||
return opts_.gen_nullable ? " _Nullable " : "";
|
||||
}
|
||||
|
||||
// A field's `native_type`/`native_type_pack_name` normally come from the
|
||||
// referenced struct's own declaration. A field can override both (see
|
||||
// `bigfoot_ref` in idl_parser.cpp, which synthesizes these two attributes
|
||||
// directly on the field) to instantiate a templated native type
|
||||
// differently per field.
|
||||
static const Value* EffectiveNativeType(const FieldDef& field,
|
||||
const StructDef& struct_def) {
|
||||
if (const auto v = field.attributes.Lookup("native_type")) return v;
|
||||
return struct_def.attributes.Lookup("native_type");
|
||||
}
|
||||
|
||||
static const Value* EffectiveNativeTypePackName(const FieldDef& field,
|
||||
const StructDef& struct_def) {
|
||||
if (const auto v = field.attributes.Lookup("native_type_pack_name"))
|
||||
return v;
|
||||
return struct_def.attributes.Lookup("native_type_pack_name");
|
||||
}
|
||||
|
||||
static std::string NativeName(const std::string& name, const StructDef* sd,
|
||||
const IDLOptions& opts) {
|
||||
// If the table is a native_type, return the native_type name.
|
||||
@@ -937,6 +972,23 @@ class CppGenerator : public BaseGenerator {
|
||||
"std::string"; // Only for custom string types.
|
||||
}
|
||||
|
||||
const std::string NativeVectorType(const FieldDef* field) {
|
||||
auto attr = field ? field->attributes.Lookup("cpp_vector_type") : nullptr;
|
||||
auto& ret = attr ? attr->constant : opts_.cpp_object_api_vector_type;
|
||||
if (ret.empty()) {
|
||||
return "std::vector";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// True if this field's native vector uses a custom (non-std::vector)
|
||||
// container, meaning generated Pack() code can't rely on the std::vector
|
||||
// specific CreateVector*() overloads and must fall back to data()/size()
|
||||
// or per-element construction instead.
|
||||
bool UsesCustomVectorType(const FieldDef* field) {
|
||||
return NativeVectorType(field) != "std::vector";
|
||||
}
|
||||
|
||||
std::string GenTypeNativePtr(const std::string& type, const FieldDef* field,
|
||||
bool is_constructor) {
|
||||
auto& ptr_type = PtrType(field);
|
||||
@@ -974,20 +1026,21 @@ class CppGenerator : public BaseGenerator {
|
||||
case BASE_TYPE_VECTOR64:
|
||||
case BASE_TYPE_VECTOR: {
|
||||
const auto type_name = GenTypeNative(type.VectorType(), true, field);
|
||||
if (type.struct_def &&
|
||||
const auto vector_type = NativeVectorType(&field);
|
||||
if (vector_type == "std::vector" && type.struct_def &&
|
||||
type.struct_def->attributes.Lookup("native_custom_alloc")) {
|
||||
auto native_custom_alloc =
|
||||
type.struct_def->attributes.Lookup("native_custom_alloc");
|
||||
return "std::vector<" + type_name + "," +
|
||||
native_custom_alloc->constant + "<" + type_name + ">>";
|
||||
} else {
|
||||
return "std::vector<" + type_name + ">";
|
||||
return vector_type + "<" + type_name + ">";
|
||||
}
|
||||
}
|
||||
case BASE_TYPE_STRUCT: {
|
||||
auto type_name = WrapInNameSpace(*type.struct_def);
|
||||
if (IsStruct(type)) {
|
||||
auto native_type = type.struct_def->attributes.Lookup("native_type");
|
||||
auto native_type = EffectiveNativeType(field, *type.struct_def);
|
||||
if (native_type) {
|
||||
type_name = native_type->constant;
|
||||
}
|
||||
@@ -1979,7 +2032,7 @@ class CppGenerator : public BaseGenerator {
|
||||
const std::string& full_type =
|
||||
(cpp_type
|
||||
? (IsVector(field.value.type)
|
||||
? "std::vector<" +
|
||||
? NativeVectorType(&field) + "<" +
|
||||
GenTypeNativePtr(cpp_type->constant, &field,
|
||||
false) +
|
||||
"> "
|
||||
@@ -1996,8 +2049,19 @@ class CppGenerator : public BaseGenerator {
|
||||
" = " + (native_default ? std::string(native_default->constant)
|
||||
: GetDefaultScalarValue(field, true));
|
||||
} else if (field.value.type.base_type == BASE_TYPE_STRUCT) {
|
||||
if (IsStruct(field.value.type) && native_default) {
|
||||
field_di = " = " + native_default->constant;
|
||||
if (IsStruct(field.value.type)) {
|
||||
if (native_default) {
|
||||
field_di = " = " + native_default->constant;
|
||||
}
|
||||
} else if (!cpp_type && !field.native_inline && field.IsRequired() &&
|
||||
PtrType(&field) != "naked") {
|
||||
// A required table field can never legally be absent once
|
||||
// Verify()/Pack() succeed, so default-construct it here instead
|
||||
// of leaving every hand-written native constructor to remember
|
||||
// to allocate it before the first Pack().
|
||||
const auto nn = WrapNativeNameInNameSpace(
|
||||
*field.value.type.struct_def, opts_);
|
||||
field_di = "{new " + nn + "()}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3515,11 +3579,11 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
case BASE_TYPE_STRUCT: {
|
||||
if (IsStruct(type)) {
|
||||
const auto& struct_attrs = type.struct_def->attributes;
|
||||
const auto native_type = struct_attrs.Lookup("native_type");
|
||||
const auto native_type = EffectiveNativeType(afield, *type.struct_def);
|
||||
if (native_type) {
|
||||
std::string unpack_call = "::flatbuffers::UnPack";
|
||||
const auto pack_name = struct_attrs.Lookup("native_type_pack_name");
|
||||
const auto pack_name =
|
||||
EffectiveNativeTypePackName(afield, *type.struct_def);
|
||||
if (pack_name) {
|
||||
unpack_call += pack_name->constant;
|
||||
}
|
||||
@@ -3772,13 +3836,22 @@ class CppGenerator : public BaseGenerator {
|
||||
case BASE_TYPE_VECTOR64:
|
||||
case BASE_TYPE_VECTOR: {
|
||||
auto vector_type = field.value.type.VectorType();
|
||||
// If the field's native container isn't std::vector, the
|
||||
// std::vector-specific CreateVector*() overloads in
|
||||
// flatbuffer_builder.h can't be used directly. Fall back to
|
||||
// data()/size()-based overloads (which only require the container to
|
||||
// support those, like std::vector does) or, where no such overload
|
||||
// exists, to the same per-element lambda serialization already used
|
||||
// above for custom string/table/union element types.
|
||||
const bool custom_vector = UsesCustomVectorType(&field);
|
||||
switch (vector_type.base_type) {
|
||||
case BASE_TYPE_STRING: {
|
||||
if (NativeString(&field) == "std::string") {
|
||||
if (!custom_vector && NativeString(&field) == "std::string") {
|
||||
code += "_fbb.CreateVectorOfStrings(" + value + ")";
|
||||
} else {
|
||||
// Use by-function serialization to emulate
|
||||
// CreateVectorOfStrings(); this works also with non-std strings.
|
||||
// CreateVectorOfStrings(); this works also with non-std strings
|
||||
// and non-std::vector vector types.
|
||||
code +=
|
||||
"_fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::"
|
||||
"String>>"
|
||||
@@ -3793,20 +3866,37 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
case BASE_TYPE_STRUCT: {
|
||||
if (IsStruct(vector_type)) {
|
||||
const auto& struct_attrs =
|
||||
field.value.type.struct_def->attributes;
|
||||
const auto native_type = struct_attrs.Lookup("native_type");
|
||||
const auto native_type =
|
||||
EffectiveNativeType(field, *field.value.type.struct_def);
|
||||
if (native_type) {
|
||||
code += "_fbb.CreateVectorOfNativeStructs<";
|
||||
code += WrapInNameSpace(*vector_type.struct_def) + ", " +
|
||||
native_type->constant + ">";
|
||||
code += "(" + value;
|
||||
const auto pack_name =
|
||||
struct_attrs.Lookup("native_type_pack_name");
|
||||
if (custom_vector) {
|
||||
code += "(" + value + ".data(), " + value + ".size()";
|
||||
} else {
|
||||
code += "(" + value;
|
||||
}
|
||||
const auto pack_name = EffectiveNativeTypePackName(
|
||||
field, *field.value.type.struct_def);
|
||||
if (pack_name) {
|
||||
code += ", ::flatbuffers::Pack" + pack_name->constant;
|
||||
}
|
||||
code += ")";
|
||||
} else if (custom_vector &&
|
||||
(field.value.type.base_type == BASE_TYPE_VECTOR64 ||
|
||||
field.offset64)) {
|
||||
// CreateVectorOfStructs64() (and CreateVectorOfStructs64<V>()
|
||||
// for offset64) only accept a std::vector; use the
|
||||
// equivalent explicit-template raw pointer overload instead.
|
||||
const auto struct_type = WrapInNameSpace(*vector_type.struct_def);
|
||||
const auto vector_t = field.value.type.base_type ==
|
||||
BASE_TYPE_VECTOR64
|
||||
? "::flatbuffers::Vector64"
|
||||
: "::flatbuffers::Vector";
|
||||
code += "_fbb.CreateVectorOfStructs<" + struct_type +
|
||||
", ::flatbuffers::Offset64, " + vector_t + ">(" +
|
||||
value + ".data(), " + value + ".size())";
|
||||
} else {
|
||||
// If the field uses 64-bit addressing, create a 64-bit vector.
|
||||
if (field.value.type.base_type == BASE_TYPE_VECTOR64) {
|
||||
@@ -3818,7 +3908,11 @@ class CppGenerator : public BaseGenerator {
|
||||
code += "64<::flatbuffers::Vector>";
|
||||
}
|
||||
}
|
||||
code += "(" + value + ")";
|
||||
if (custom_vector) {
|
||||
code += "(" + value + ".data(), " + value + ".size())";
|
||||
} else {
|
||||
code += "(" + value + ")";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
code += "_fbb.CreateVector<::flatbuffers::Offset<";
|
||||
@@ -3837,7 +3931,17 @@ class CppGenerator : public BaseGenerator {
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_BOOL: {
|
||||
code += "_fbb.CreateVector(" + value + ")";
|
||||
if (custom_vector) {
|
||||
// Vectors of bool are always stored on the wire as uint8_t
|
||||
// (there is no Vector<bool>); CreateVectorScalarCast() does
|
||||
// the per-element bool->uint8_t cast from a raw data()/size()
|
||||
// pointer pair, avoiding any dependency on std::vector<bool>'s
|
||||
// bit-packed specialization.
|
||||
code += "_fbb.CreateVectorScalarCast<uint8_t>(" + value +
|
||||
".data(), " + value + ".size())";
|
||||
} else {
|
||||
code += "_fbb.CreateVector(" + value + ")";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_UNION: {
|
||||
@@ -3873,9 +3977,11 @@ class CppGenerator : public BaseGenerator {
|
||||
// the underlying storage type (eg. uint8_t).
|
||||
const auto basetype = GenTypeBasic(
|
||||
field.value.type.enum_def->underlying_type, false);
|
||||
code += "_fbb.CreateVectorScalarCast<" + basetype +
|
||||
">(::flatbuffers::data(" + value + "), " + value +
|
||||
".size())";
|
||||
const std::string data_ptr =
|
||||
custom_vector ? value + ".data()"
|
||||
: "::flatbuffers::data(" + value + ")";
|
||||
code += "_fbb.CreateVectorScalarCast<" + basetype + ">(" +
|
||||
data_ptr + ", " + value + ".size())";
|
||||
} else if (field.attributes.Lookup("cpp_type")) {
|
||||
auto type = GenTypeBasic(vector_type, false);
|
||||
code += "_fbb.CreateVector<" + type + ">(" + value + ".size(), ";
|
||||
@@ -3884,6 +3990,27 @@ class CppGenerator : public BaseGenerator {
|
||||
code += "static_cast<" + type + ">((*__va->__rehasher)";
|
||||
code += "(__va->_" + value + "[i]" + GenPtrGet(field) + ")) : 0";
|
||||
code += "; }, &_va )";
|
||||
} else if (custom_vector) {
|
||||
// Explicitly specify the element type so it can be deduced
|
||||
// from a raw data()/size() pointer pair instead of relying on
|
||||
// the std::vector<T, Alloc>-specific CreateVector overloads.
|
||||
// Use the user-facing type (matches what GenTypeNative()
|
||||
// stores in the native vector, e.g. the enum type itself for
|
||||
// scoped-enum fields) so it matches data()'s pointee type.
|
||||
auto type = GenTypeBasic(vector_type, true);
|
||||
if (field.value.type.base_type == BASE_TYPE_VECTOR64) {
|
||||
code += "_fbb.CreateVector<" + type +
|
||||
", ::flatbuffers::Offset64, ::flatbuffers::Vector64>(" +
|
||||
value + ".data(), " + value + ".size())";
|
||||
} else if (field.offset64) {
|
||||
// This is normal 32-bit vector, with 64-bit addressing.
|
||||
code += "_fbb.CreateVector<" + type +
|
||||
", ::flatbuffers::Offset64, ::flatbuffers::Vector>(" +
|
||||
value + ".data(), " + value + ".size())";
|
||||
} else {
|
||||
code += "_fbb.CreateVector(" + value + ".data(), " + value +
|
||||
".size())";
|
||||
}
|
||||
} else {
|
||||
// If the field uses 64-bit addressing, create a 64-bit vector.
|
||||
if (field.value.type.base_type == BASE_TYPE_VECTOR64) {
|
||||
@@ -3917,12 +4044,12 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
case BASE_TYPE_STRUCT: {
|
||||
if (IsStruct(field.value.type)) {
|
||||
const auto& struct_attribs = field.value.type.struct_def->attributes;
|
||||
const auto native_type = struct_attribs.Lookup("native_type");
|
||||
const auto native_type =
|
||||
EffectiveNativeType(field, *field.value.type.struct_def);
|
||||
if (native_type && field.native_inline) {
|
||||
code += "::flatbuffers::Pack";
|
||||
const auto pack_name =
|
||||
struct_attribs.Lookup("native_type_pack_name");
|
||||
EffectiveNativeTypePackName(field, *field.value.type.struct_def);
|
||||
if (pack_name) {
|
||||
code += pack_name->constant;
|
||||
}
|
||||
@@ -4087,8 +4214,7 @@ class CppGenerator : public BaseGenerator {
|
||||
if (field->value.type.base_type == BASE_TYPE_STRUCT) {
|
||||
if (IsStruct(field->value.type)) {
|
||||
auto native_type =
|
||||
field->value.type.struct_def->attributes.Lookup(
|
||||
"native_type");
|
||||
EffectiveNativeType(*field, *field->value.type.struct_def);
|
||||
auto native_inline = field->attributes.Lookup("native_inline");
|
||||
if (native_type) {
|
||||
pass_by_address = true;
|
||||
@@ -4443,6 +4569,141 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
// Split a "::"-qualified C++ name into namespace components + final name.
|
||||
static std::vector<std::string> SplitQualifiedName(const std::string& qualified) {
|
||||
std::vector<std::string> parts;
|
||||
size_t start = qualified.compare(0, 2, "::") == 0 ? 2 : 0;
|
||||
for (;;) {
|
||||
const auto pos = qualified.find("::", start);
|
||||
if (pos == std::string::npos) {
|
||||
parts.push_back(qualified.substr(start));
|
||||
break;
|
||||
}
|
||||
parts.push_back(qualified.substr(start, pos - start));
|
||||
start = pos + 2;
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
// Bigfoot: for every field annotated `bigfoot_ref: "::Ns::AssetX"` (see
|
||||
// idl_parser.cpp), forward-declare AssetX plus prototype the Pack/UnPack
|
||||
// functions for its reference wrapper. Called early (alongside the
|
||||
// regular struct/table forward declarations), since these prototypes -
|
||||
// unlike their definitions in GenerateBigfootRefImpls() - only need
|
||||
// AssetX and the wrapper struct forward-declared, not complete.
|
||||
void GenerateBigfootRefForwardDecls() {
|
||||
std::unordered_set<std::string> declared_assets;
|
||||
for (const auto& struct_def : parser_.structs_.vec) {
|
||||
if (struct_def->generated) continue;
|
||||
for (const auto& field : struct_def->fields.vec) {
|
||||
const auto* bigfoot_ref = field->attributes.Lookup("bigfoot_ref");
|
||||
if (!bigfoot_ref) continue;
|
||||
if (!declared_assets.insert(bigfoot_ref->constant).second) continue;
|
||||
|
||||
auto parts = SplitQualifiedName(bigfoot_ref->constant);
|
||||
const std::string class_name = parts.back();
|
||||
parts.pop_back();
|
||||
|
||||
SetNameSpace(nullptr);
|
||||
for (const auto& ns_part : parts) code_ += "namespace " + ns_part + " {";
|
||||
code_ += "class " + class_name + ";";
|
||||
for (auto it = parts.rbegin(); it != parts.rend(); ++it)
|
||||
code_ += "} // namespace " + *it;
|
||||
code_ += "";
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_set<std::string> declared_pairs;
|
||||
bool opened_flatbuffers_ns = false;
|
||||
for (const auto& struct_def : parser_.structs_.vec) {
|
||||
if (struct_def->generated) continue;
|
||||
for (const auto& field : struct_def->fields.vec) {
|
||||
const auto* bigfoot_ref = field->attributes.Lookup("bigfoot_ref");
|
||||
if (!bigfoot_ref) continue;
|
||||
|
||||
const auto* pack_name = field->attributes.Lookup("native_type_pack_name");
|
||||
if (!declared_pairs.insert(pack_name->constant).second) continue;
|
||||
|
||||
if (!opened_flatbuffers_ns) {
|
||||
SetNameSpace(nullptr);
|
||||
code_ += "namespace flatbuffers {";
|
||||
opened_flatbuffers_ns = true;
|
||||
}
|
||||
|
||||
const auto* native_type = field->attributes.Lookup("native_type");
|
||||
const std::string flat_wrapper =
|
||||
WrapInNameSpace(*field->value.type.struct_def);
|
||||
|
||||
code_ += flat_wrapper + " Pack" + pack_name->constant +
|
||||
"(const " + native_type->constant + "& p_asset);";
|
||||
code_ += native_type->constant + " UnPack" + pack_name->constant +
|
||||
"(const " + flat_wrapper + "& p_asset);";
|
||||
}
|
||||
}
|
||||
|
||||
if (opened_flatbuffers_ns) {
|
||||
code_ += "} // namespace flatbuffers";
|
||||
code_ += "";
|
||||
}
|
||||
}
|
||||
|
||||
// Bigfoot: defines the Pack/UnPack functions prototyped by
|
||||
// GenerateBigfootRefForwardDecls(). Called late (after every struct/table
|
||||
// in this file has been fully defined), since a wrapper struct (e.g.
|
||||
// HardReference/SoftReference) may be defined in this same generated file
|
||||
// rather than one it includes, and these definitions construct it by
|
||||
// value - they need it complete, unlike the earlier prototypes.
|
||||
void GenerateBigfootRefImpls() {
|
||||
std::unordered_set<std::string> declared_pairs;
|
||||
bool opened_flatbuffers_ns = false;
|
||||
for (const auto& struct_def : parser_.structs_.vec) {
|
||||
if (struct_def->generated) continue;
|
||||
for (const auto& field : struct_def->fields.vec) {
|
||||
const auto* bigfoot_ref = field->attributes.Lookup("bigfoot_ref");
|
||||
if (!bigfoot_ref) continue;
|
||||
|
||||
const auto* pack_name = field->attributes.Lookup("native_type_pack_name");
|
||||
if (!declared_pairs.insert(pack_name->constant).second) continue;
|
||||
|
||||
if (!opened_flatbuffers_ns) {
|
||||
SetNameSpace(nullptr);
|
||||
code_ += "namespace flatbuffers {";
|
||||
opened_flatbuffers_ns = true;
|
||||
}
|
||||
|
||||
const auto* native_type = field->attributes.Lookup("native_type");
|
||||
const std::string flat_wrapper =
|
||||
WrapInNameSpace(*field->value.type.struct_def);
|
||||
|
||||
// A single translation unit can end up including two different
|
||||
// generated headers that both reference the same asset type (e.g.
|
||||
// AssetB references AssetA, and some other TU includes both
|
||||
// AssetA_generated.hpp and AssetB_generated.hpp directly) - each
|
||||
// would otherwise emit an identical, independent definition of these
|
||||
// functions. `inline` only allows identical definitions to repeat
|
||||
// across *different* translation units, not twice within the same
|
||||
// one, so guard against that with a plain macro guard.
|
||||
std::string guard_name = pack_name->constant;
|
||||
std::transform(guard_name.begin(), guard_name.end(), guard_name.begin(), CharToUpper);
|
||||
const std::string guard = "FLATBUFFERS_BIGFOOT_REF_" + guard_name;
|
||||
code_ += "#ifndef " + guard;
|
||||
code_ += "#define " + guard;
|
||||
code_ += "inline " + flat_wrapper + " Pack" + pack_name->constant +
|
||||
"(const " + native_type->constant +
|
||||
"& p_asset) { return {Pack(p_asset.GetUUID())}; }";
|
||||
code_ += "inline " + native_type->constant + " UnPack" +
|
||||
pack_name->constant + "(const " + flat_wrapper +
|
||||
"& p_asset) { return {UnPack(p_asset.uuid())}; }";
|
||||
code_ += "#endif // " + guard;
|
||||
}
|
||||
}
|
||||
|
||||
if (opened_flatbuffers_ns) {
|
||||
code_ += "} // namespace flatbuffers";
|
||||
code_ += "";
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the correct namespace. Only open a namespace if the existing one is
|
||||
// different (closing/opening only what is necessary).
|
||||
//
|
||||
|
||||
@@ -1286,6 +1286,55 @@ CheckedError Parser::ParseField(StructDef& struct_def) {
|
||||
"'native_inline' can only be defined on structs, vector of structs or "
|
||||
"vector of tables");
|
||||
|
||||
// `bigfoot_ref` is Bigfoot's single-purpose replacement for the old,
|
||||
// general-purpose `native_type_template`/`native_type_template_arg` pair:
|
||||
// a field typed as a `bigfoot_ref_wrapper`-tagged struct (HardReference or
|
||||
// SoftReference) and annotated `bigfoot_ref: "::Bigfoot::AssetX"` gets its
|
||||
// native type instantiated as `<wrapper><::Bigfoot::AssetX>`, plus (unlike
|
||||
// the old mechanism) a forward declaration of AssetX and inline Pack/UnPack
|
||||
// definitions are emitted directly into the generated header - see
|
||||
// GenerateBigfootRefDecls in idl_gen_cpp.cpp.
|
||||
auto bigfoot_ref = field->attributes.Lookup("bigfoot_ref");
|
||||
if (bigfoot_ref) {
|
||||
if (!IsStruct(field->value.type) && !IsVectorOfStruct(field->value.type))
|
||||
return Error(
|
||||
"'bigfoot_ref' can only be defined on struct-typed fields or "
|
||||
"vectors of structs");
|
||||
const auto* target_struct = field->value.type.struct_def;
|
||||
const auto* wrapper = target_struct->attributes.Lookup("bigfoot_ref_wrapper");
|
||||
if (!wrapper)
|
||||
return Error(
|
||||
"'bigfoot_ref' requires the field's type ('" + target_struct->name +
|
||||
"') to declare a 'bigfoot_ref_wrapper' attribute");
|
||||
if (field->attributes.Lookup("native_type"))
|
||||
return Error(
|
||||
"'bigfoot_ref' cannot be combined with an explicit 'native_type' "
|
||||
"on the same field");
|
||||
|
||||
const auto b = bigfoot_ref->constant.find_first_not_of(" \t");
|
||||
const auto e = bigfoot_ref->constant.find_last_not_of(" \t");
|
||||
const std::string asset_type =
|
||||
b == std::string::npos ? "" : bigfoot_ref->constant.substr(b, e - b + 1);
|
||||
if (asset_type.empty())
|
||||
return Error("'bigfoot_ref' cannot be empty");
|
||||
|
||||
auto native_type_val = new Value();
|
||||
native_type_val->type = bigfoot_ref->type;
|
||||
native_type_val->constant = wrapper->constant + "<" + asset_type + ">";
|
||||
field->attributes.Add("native_type", native_type_val);
|
||||
|
||||
if (!field->attributes.Lookup("native_type_pack_name")) {
|
||||
const auto last_colon = asset_type.find_last_of(':');
|
||||
const std::string asset_short_name =
|
||||
last_colon == std::string::npos ? asset_type
|
||||
: asset_type.substr(last_colon + 1);
|
||||
auto pack_name_val = new Value();
|
||||
pack_name_val->type = bigfoot_ref->type;
|
||||
pack_name_val->constant = target_struct->name + asset_short_name;
|
||||
field->attributes.Add("native_type_pack_name", pack_name_val);
|
||||
}
|
||||
}
|
||||
|
||||
auto nested = field->attributes.Lookup("nested_flatbuffer");
|
||||
if (nested) {
|
||||
if (nested->type.base_type != BASE_TYPE_STRING)
|
||||
|
||||
@@ -78,6 +78,9 @@ cc_test(
|
||||
"vector_table_naked_ptr/vector_table_naked_ptr_generated.h",
|
||||
"vector_table_naked_ptr_test.h",
|
||||
"vector_table_naked_ptr_test.cpp",
|
||||
"test_vector_type.h",
|
||||
"cpp_vector_type_test.h",
|
||||
"cpp_vector_type_test.cpp",
|
||||
],
|
||||
copts = [
|
||||
"-DFLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE",
|
||||
@@ -136,6 +139,7 @@ cc_test(
|
||||
deps = [
|
||||
":alignment_test_cc_fbs",
|
||||
":arrays_test_cc_fbs",
|
||||
":cpp_vector_type_cc_fbs",
|
||||
":default_vectors_strings_test_cc_fbs",
|
||||
":monster_extra_cc_fbs",
|
||||
":monster_test_cc_fbs",
|
||||
@@ -271,6 +275,19 @@ flatbuffer_cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
flatbuffer_cc_library(
|
||||
name = "cpp_vector_type_cc_fbs",
|
||||
srcs = ["cpp_vector_type.fbs"],
|
||||
flatc_args = [
|
||||
"--gen-compare",
|
||||
"--gen-mutable",
|
||||
"--gen-object-api",
|
||||
"--reflect-names",
|
||||
"--cpp-include test_vector_type.h",
|
||||
"--cpp-vector-type ::flatbuffers::tests::CustomVector",
|
||||
],
|
||||
)
|
||||
|
||||
flatbuffer_cc_library(
|
||||
name = "alignment_test_cc_fbs",
|
||||
srcs = ["alignment_test.fbs"],
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
// <auto-generated>
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
// </auto-generated>
|
||||
|
||||
namespace MyGame.Example
|
||||
{
|
||||
|
||||
using global::System;
|
||||
using global::System.Collections.Generic;
|
||||
using global::Google.FlatBuffers;
|
||||
|
||||
public struct LargeArrayStruct : IFlatbufferObject
|
||||
{
|
||||
private Struct __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
|
||||
public LargeArrayStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public byte D(int j) { return __p.bb.Get(__p.bb_pos + 0 + j * 1); }
|
||||
public const int DLength = 64;
|
||||
#if ENABLE_SPAN_T
|
||||
public Span<byte> GetDBytes() { return __p.bb.ToSpan(__p.bb_pos + 0, 64); }
|
||||
#else
|
||||
public ArraySegment<byte>? GetDBytes() { return __p.bb.ToArraySegment(__p.bb_pos + 0, 64);}
|
||||
#endif
|
||||
public void MutateD(int j, byte d) { __p.bb.Put(__p.bb_pos + 0 + j * 1, d); }
|
||||
public float E(int j) { return __p.bb.GetFloat(__p.bb_pos + 64 + j * 4); }
|
||||
public const int ELength = 64;
|
||||
#if ENABLE_SPAN_T
|
||||
public Span<float> GetEBytes() { return System.Runtime.InteropServices.MemoryMarshal.Cast<byte, float>(__p.bb.ToSpan(__p.bb_pos + 64, 256)); }
|
||||
#else
|
||||
public ArraySegment<byte>? GetEBytes() { return __p.bb.ToArraySegment(__p.bb_pos + 64, 256);}
|
||||
#endif
|
||||
public void MutateE(int j, float e) { __p.bb.PutFloat(__p.bb_pos + 64 + j * 4, e); }
|
||||
public bool F(int j) { return 0!=__p.bb.Get(__p.bb_pos + 320 + j * 1); }
|
||||
public const int FLength = 64;
|
||||
#if ENABLE_SPAN_T
|
||||
public Span<bool> GetFBytes() { return System.Runtime.InteropServices.MemoryMarshal.Cast<byte, bool>(__p.bb.ToSpan(__p.bb_pos + 320, 64)); }
|
||||
#else
|
||||
public ArraySegment<byte>? GetFBytes() { return __p.bb.ToArraySegment(__p.bb_pos + 320, 64);}
|
||||
#endif
|
||||
public void MutateF(int j, bool f) { __p.bb.Put(__p.bb_pos + 320 + j * 1, (byte)(f ? 1 : 0)); }
|
||||
public MyGame.Example.NestedStruct G(int j) { return (new MyGame.Example.NestedStruct()).__assign(__p.bb_pos + 384 + j * 32, __p.bb); }
|
||||
public MyGame.Example.TestEnum H(int j) { return (MyGame.Example.TestEnum)__p.bb.GetSbyte(__p.bb_pos + 2432 + j * 1); }
|
||||
public const int HLength = 64;
|
||||
#if ENABLE_SPAN_T
|
||||
public Span<MyGame.Example.TestEnum> GetHBytes() { return System.Runtime.InteropServices.MemoryMarshal.Cast<byte, MyGame.Example.TestEnum>(__p.bb.ToSpan(__p.bb_pos + 2432, 64)); }
|
||||
#else
|
||||
public ArraySegment<byte>? GetHBytes() { return __p.bb.ToArraySegment(__p.bb_pos + 2432, 64);}
|
||||
#endif
|
||||
public void MutateH(int j, MyGame.Example.TestEnum h) { __p.bb.PutSbyte(__p.bb_pos + 2432 + j * 1, (sbyte)h); }
|
||||
|
||||
public static Offset<MyGame.Example.LargeArrayStruct> CreateLargeArrayStruct(FlatBufferBuilder builder, byte[] D, float[] E, bool[] F, int[,] g_A, MyGame.Example.TestEnum[] g_B, MyGame.Example.TestEnum[,] g_C, long[,] g_D, MyGame.Example.TestEnum[] H) {
|
||||
builder.Prep(8, 2496);
|
||||
for (int _idx0 = 64; _idx0 > 0; _idx0--) {
|
||||
builder.PutSbyte((sbyte)H[_idx0-1]);
|
||||
}
|
||||
for (int _idx0 = 64; _idx0 > 0; _idx0--) {
|
||||
builder.Prep(8, 32);
|
||||
for (int _idx1 = 2; _idx1 > 0; _idx1--) {
|
||||
builder.PutLong(g_D[_idx0-1,_idx1-1]);
|
||||
}
|
||||
builder.Pad(5);
|
||||
for (int _idx1 = 2; _idx1 > 0; _idx1--) {
|
||||
builder.PutSbyte((sbyte)g_C[_idx0-1,_idx1-1]);
|
||||
}
|
||||
builder.PutSbyte((sbyte)g_B[_idx0-1]);
|
||||
for (int _idx1 = 2; _idx1 > 0; _idx1--) {
|
||||
builder.PutInt(g_A[_idx0-1,_idx1-1]);
|
||||
}
|
||||
}
|
||||
for (int _idx0 = 64; _idx0 > 0; _idx0--) {
|
||||
builder.PutBool(F[_idx0-1]);
|
||||
}
|
||||
for (int _idx0 = 64; _idx0 > 0; _idx0--) {
|
||||
builder.PutFloat(E[_idx0-1]);
|
||||
}
|
||||
for (int _idx0 = 64; _idx0 > 0; _idx0--) {
|
||||
builder.PutByte(D[_idx0-1]);
|
||||
}
|
||||
return new Offset<MyGame.Example.LargeArrayStruct>(builder.Offset);
|
||||
}
|
||||
public LargeArrayStructT UnPack() {
|
||||
var _o = new LargeArrayStructT();
|
||||
this.UnPackTo(_o);
|
||||
return _o;
|
||||
}
|
||||
public void UnPackTo(LargeArrayStructT _o) {
|
||||
_o.D = new byte[64];
|
||||
for (var _j = 0; _j < 64; ++_j) { _o.D[_j] = this.D(_j); }
|
||||
_o.E = new float[64];
|
||||
for (var _j = 0; _j < 64; ++_j) { _o.E[_j] = this.E(_j); }
|
||||
_o.F = new bool[64];
|
||||
for (var _j = 0; _j < 64; ++_j) { _o.F[_j] = this.F(_j); }
|
||||
_o.G = new MyGame.Example.NestedStructT[64];
|
||||
for (var _j = 0; _j < 64; ++_j) { _o.G[_j] = this.G(_j).UnPack(); }
|
||||
_o.H = new MyGame.Example.TestEnum[64];
|
||||
for (var _j = 0; _j < 64; ++_j) { _o.H[_j] = this.H(_j); }
|
||||
}
|
||||
public static Offset<MyGame.Example.LargeArrayStruct> Pack(FlatBufferBuilder builder, LargeArrayStructT _o) {
|
||||
if (_o == null) return default(Offset<MyGame.Example.LargeArrayStruct>);
|
||||
var _d = _o.D;
|
||||
var _e = _o.E;
|
||||
var _f = _o.F;
|
||||
var _g_a = new int[64,2];
|
||||
for (var idx0 = 0; idx0 < 64; ++idx0) {for (var idx1 = 0; idx1 < 2; ++idx1) {_g_a[idx0,idx1] = _o.G[idx0].A[idx1];}}
|
||||
var _g_b = new MyGame.Example.TestEnum[64];
|
||||
for (var idx0 = 0; idx0 < 64; ++idx0) {_g_b[idx0] = _o.G[idx0].B;}
|
||||
var _g_c = new MyGame.Example.TestEnum[64,2];
|
||||
for (var idx0 = 0; idx0 < 64; ++idx0) {for (var idx1 = 0; idx1 < 2; ++idx1) {_g_c[idx0,idx1] = _o.G[idx0].C[idx1];}}
|
||||
var _g_d = new long[64,2];
|
||||
for (var idx0 = 0; idx0 < 64; ++idx0) {for (var idx1 = 0; idx1 < 2; ++idx1) {_g_d[idx0,idx1] = _o.G[idx0].D[idx1];}}
|
||||
var _h = _o.H;
|
||||
return CreateLargeArrayStruct(
|
||||
builder,
|
||||
_d,
|
||||
_e,
|
||||
_f,
|
||||
_g_a,
|
||||
_g_b,
|
||||
_g_c,
|
||||
_g_d,
|
||||
_h);
|
||||
}
|
||||
}
|
||||
|
||||
public class LargeArrayStructT
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("d")]
|
||||
public byte[] D { get; set; }
|
||||
[Newtonsoft.Json.JsonProperty("e")]
|
||||
public float[] E { get; set; }
|
||||
[Newtonsoft.Json.JsonProperty("f")]
|
||||
public bool[] F { get; set; }
|
||||
[Newtonsoft.Json.JsonProperty("g")]
|
||||
public MyGame.Example.NestedStructT[] G { get; set; }
|
||||
[Newtonsoft.Json.JsonProperty("h")]
|
||||
public MyGame.Example.TestEnum[] H { get; set; }
|
||||
|
||||
public LargeArrayStructT() {
|
||||
this.D = new byte[64];
|
||||
this.E = new float[64];
|
||||
this.F = new bool[64];
|
||||
this.G = new MyGame.Example.NestedStructT[64];
|
||||
this.H = new MyGame.Example.TestEnum[64];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
package MyGame.Example;
|
||||
|
||||
import com.google.flatbuffers.BaseVector;
|
||||
import com.google.flatbuffers.BooleanVector;
|
||||
import com.google.flatbuffers.ByteVector;
|
||||
import com.google.flatbuffers.Constants;
|
||||
import com.google.flatbuffers.DoubleVector;
|
||||
import com.google.flatbuffers.FlatBufferBuilder;
|
||||
import com.google.flatbuffers.FloatVector;
|
||||
import com.google.flatbuffers.IntVector;
|
||||
import com.google.flatbuffers.LongVector;
|
||||
import com.google.flatbuffers.ShortVector;
|
||||
import com.google.flatbuffers.StringVector;
|
||||
import com.google.flatbuffers.Struct;
|
||||
import com.google.flatbuffers.UnionVector;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class LargeArrayStruct extends Struct {
|
||||
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
|
||||
public LargeArrayStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public int d(int j) { return bb.get(bb_pos + 0 + j * 1); }
|
||||
public void mutateD(int j, int d) { bb.put(bb_pos + 0 + j * 1, (byte) d); }
|
||||
public float e(int j) { return bb.getFloat(bb_pos + 64 + j * 4); }
|
||||
public void mutateE(int j, float e) { bb.putFloat(bb_pos + 64 + j * 4, e); }
|
||||
public boolean f(int j) { return 0!=bb.get(bb_pos + 320 + j * 1); }
|
||||
public void mutateF(int j, boolean f) { bb.put(bb_pos + 320 + j * 1, (byte)(f ? 1 : 0)); }
|
||||
public MyGame.Example.NestedStruct g(int j) { return g(new MyGame.Example.NestedStruct(), j); }
|
||||
public MyGame.Example.NestedStruct g(MyGame.Example.NestedStruct obj, int j) { return obj.__assign(bb_pos + 384 + j * 32, bb); }
|
||||
public byte h(int j) { return bb.get(bb_pos + 2432 + j * 1); }
|
||||
public void mutateH(int j, byte h) { bb.put(bb_pos + 2432 + j * 1, h); }
|
||||
|
||||
public static int createLargeArrayStruct(FlatBufferBuilder builder, int[] d, float[] e, boolean[] f, int[][] g_a, byte[] g_b, byte[][] g_c, long[][] g_d, byte[] h) {
|
||||
builder.prep(8, 2496);
|
||||
for (int _idx0 = 64; _idx0 > 0; _idx0--) {
|
||||
builder.putByte(h[_idx0-1]);
|
||||
}
|
||||
for (int _idx0 = 64; _idx0 > 0; _idx0--) {
|
||||
builder.prep(8, 32);
|
||||
for (int _idx1 = 2; _idx1 > 0; _idx1--) {
|
||||
builder.putLong(g_d[_idx0-1][_idx1-1]);
|
||||
}
|
||||
builder.pad(5);
|
||||
for (int _idx1 = 2; _idx1 > 0; _idx1--) {
|
||||
builder.putByte(g_c[_idx0-1][_idx1-1]);
|
||||
}
|
||||
builder.putByte(g_b[_idx0-1]);
|
||||
for (int _idx1 = 2; _idx1 > 0; _idx1--) {
|
||||
builder.putInt(g_a[_idx0-1][_idx1-1]);
|
||||
}
|
||||
}
|
||||
for (int _idx0 = 64; _idx0 > 0; _idx0--) {
|
||||
builder.putBoolean(f[_idx0-1]);
|
||||
}
|
||||
for (int _idx0 = 64; _idx0 > 0; _idx0--) {
|
||||
builder.putFloat(e[_idx0-1]);
|
||||
}
|
||||
for (int _idx0 = 64; _idx0 > 0; _idx0--) {
|
||||
builder.putByte((byte) d[_idx0-1]);
|
||||
}
|
||||
return builder.offset();
|
||||
}
|
||||
|
||||
public static final class Vector extends BaseVector {
|
||||
public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
|
||||
|
||||
public LargeArrayStruct get(int j) { return get(new LargeArrayStruct(), j); }
|
||||
public LargeArrayStruct get(LargeArrayStruct obj, int j) { return obj.__assign(__element(j), bb); }
|
||||
}
|
||||
public LargeArrayStructT unpack() {
|
||||
LargeArrayStructT _o = new LargeArrayStructT();
|
||||
unpackTo(_o);
|
||||
return _o;
|
||||
}
|
||||
public void unpackTo(LargeArrayStructT _o) {
|
||||
int[] _oD = _o.getD();
|
||||
for (int _j = 0; _j < 64; ++_j) { _oD[_j] = d(_j); }
|
||||
float[] _oE = _o.getE();
|
||||
for (int _j = 0; _j < 64; ++_j) { _oE[_j] = e(_j); }
|
||||
boolean[] _oF = _o.getF();
|
||||
for (int _j = 0; _j < 64; ++_j) { _oF[_j] = f(_j); }
|
||||
MyGame.Example.NestedStructT[] _oG = _o.getG();
|
||||
for (int _j = 0; _j < 64; ++_j) { _oG[_j] = g(_j).unpack(); }
|
||||
byte[] _oH = _o.getH();
|
||||
for (int _j = 0; _j < 64; ++_j) { _oH[_j] = h(_j); }
|
||||
}
|
||||
public static int pack(FlatBufferBuilder builder, LargeArrayStructT _o) {
|
||||
if (_o == null) return 0;
|
||||
int[] _d = _o.getD();
|
||||
float[] _e = _o.getE();
|
||||
boolean[] _f = _o.getF();
|
||||
int[][] _g_a = new int[64][2];
|
||||
for (int idx0 = 0; idx0 < 64; ++idx0) {for (int idx1 = 0; idx1 < 2; ++idx1) {_g_a[idx0][idx1] = _o.getG()[idx0].getA()[idx1];}}
|
||||
byte[] _g_b = new byte[64];
|
||||
for (int idx0 = 0; idx0 < 64; ++idx0) {_g_b[idx0] = _o.getG()[idx0].getB();}
|
||||
byte[][] _g_c = new byte[64][2];
|
||||
for (int idx0 = 0; idx0 < 64; ++idx0) {for (int idx1 = 0; idx1 < 2; ++idx1) {_g_c[idx0][idx1] = _o.getG()[idx0].getC()[idx1];}}
|
||||
long[][] _g_d = new long[64][2];
|
||||
for (int idx0 = 0; idx0 < 64; ++idx0) {for (int idx1 = 0; idx1 < 2; ++idx1) {_g_d[idx0][idx1] = _o.getG()[idx0].getD()[idx1];}}
|
||||
byte[] _h = _o.getH();
|
||||
return createLargeArrayStruct(
|
||||
builder,
|
||||
_d,
|
||||
_e,
|
||||
_f,
|
||||
_g_a,
|
||||
_g_b,
|
||||
_g_c,
|
||||
_g_d,
|
||||
_h);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace: Example
|
||||
|
||||
import flatbuffers
|
||||
from flatbuffers.compat import import_numpy
|
||||
from typing import Any
|
||||
from MyGame.Example.NestedStruct import NestedStruct
|
||||
np = import_numpy()
|
||||
|
||||
class LargeArrayStruct(object):
|
||||
__slots__ = ['_tab']
|
||||
|
||||
@classmethod
|
||||
def SizeOf(cls) -> int:
|
||||
return 2496
|
||||
|
||||
# LargeArrayStruct
|
||||
def Init(self, buf: bytes, pos: int):
|
||||
self._tab = flatbuffers.table.Table(buf, pos)
|
||||
|
||||
# LargeArrayStruct
|
||||
def D(self, j = None):
|
||||
if j is None:
|
||||
return [self._tab.Get(flatbuffers.number_types.Uint8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0 + i * 1)) for i in range(self.DLength())]
|
||||
elif j >= 0 and j < self.DLength():
|
||||
return self._tab.Get(flatbuffers.number_types.Uint8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0 + j * 1))
|
||||
else:
|
||||
return None
|
||||
|
||||
# LargeArrayStruct
|
||||
def DAsNumpy(self):
|
||||
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Uint8Flags, self._tab.Pos + 0, self.DLength())
|
||||
|
||||
# LargeArrayStruct
|
||||
def DLength(self) -> int:
|
||||
return 64
|
||||
|
||||
# LargeArrayStruct
|
||||
def DIsNone(self) -> bool:
|
||||
return False
|
||||
|
||||
# LargeArrayStruct
|
||||
def E(self, j = None):
|
||||
if j is None:
|
||||
return [self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(64 + i * 4)) for i in range(self.ELength())]
|
||||
elif j >= 0 and j < self.ELength():
|
||||
return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(64 + j * 4))
|
||||
else:
|
||||
return None
|
||||
|
||||
# LargeArrayStruct
|
||||
def EAsNumpy(self):
|
||||
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Float32Flags, self._tab.Pos + 64, self.ELength())
|
||||
|
||||
# LargeArrayStruct
|
||||
def ELength(self) -> int:
|
||||
return 64
|
||||
|
||||
# LargeArrayStruct
|
||||
def EIsNone(self) -> bool:
|
||||
return False
|
||||
|
||||
# LargeArrayStruct
|
||||
def F(self, j = None):
|
||||
if j is None:
|
||||
return [self._tab.Get(flatbuffers.number_types.BoolFlags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(320 + i * 1)) for i in range(self.FLength())]
|
||||
elif j >= 0 and j < self.FLength():
|
||||
return self._tab.Get(flatbuffers.number_types.BoolFlags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(320 + j * 1))
|
||||
else:
|
||||
return None
|
||||
|
||||
# LargeArrayStruct
|
||||
def FAsNumpy(self):
|
||||
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.BoolFlags, self._tab.Pos + 320, self.FLength())
|
||||
|
||||
# LargeArrayStruct
|
||||
def FLength(self) -> int:
|
||||
return 64
|
||||
|
||||
# LargeArrayStruct
|
||||
def FIsNone(self) -> bool:
|
||||
return False
|
||||
|
||||
# LargeArrayStruct
|
||||
def G(self, i: int) -> NestedStruct:
|
||||
obj = NestedStruct()
|
||||
obj.Init(self._tab.Bytes, self._tab.Pos + 384 + i * 32)
|
||||
return obj
|
||||
|
||||
# LargeArrayStruct
|
||||
def GLength(self) -> int:
|
||||
return 64
|
||||
|
||||
# LargeArrayStruct
|
||||
def GIsNone(self) -> bool:
|
||||
return False
|
||||
|
||||
# LargeArrayStruct
|
||||
def H(self, j = None):
|
||||
if j is None:
|
||||
return [self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(2432 + i * 1)) for i in range(self.HLength())]
|
||||
elif j >= 0 and j < self.HLength():
|
||||
return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(2432 + j * 1))
|
||||
else:
|
||||
return None
|
||||
|
||||
# LargeArrayStruct
|
||||
def HAsNumpy(self):
|
||||
return self._tab.GetArrayAsNumpy(flatbuffers.number_types.Int8Flags, self._tab.Pos + 2432, self.HLength())
|
||||
|
||||
# LargeArrayStruct
|
||||
def HLength(self) -> int:
|
||||
return 64
|
||||
|
||||
# LargeArrayStruct
|
||||
def HIsNone(self) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def CreateLargeArrayStruct(builder, d, e, f, g_a, g_b, g_c, g_d, h):
|
||||
builder.Prep(8, 2496)
|
||||
for _idx0 in range(64 , 0, -1):
|
||||
builder.PrependInt8(h[_idx0-1])
|
||||
for _idx0 in range(64 , 0, -1):
|
||||
builder.Prep(8, 32)
|
||||
for _idx1 in range(2 , 0, -1):
|
||||
builder.PrependInt64(g_d[_idx0-1][_idx1-1])
|
||||
builder.Pad(5)
|
||||
for _idx1 in range(2 , 0, -1):
|
||||
builder.PrependInt8(g_c[_idx0-1][_idx1-1])
|
||||
builder.PrependInt8(g_b[_idx0-1])
|
||||
for _idx1 in range(2 , 0, -1):
|
||||
builder.PrependInt32(g_a[_idx0-1][_idx1-1])
|
||||
for _idx0 in range(64 , 0, -1):
|
||||
builder.PrependBool(f[_idx0-1])
|
||||
for _idx0 in range(64 , 0, -1):
|
||||
builder.PrependFloat32(e[_idx0-1])
|
||||
for _idx0 in range(64 , 0, -1):
|
||||
builder.PrependUint8(d[_idx0-1])
|
||||
return builder.Offset()
|
||||
|
||||
import MyGame.Example.NestedStruct
|
||||
try:
|
||||
from typing import List
|
||||
except:
|
||||
pass
|
||||
|
||||
class LargeArrayStructT(object):
|
||||
|
||||
# LargeArrayStructT
|
||||
def __init__(
|
||||
self,
|
||||
d = None,
|
||||
e = None,
|
||||
f = None,
|
||||
g = None,
|
||||
h = None,
|
||||
):
|
||||
self.d = d # type: Optional[List[int]]
|
||||
self.e = e # type: Optional[List[float]]
|
||||
self.f = f # type: Optional[List[bool]]
|
||||
self.g = g # type: Optional[List[MyGame.Example.NestedStruct.NestedStructT]]
|
||||
self.h = h # type: Optional[List[int]]
|
||||
|
||||
@classmethod
|
||||
def InitFromBuf(cls, buf, pos):
|
||||
largeArrayStruct = LargeArrayStruct()
|
||||
largeArrayStruct.Init(buf, pos)
|
||||
return cls.InitFromObj(largeArrayStruct)
|
||||
|
||||
@classmethod
|
||||
def InitFromPackedBuf(cls, buf, pos=0):
|
||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
|
||||
return cls.InitFromBuf(buf, pos+n)
|
||||
|
||||
@classmethod
|
||||
def InitFromObj(cls, largeArrayStruct):
|
||||
x = LargeArrayStructT()
|
||||
x._UnPack(largeArrayStruct)
|
||||
return x
|
||||
|
||||
# LargeArrayStructT
|
||||
def _UnPack(self, largeArrayStruct):
|
||||
if largeArrayStruct is None:
|
||||
return
|
||||
if not largeArrayStruct.DIsNone():
|
||||
if np is None:
|
||||
self.d = []
|
||||
for i in range(largeArrayStruct.DLength()):
|
||||
self.d.append(largeArrayStruct.D(i))
|
||||
else:
|
||||
self.d = largeArrayStruct.DAsNumpy()
|
||||
if not largeArrayStruct.EIsNone():
|
||||
if np is None:
|
||||
self.e = []
|
||||
for i in range(largeArrayStruct.ELength()):
|
||||
self.e.append(largeArrayStruct.E(i))
|
||||
else:
|
||||
self.e = largeArrayStruct.EAsNumpy()
|
||||
if not largeArrayStruct.FIsNone():
|
||||
if np is None:
|
||||
self.f = []
|
||||
for i in range(largeArrayStruct.FLength()):
|
||||
self.f.append(largeArrayStruct.F(i))
|
||||
else:
|
||||
self.f = largeArrayStruct.FAsNumpy()
|
||||
if not largeArrayStruct.GIsNone():
|
||||
self.g = []
|
||||
for i in range(largeArrayStruct.GLength()):
|
||||
if largeArrayStruct.G(i) is None:
|
||||
self.g.append(None)
|
||||
else:
|
||||
nestedStruct_ = MyGame.Example.NestedStruct.NestedStructT.InitFromObj(largeArrayStruct.G(i))
|
||||
self.g.append(nestedStruct_)
|
||||
if not largeArrayStruct.HIsNone():
|
||||
if np is None:
|
||||
self.h = []
|
||||
for i in range(largeArrayStruct.HLength()):
|
||||
self.h.append(largeArrayStruct.H(i))
|
||||
else:
|
||||
self.h = largeArrayStruct.HAsNumpy()
|
||||
|
||||
# LargeArrayStructT
|
||||
def Pack(self, builder):
|
||||
return CreateLargeArrayStruct(builder, self.d, self.e, self.f, self.g.a, self.g.b, self.g.c, self.g.d, self.h)
|
||||
@@ -0,0 +1,60 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import flatbuffers
|
||||
import numpy as np
|
||||
|
||||
import typing
|
||||
from MyGame.Example.NestedStruct import NestedStruct, NestedStructT
|
||||
from MyGame.Example.TestEnum import TestEnum
|
||||
|
||||
uoffset: typing.TypeAlias = flatbuffers.number_types.UOffsetTFlags.py_type
|
||||
|
||||
class LargeArrayStruct(object):
|
||||
@classmethod
|
||||
def SizeOf(cls) -> int: ...
|
||||
|
||||
def Init(self, buf: bytes, pos: int) -> None: ...
|
||||
def D(self, i: int) -> typing.List[int]: ...
|
||||
def DAsNumpy(self) -> np.ndarray: ...
|
||||
def DLength(self) -> int: ...
|
||||
def DIsNone(self) -> bool: ...
|
||||
def E(self, i: int) -> typing.List[float]: ...
|
||||
def EAsNumpy(self) -> np.ndarray: ...
|
||||
def ELength(self) -> int: ...
|
||||
def EIsNone(self) -> bool: ...
|
||||
def F(self, i: int) -> typing.List[bool]: ...
|
||||
def FAsNumpy(self) -> np.ndarray: ...
|
||||
def FLength(self) -> int: ...
|
||||
def FIsNone(self) -> bool: ...
|
||||
def G(self, i: int) -> NestedStruct | None: ...
|
||||
def GLength(self) -> int: ...
|
||||
def GIsNone(self) -> bool: ...
|
||||
def H(self, i: int) -> typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C]: ...
|
||||
def HAsNumpy(self) -> np.ndarray: ...
|
||||
def HLength(self) -> int: ...
|
||||
def HIsNone(self) -> bool: ...
|
||||
class LargeArrayStructT(object):
|
||||
d: typing.List[int]
|
||||
e: typing.List[float]
|
||||
f: typing.List[bool]
|
||||
g: typing.List[NestedStructT]
|
||||
h: typing.List[typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C]]
|
||||
def __init__(
|
||||
self,
|
||||
d: typing.List[int] | None = ...,
|
||||
e: typing.List[float] | None = ...,
|
||||
f: typing.List[bool] | None = ...,
|
||||
g: typing.List['NestedStructT'] | None = ...,
|
||||
h: typing.List[typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C]] | None = ...,
|
||||
) -> None: ...
|
||||
@classmethod
|
||||
def InitFromBuf(cls, buf: bytes, pos: int) -> LargeArrayStructT: ...
|
||||
@classmethod
|
||||
def InitFromPackedBuf(cls, buf: bytes, pos: int = 0) -> LargeArrayStructT: ...
|
||||
@classmethod
|
||||
def InitFromObj(cls, largeArrayStruct: LargeArrayStruct) -> LargeArrayStructT: ...
|
||||
def _UnPack(self, largeArrayStruct: LargeArrayStruct) -> None: ...
|
||||
def Pack(self, builder: flatbuffers.Builder) -> None: ...
|
||||
|
||||
def CreateLargeArrayStruct(builder: flatbuffers.Builder, d: int, e: float, f: bool, g_a: int, g_b: typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C], g_c: typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C], g_d: int, h: typing.Literal[TestEnum.A, TestEnum.B, TestEnum.C]) -> uoffset: ...
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
package MyGame.Example;
|
||||
|
||||
import com.google.flatbuffers.BaseVector;
|
||||
import com.google.flatbuffers.BooleanVector;
|
||||
import com.google.flatbuffers.ByteVector;
|
||||
import com.google.flatbuffers.Constants;
|
||||
import com.google.flatbuffers.DoubleVector;
|
||||
import com.google.flatbuffers.FlatBufferBuilder;
|
||||
import com.google.flatbuffers.FloatVector;
|
||||
import com.google.flatbuffers.IntVector;
|
||||
import com.google.flatbuffers.LongVector;
|
||||
import com.google.flatbuffers.ShortVector;
|
||||
import com.google.flatbuffers.StringVector;
|
||||
import com.google.flatbuffers.Struct;
|
||||
import com.google.flatbuffers.UnionVector;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class LargeArrayStructT {
|
||||
private int[] d;
|
||||
private float[] e;
|
||||
private boolean[] f;
|
||||
private MyGame.Example.NestedStructT[] g;
|
||||
private byte[] h;
|
||||
|
||||
public int[] getD() { return d; }
|
||||
|
||||
public void setD(int[] d) { if (d != null && d.length == 64) this.d = d; }
|
||||
|
||||
public float[] getE() { return e; }
|
||||
|
||||
public void setE(float[] e) { if (e != null && e.length == 64) this.e = e; }
|
||||
|
||||
public boolean[] getF() { return f; }
|
||||
|
||||
public void setF(boolean[] f) { if (f != null && f.length == 64) this.f = f; }
|
||||
|
||||
public MyGame.Example.NestedStructT[] getG() { return g; }
|
||||
|
||||
public void setG(MyGame.Example.NestedStructT[] g) { if (g != null && g.length == 64) this.g = g; }
|
||||
|
||||
public byte[] getH() { return h; }
|
||||
|
||||
public void setH(byte[] h) { if (h != null && h.length == 64) this.h = h; }
|
||||
|
||||
|
||||
public LargeArrayStructT() {
|
||||
this.d = new int[64];
|
||||
this.e = new float[64];
|
||||
this.f = new boolean[64];
|
||||
this.g = new MyGame.Example.NestedStructT[64];
|
||||
this.h = new byte[64];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,921 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
// @generated
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod my_game {
|
||||
|
||||
extern crate alloc;
|
||||
#[allow(unused_imports, dead_code)]
|
||||
pub mod example {
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MIN_TEST_ENUM: i8 = 0;
|
||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
pub const ENUM_MAX_TEST_ENUM: i8 = 2;
|
||||
#[deprecated(since = "2.0.0", note = "Use associated constants instead. This will no longer be generated in 2021.")]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub const ENUM_VALUES_TEST_ENUM: [TestEnum; 3] = [
|
||||
TestEnum::A,
|
||||
TestEnum::B,
|
||||
TestEnum::C,
|
||||
];
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
#[repr(transparent)]
|
||||
pub struct TestEnum(pub i8);
|
||||
#[allow(non_upper_case_globals)]
|
||||
impl TestEnum {
|
||||
pub const A: Self = Self(0);
|
||||
pub const B: Self = Self(1);
|
||||
pub const C: Self = Self(2);
|
||||
|
||||
pub const ENUM_MIN: i8 = 0;
|
||||
pub const ENUM_MAX: i8 = 2;
|
||||
pub const ENUM_VALUES: &'static [Self] = &[
|
||||
Self::A,
|
||||
Self::B,
|
||||
Self::C,
|
||||
];
|
||||
/// Returns the variant's name or "" if unknown.
|
||||
pub fn variant_name(self) -> Option<&'static str> {
|
||||
match self {
|
||||
Self::A => Some("A"),
|
||||
Self::B => Some("B"),
|
||||
Self::C => Some("C"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl ::core::fmt::Debug for TestEnum {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||
if let Some(name) = self.variant_name() {
|
||||
f.write_str(name)
|
||||
} else {
|
||||
f.write_fmt(format_args!("<UNKNOWN {:?}>", self.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'a> ::flatbuffers::Follow<'a> for TestEnum {
|
||||
type Inner = Self;
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
let b = unsafe { ::flatbuffers::read_scalar_at::<i8>(buf, loc) };
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::flatbuffers::Push for TestEnum {
|
||||
type Output = TestEnum;
|
||||
#[inline]
|
||||
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||
unsafe { ::flatbuffers::emplace_scalar::<i8>(dst, self.0) };
|
||||
}
|
||||
}
|
||||
|
||||
impl ::flatbuffers::EndianScalar for TestEnum {
|
||||
type Scalar = i8;
|
||||
#[inline]
|
||||
fn to_little_endian(self) -> i8 {
|
||||
self.0.to_le()
|
||||
}
|
||||
#[inline]
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn from_little_endian(v: i8) -> Self {
|
||||
let b = i8::from_le(v);
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ::flatbuffers::Verifiable for TestEnum {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||
i8::run_verifier(v, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::flatbuffers::SimpleToVerifyInSlice for TestEnum {}
|
||||
// struct NestedStruct, aligned to 8
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub struct NestedStruct(pub [u8; 32]);
|
||||
impl Default for NestedStruct {
|
||||
fn default() -> Self {
|
||||
Self([0; 32])
|
||||
}
|
||||
}
|
||||
impl ::core::fmt::Debug for NestedStruct {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||
f.debug_struct("NestedStruct")
|
||||
.field("a", &self.a())
|
||||
.field("b", &self.b())
|
||||
.field("c", &self.c())
|
||||
.field("d", &self.d())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::flatbuffers::SimpleToVerifyInSlice for NestedStruct {}
|
||||
impl<'a> ::flatbuffers::Follow<'a> for NestedStruct {
|
||||
type Inner = &'a NestedStruct;
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
unsafe { <&'a NestedStruct>::follow(buf, loc) }
|
||||
}
|
||||
}
|
||||
impl<'a> ::flatbuffers::Follow<'a> for &'a NestedStruct {
|
||||
type Inner = &'a NestedStruct;
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
unsafe { ::flatbuffers::follow_cast_ref::<NestedStruct>(buf, loc) }
|
||||
}
|
||||
}
|
||||
impl<'b> ::flatbuffers::Push for NestedStruct {
|
||||
type Output = NestedStruct;
|
||||
#[inline]
|
||||
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||
let src = unsafe { ::core::slice::from_raw_parts(self as *const NestedStruct as *const u8, <Self as ::flatbuffers::Push>::size()) };
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
#[inline]
|
||||
fn alignment() -> ::flatbuffers::PushAlignment {
|
||||
::flatbuffers::PushAlignment::new(8)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ::flatbuffers::Verifiable for NestedStruct {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> NestedStruct {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
a: &[i32; 2],
|
||||
b: TestEnum,
|
||||
c: &[TestEnum; 2],
|
||||
d: &[i64; 2],
|
||||
) -> Self {
|
||||
let mut s = Self([0; 32]);
|
||||
s.set_a(a);
|
||||
s.set_b(b);
|
||||
s.set_c(c);
|
||||
s.set_d(d);
|
||||
s
|
||||
}
|
||||
|
||||
pub fn a(&'a self) -> ::flatbuffers::Array<'a, i32, 2> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 0) }
|
||||
}
|
||||
|
||||
pub fn set_a(&mut self, items: &[i32; 2]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe { ::flatbuffers::emplace_scalar_array(&mut self.0, 0, items) };
|
||||
}
|
||||
|
||||
pub fn b(&self) -> TestEnum {
|
||||
let mut mem = ::core::mem::MaybeUninit::<<TestEnum as ::flatbuffers::EndianScalar>::Scalar>::uninit();
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
::flatbuffers::EndianScalar::from_little_endian(unsafe {
|
||||
::core::ptr::copy_nonoverlapping(
|
||||
self.0[8..].as_ptr(),
|
||||
mem.as_mut_ptr() as *mut u8,
|
||||
::core::mem::size_of::<<TestEnum as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||
);
|
||||
mem.assume_init()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_b(&mut self, x: TestEnum) {
|
||||
let x_le = ::flatbuffers::EndianScalar::to_little_endian(x);
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
unsafe {
|
||||
::core::ptr::copy_nonoverlapping(
|
||||
&x_le as *const _ as *const u8,
|
||||
self.0[8..].as_mut_ptr(),
|
||||
::core::mem::size_of::<<TestEnum as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn c(&'a self) -> ::flatbuffers::Array<'a, TestEnum, 2> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 9) }
|
||||
}
|
||||
|
||||
pub fn set_c(&mut self, x: &[TestEnum; 2]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe {
|
||||
::core::ptr::copy(
|
||||
x.as_ptr() as *const u8,
|
||||
self.0.as_mut_ptr().add(9),
|
||||
2,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn d(&'a self) -> ::flatbuffers::Array<'a, i64, 2> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 16) }
|
||||
}
|
||||
|
||||
pub fn set_d(&mut self, items: &[i64; 2]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe { ::flatbuffers::emplace_scalar_array(&mut self.0, 16, items) };
|
||||
}
|
||||
|
||||
pub fn unpack(&self) -> NestedStructT {
|
||||
NestedStructT {
|
||||
a: self.a().into(),
|
||||
b: self.b(),
|
||||
c: self.c().into(),
|
||||
d: self.d().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct NestedStructT {
|
||||
pub a: [i32; 2],
|
||||
pub b: TestEnum,
|
||||
pub c: [TestEnum; 2],
|
||||
pub d: [i64; 2],
|
||||
}
|
||||
impl Default for NestedStructT {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
a: [0; 2],
|
||||
b: TestEnum::A,
|
||||
c: ::flatbuffers::array_init(|_| Default::default()),
|
||||
d: [0; 2],
|
||||
}
|
||||
}
|
||||
}
|
||||
impl NestedStructT {
|
||||
pub fn pack(&self) -> NestedStruct {
|
||||
NestedStruct::new(
|
||||
&self.a,
|
||||
self.b,
|
||||
&self.c,
|
||||
&self.d,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// struct ArrayStruct, aligned to 8
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub struct ArrayStruct(pub [u8; 160]);
|
||||
impl Default for ArrayStruct {
|
||||
fn default() -> Self {
|
||||
Self([0; 160])
|
||||
}
|
||||
}
|
||||
impl ::core::fmt::Debug for ArrayStruct {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||
f.debug_struct("ArrayStruct")
|
||||
.field("a", &self.a())
|
||||
.field("b", &self.b())
|
||||
.field("c", &self.c())
|
||||
.field("d", &self.d())
|
||||
.field("e", &self.e())
|
||||
.field("f", &self.f())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::flatbuffers::SimpleToVerifyInSlice for ArrayStruct {}
|
||||
impl<'a> ::flatbuffers::Follow<'a> for ArrayStruct {
|
||||
type Inner = &'a ArrayStruct;
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
unsafe { <&'a ArrayStruct>::follow(buf, loc) }
|
||||
}
|
||||
}
|
||||
impl<'a> ::flatbuffers::Follow<'a> for &'a ArrayStruct {
|
||||
type Inner = &'a ArrayStruct;
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
unsafe { ::flatbuffers::follow_cast_ref::<ArrayStruct>(buf, loc) }
|
||||
}
|
||||
}
|
||||
impl<'b> ::flatbuffers::Push for ArrayStruct {
|
||||
type Output = ArrayStruct;
|
||||
#[inline]
|
||||
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||
let src = unsafe { ::core::slice::from_raw_parts(self as *const ArrayStruct as *const u8, <Self as ::flatbuffers::Push>::size()) };
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
#[inline]
|
||||
fn alignment() -> ::flatbuffers::PushAlignment {
|
||||
::flatbuffers::PushAlignment::new(8)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ::flatbuffers::Verifiable for ArrayStruct {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ArrayStruct {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
a: f32,
|
||||
b: &[i32; 15],
|
||||
c: i8,
|
||||
d: &[NestedStruct; 2],
|
||||
e: i32,
|
||||
f: &[i64; 2],
|
||||
) -> Self {
|
||||
let mut s = Self([0; 160]);
|
||||
s.set_a(a);
|
||||
s.set_b(b);
|
||||
s.set_c(c);
|
||||
s.set_d(d);
|
||||
s.set_e(e);
|
||||
s.set_f(f);
|
||||
s
|
||||
}
|
||||
|
||||
pub fn a(&self) -> f32 {
|
||||
let mut mem = ::core::mem::MaybeUninit::<<f32 as ::flatbuffers::EndianScalar>::Scalar>::uninit();
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
::flatbuffers::EndianScalar::from_little_endian(unsafe {
|
||||
::core::ptr::copy_nonoverlapping(
|
||||
self.0[0..].as_ptr(),
|
||||
mem.as_mut_ptr() as *mut u8,
|
||||
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||
);
|
||||
mem.assume_init()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_a(&mut self, x: f32) {
|
||||
let x_le = ::flatbuffers::EndianScalar::to_little_endian(x);
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
unsafe {
|
||||
::core::ptr::copy_nonoverlapping(
|
||||
&x_le as *const _ as *const u8,
|
||||
self.0[0..].as_mut_ptr(),
|
||||
::core::mem::size_of::<<f32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn b(&'a self) -> ::flatbuffers::Array<'a, i32, 15> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 4) }
|
||||
}
|
||||
|
||||
pub fn set_b(&mut self, items: &[i32; 15]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe { ::flatbuffers::emplace_scalar_array(&mut self.0, 4, items) };
|
||||
}
|
||||
|
||||
pub fn c(&self) -> i8 {
|
||||
let mut mem = ::core::mem::MaybeUninit::<<i8 as ::flatbuffers::EndianScalar>::Scalar>::uninit();
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
::flatbuffers::EndianScalar::from_little_endian(unsafe {
|
||||
::core::ptr::copy_nonoverlapping(
|
||||
self.0[64..].as_ptr(),
|
||||
mem.as_mut_ptr() as *mut u8,
|
||||
::core::mem::size_of::<<i8 as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||
);
|
||||
mem.assume_init()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_c(&mut self, x: i8) {
|
||||
let x_le = ::flatbuffers::EndianScalar::to_little_endian(x);
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
unsafe {
|
||||
::core::ptr::copy_nonoverlapping(
|
||||
&x_le as *const _ as *const u8,
|
||||
self.0[64..].as_mut_ptr(),
|
||||
::core::mem::size_of::<<i8 as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn d(&'a self) -> ::flatbuffers::Array<'a, NestedStruct, 2> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 72) }
|
||||
}
|
||||
|
||||
pub fn set_d(&mut self, x: &[NestedStruct; 2]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe {
|
||||
::core::ptr::copy(
|
||||
x.as_ptr() as *const u8,
|
||||
self.0.as_mut_ptr().add(72),
|
||||
64,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn e(&self) -> i32 {
|
||||
let mut mem = ::core::mem::MaybeUninit::<<i32 as ::flatbuffers::EndianScalar>::Scalar>::uninit();
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
::flatbuffers::EndianScalar::from_little_endian(unsafe {
|
||||
::core::ptr::copy_nonoverlapping(
|
||||
self.0[136..].as_ptr(),
|
||||
mem.as_mut_ptr() as *mut u8,
|
||||
::core::mem::size_of::<<i32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||
);
|
||||
mem.assume_init()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_e(&mut self, x: i32) {
|
||||
let x_le = ::flatbuffers::EndianScalar::to_little_endian(x);
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid value in this slot
|
||||
unsafe {
|
||||
::core::ptr::copy_nonoverlapping(
|
||||
&x_le as *const _ as *const u8,
|
||||
self.0[136..].as_mut_ptr(),
|
||||
::core::mem::size_of::<<i32 as ::flatbuffers::EndianScalar>::Scalar>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn f(&'a self) -> ::flatbuffers::Array<'a, i64, 2> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 144) }
|
||||
}
|
||||
|
||||
pub fn set_f(&mut self, items: &[i64; 2]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe { ::flatbuffers::emplace_scalar_array(&mut self.0, 144, items) };
|
||||
}
|
||||
|
||||
pub fn unpack(&self) -> ArrayStructT {
|
||||
ArrayStructT {
|
||||
a: self.a(),
|
||||
b: self.b().into(),
|
||||
c: self.c(),
|
||||
d: { let d = self.d(); ::flatbuffers::array_init(|i| d.get(i).unpack()) },
|
||||
e: self.e(),
|
||||
f: self.f().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct ArrayStructT {
|
||||
pub a: f32,
|
||||
pub b: [i32; 15],
|
||||
pub c: i8,
|
||||
pub d: [NestedStructT; 2],
|
||||
pub e: i32,
|
||||
pub f: [i64; 2],
|
||||
}
|
||||
impl Default for ArrayStructT {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
a: 0.0,
|
||||
b: [0; 15],
|
||||
c: 0,
|
||||
d: ::flatbuffers::array_init(|_| Default::default()),
|
||||
e: 0,
|
||||
f: [0; 2],
|
||||
}
|
||||
}
|
||||
}
|
||||
impl ArrayStructT {
|
||||
pub fn pack(&self) -> ArrayStruct {
|
||||
ArrayStruct::new(
|
||||
self.a,
|
||||
&self.b,
|
||||
self.c,
|
||||
&::flatbuffers::array_init(|i| self.d[i].pack()),
|
||||
self.e,
|
||||
&self.f,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// struct LargeArrayStruct, aligned to 4
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub struct LargeArrayStruct(pub [u8; 384]);
|
||||
impl Default for LargeArrayStruct {
|
||||
fn default() -> Self {
|
||||
Self([0; 384])
|
||||
}
|
||||
}
|
||||
impl ::core::fmt::Debug for LargeArrayStruct {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||
f.debug_struct("LargeArrayStruct")
|
||||
.field("d", &self.d())
|
||||
.field("e", &self.e())
|
||||
.field("f", &self.f())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::flatbuffers::SimpleToVerifyInSlice for LargeArrayStruct {}
|
||||
impl<'a> ::flatbuffers::Follow<'a> for LargeArrayStruct {
|
||||
type Inner = &'a LargeArrayStruct;
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
unsafe { <&'a LargeArrayStruct>::follow(buf, loc) }
|
||||
}
|
||||
}
|
||||
impl<'a> ::flatbuffers::Follow<'a> for &'a LargeArrayStruct {
|
||||
type Inner = &'a LargeArrayStruct;
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
unsafe { ::flatbuffers::follow_cast_ref::<LargeArrayStruct>(buf, loc) }
|
||||
}
|
||||
}
|
||||
impl<'b> ::flatbuffers::Push for LargeArrayStruct {
|
||||
type Output = LargeArrayStruct;
|
||||
#[inline]
|
||||
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||
let src = unsafe { ::core::slice::from_raw_parts(self as *const LargeArrayStruct as *const u8, <Self as ::flatbuffers::Push>::size()) };
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
#[inline]
|
||||
fn alignment() -> ::flatbuffers::PushAlignment {
|
||||
::flatbuffers::PushAlignment::new(4)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ::flatbuffers::Verifiable for LargeArrayStruct {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> LargeArrayStruct {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
d: &[u8; 64],
|
||||
e: &[f32; 64],
|
||||
f: &[bool; 64],
|
||||
) -> Self {
|
||||
let mut s = Self([0; 384]);
|
||||
s.set_d(d);
|
||||
s.set_e(e);
|
||||
s.set_f(f);
|
||||
s
|
||||
}
|
||||
|
||||
pub fn d(&'a self) -> ::flatbuffers::Array<'a, u8, 64> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 0) }
|
||||
}
|
||||
|
||||
pub fn set_d(&mut self, items: &[u8; 64]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe { ::flatbuffers::emplace_scalar_array(&mut self.0, 0, items) };
|
||||
}
|
||||
|
||||
pub fn e(&'a self) -> ::flatbuffers::Array<'a, f32, 64> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 64) }
|
||||
}
|
||||
|
||||
pub fn set_e(&mut self, items: &[f32; 64]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe { ::flatbuffers::emplace_scalar_array(&mut self.0, 64, items) };
|
||||
}
|
||||
|
||||
pub fn f(&'a self) -> ::flatbuffers::Array<'a, bool, 64> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 320) }
|
||||
}
|
||||
|
||||
pub fn set_f(&mut self, items: &[bool; 64]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe { ::flatbuffers::emplace_scalar_array(&mut self.0, 320, items) };
|
||||
}
|
||||
|
||||
pub fn unpack(&self) -> LargeArrayStructT {
|
||||
LargeArrayStructT {
|
||||
d: self.d().into(),
|
||||
e: self.e().into(),
|
||||
f: self.f().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct LargeArrayStructT {
|
||||
pub d: [u8; 64],
|
||||
pub e: [f32; 64],
|
||||
pub f: [bool; 64],
|
||||
}
|
||||
impl Default for LargeArrayStructT {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
d: [0; 64],
|
||||
e: [0.0; 64],
|
||||
f: [false; 64],
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LargeArrayStructT {
|
||||
pub fn pack(&self) -> LargeArrayStruct {
|
||||
LargeArrayStruct::new(
|
||||
&self.d,
|
||||
&self.e,
|
||||
&self.f,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ArrayTableOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
||||
pub struct ArrayTable<'a> {
|
||||
pub _tab: ::flatbuffers::Table<'a>,
|
||||
}
|
||||
|
||||
impl<'a> ::flatbuffers::Follow<'a> for ArrayTable<'a> {
|
||||
type Inner = ArrayTable<'a>;
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self { _tab: unsafe { ::flatbuffers::Table::new(buf, loc) } }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ArrayTable<'a> {
|
||||
pub const VT_A: ::flatbuffers::VOffsetT = 4;
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn init_from_table(table: ::flatbuffers::Table<'a>) -> Self {
|
||||
ArrayTable { _tab: table }
|
||||
}
|
||||
#[allow(unused_mut)]
|
||||
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: ::flatbuffers::Allocator + 'bldr>(
|
||||
_fbb: &'mut_bldr mut ::flatbuffers::FlatBufferBuilder<'bldr, A>,
|
||||
args: &'args ArrayTableArgs<'args>
|
||||
) -> ::flatbuffers::WIPOffset<ArrayTable<'bldr>> {
|
||||
let mut builder = ArrayTableBuilder::new(_fbb);
|
||||
if let Some(x) = args.a { builder.add_a(x); }
|
||||
builder.finish()
|
||||
}
|
||||
|
||||
pub fn unpack(&self) -> ArrayTableT {
|
||||
let a = self.a().map(|x| {
|
||||
x.unpack()
|
||||
});
|
||||
ArrayTableT {
|
||||
a,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn a(&self) -> Option<&'a ArrayStruct> {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<ArrayStruct>(ArrayTable::VT_A, None)}
|
||||
}
|
||||
}
|
||||
|
||||
impl ::flatbuffers::Verifiable for ArrayTable<'_> {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<ArrayStruct>("a", Self::VT_A, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct ArrayTableArgs<'a> {
|
||||
pub a: Option<&'a ArrayStruct>,
|
||||
}
|
||||
impl<'a> Default for ArrayTableArgs<'a> {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
ArrayTableArgs {
|
||||
a: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ArrayTableBuilder<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> {
|
||||
fbb_: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
||||
start_: ::flatbuffers::WIPOffset<::flatbuffers::TableUnfinishedWIPOffset>,
|
||||
}
|
||||
impl<'a: 'b, 'b, A: ::flatbuffers::Allocator + 'a> ArrayTableBuilder<'a, 'b, A> {
|
||||
#[inline]
|
||||
pub fn add_a(&mut self, a: &ArrayStruct) {
|
||||
self.fbb_.push_slot_always::<&ArrayStruct>(ArrayTable::VT_A, a);
|
||||
}
|
||||
#[inline]
|
||||
pub fn new(_fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>) -> ArrayTableBuilder<'a, 'b, A> {
|
||||
let start = _fbb.start_table();
|
||||
ArrayTableBuilder {
|
||||
fbb_: _fbb,
|
||||
start_: start,
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn finish(self) -> ::flatbuffers::WIPOffset<ArrayTable<'a>> {
|
||||
let o = self.fbb_.end_table(self.start_);
|
||||
::flatbuffers::WIPOffset::new(o.value())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::core::fmt::Debug for ArrayTable<'_> {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
|
||||
let mut ds = f.debug_struct("ArrayTable");
|
||||
ds.field("a", &self.a());
|
||||
ds.finish()
|
||||
}
|
||||
}
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct ArrayTableT {
|
||||
pub a: Option<ArrayStructT>,
|
||||
}
|
||||
impl Default for ArrayTableT {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
a: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl ArrayTableT {
|
||||
pub fn pack<'b, A: ::flatbuffers::Allocator + 'b>(
|
||||
&self,
|
||||
_fbb: &mut ::flatbuffers::FlatBufferBuilder<'b, A>
|
||||
) -> ::flatbuffers::WIPOffset<ArrayTable<'b>> {
|
||||
let a_tmp = self.a.as_ref().map(|x| x.pack());
|
||||
let a = a_tmp.as_ref();
|
||||
ArrayTable::create(_fbb, &ArrayTableArgs{
|
||||
a,
|
||||
})
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a `ArrayTable`
|
||||
/// and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_array_table_unchecked`.
|
||||
pub fn root_as_array_table(buf: &[u8]) -> Result<ArrayTable<'_>, ::flatbuffers::InvalidFlatbuffer> {
|
||||
::flatbuffers::root::<ArrayTable>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a size prefixed
|
||||
/// `ArrayTable` and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `size_prefixed_root_as_array_table_unchecked`.
|
||||
pub fn size_prefixed_root_as_array_table(buf: &[u8]) -> Result<ArrayTable<'_>, ::flatbuffers::InvalidFlatbuffer> {
|
||||
::flatbuffers::size_prefixed_root::<ArrayTable>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies, with the given options, that a buffer of bytes
|
||||
/// contains a `ArrayTable` and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_array_table_unchecked`.
|
||||
pub fn root_as_array_table_with_opts<'b, 'o>(
|
||||
opts: &'o ::flatbuffers::VerifierOptions,
|
||||
buf: &'b [u8],
|
||||
) -> Result<ArrayTable<'b>, ::flatbuffers::InvalidFlatbuffer> {
|
||||
::flatbuffers::root_with_opts::<ArrayTable<'b>>(opts, buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies, with the given verifier options, that a buffer of
|
||||
/// bytes contains a size prefixed `ArrayTable` and returns
|
||||
/// it. Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_array_table_unchecked`.
|
||||
pub fn size_prefixed_root_as_array_table_with_opts<'b, 'o>(
|
||||
opts: &'o ::flatbuffers::VerifierOptions,
|
||||
buf: &'b [u8],
|
||||
) -> Result<ArrayTable<'b>, ::flatbuffers::InvalidFlatbuffer> {
|
||||
::flatbuffers::size_prefixed_root_with_opts::<ArrayTable<'b>>(opts, buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Assumes, without verification, that a buffer of bytes contains a ArrayTable and returns it.
|
||||
/// # Safety
|
||||
/// Callers must trust the given bytes do indeed contain a valid `ArrayTable`.
|
||||
pub unsafe fn root_as_array_table_unchecked(buf: &[u8]) -> ArrayTable<'_> {
|
||||
unsafe { ::flatbuffers::root_unchecked::<ArrayTable>(buf) }
|
||||
}
|
||||
#[inline]
|
||||
/// Assumes, without verification, that a buffer of bytes contains a size prefixed ArrayTable and returns it.
|
||||
/// # Safety
|
||||
/// Callers must trust the given bytes do indeed contain a valid size prefixed `ArrayTable`.
|
||||
pub unsafe fn size_prefixed_root_as_array_table_unchecked(buf: &[u8]) -> ArrayTable<'_> {
|
||||
unsafe { ::flatbuffers::size_prefixed_root_unchecked::<ArrayTable>(buf) }
|
||||
}
|
||||
pub const ARRAY_TABLE_IDENTIFIER: &str = "ARRT";
|
||||
|
||||
#[inline]
|
||||
pub fn array_table_buffer_has_identifier(buf: &[u8]) -> bool {
|
||||
::flatbuffers::buffer_has_identifier(buf, ARRAY_TABLE_IDENTIFIER, false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn array_table_size_prefixed_buffer_has_identifier(buf: &[u8]) -> bool {
|
||||
::flatbuffers::buffer_has_identifier(buf, ARRAY_TABLE_IDENTIFIER, true)
|
||||
}
|
||||
|
||||
pub const ARRAY_TABLE_EXTENSION: &str = "mon";
|
||||
|
||||
#[inline]
|
||||
pub fn finish_array_table_buffer<'a, 'b, A: ::flatbuffers::Allocator + 'a>(
|
||||
fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>,
|
||||
root: ::flatbuffers::WIPOffset<ArrayTable<'a>>) {
|
||||
fbb.finish(root, Some(ARRAY_TABLE_IDENTIFIER));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn finish_size_prefixed_array_table_buffer<'a, 'b, A: ::flatbuffers::Allocator + 'a>(fbb: &'b mut ::flatbuffers::FlatBufferBuilder<'a, A>, root: ::flatbuffers::WIPOffset<ArrayTable<'a>>) {
|
||||
fbb.finish_size_prefixed(root, Some(ARRAY_TABLE_IDENTIFIER));
|
||||
}
|
||||
} // pub mod Example
|
||||
} // pub mod MyGame
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
// @generated
|
||||
extern crate alloc;
|
||||
use super::*;
|
||||
|
||||
// struct LargeArrayStruct, aligned to 8
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub struct LargeArrayStruct(pub [u8; 2496]);
|
||||
|
||||
impl Default for LargeArrayStruct {
|
||||
fn default() -> Self {
|
||||
Self([0; 2496])
|
||||
}
|
||||
}
|
||||
|
||||
impl ::core::fmt::Debug for LargeArrayStruct {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||
f.debug_struct("LargeArrayStruct")
|
||||
.field("d", &self.d())
|
||||
.field("e", &self.e())
|
||||
.field("f", &self.f())
|
||||
.field("g", &self.g())
|
||||
.field("h", &self.h())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::flatbuffers::SimpleToVerifyInSlice for LargeArrayStruct {}
|
||||
|
||||
impl<'a> ::flatbuffers::Follow<'a> for LargeArrayStruct {
|
||||
type Inner = &'a LargeArrayStruct;
|
||||
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
unsafe { <&'a LargeArrayStruct>::follow(buf, loc) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ::flatbuffers::Follow<'a> for &'a LargeArrayStruct {
|
||||
type Inner = &'a LargeArrayStruct;
|
||||
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
unsafe { ::flatbuffers::follow_cast_ref::<LargeArrayStruct>(buf, loc) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> ::flatbuffers::Push for LargeArrayStruct {
|
||||
type Output = LargeArrayStruct;
|
||||
|
||||
#[inline]
|
||||
unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {
|
||||
let src = unsafe { ::core::slice::from_raw_parts(self as *const LargeArrayStruct as *const u8, <Self as ::flatbuffers::Push>::size()) };
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn alignment() -> ::flatbuffers::PushAlignment {
|
||||
::flatbuffers::PushAlignment::new(8)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ::flatbuffers::Verifiable for LargeArrayStruct {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut ::flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), ::flatbuffers::InvalidFlatbuffer> {
|
||||
v.in_buffer::<Self>(pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> LargeArrayStruct {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
d: &[u8; 64],
|
||||
e: &[f32; 64],
|
||||
f: &[bool; 64],
|
||||
g: &[NestedStruct; 64],
|
||||
h: &[TestEnum; 64],
|
||||
) -> Self {
|
||||
let mut s = Self([0; 2496]);
|
||||
s.set_d(d);
|
||||
s.set_e(e);
|
||||
s.set_f(f);
|
||||
s.set_g(g);
|
||||
s.set_h(h);
|
||||
s
|
||||
}
|
||||
|
||||
pub const fn get_fully_qualified_name() -> &'static str {
|
||||
"MyGame.Example.LargeArrayStruct"
|
||||
}
|
||||
|
||||
pub fn d(&'a self) -> ::flatbuffers::Array<'a, u8, 64> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 0) }
|
||||
}
|
||||
|
||||
pub fn set_d(&mut self, items: &[u8; 64]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe { ::flatbuffers::emplace_scalar_array(&mut self.0, 0, items) };
|
||||
}
|
||||
|
||||
pub fn e(&'a self) -> ::flatbuffers::Array<'a, f32, 64> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 64) }
|
||||
}
|
||||
|
||||
pub fn set_e(&mut self, items: &[f32; 64]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe { ::flatbuffers::emplace_scalar_array(&mut self.0, 64, items) };
|
||||
}
|
||||
|
||||
pub fn f(&'a self) -> ::flatbuffers::Array<'a, bool, 64> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 320) }
|
||||
}
|
||||
|
||||
pub fn set_f(&mut self, items: &[bool; 64]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe { ::flatbuffers::emplace_scalar_array(&mut self.0, 320, items) };
|
||||
}
|
||||
|
||||
pub fn g(&'a self) -> ::flatbuffers::Array<'a, NestedStruct, 64> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 384) }
|
||||
}
|
||||
|
||||
pub fn set_g(&mut self, x: &[NestedStruct; 64]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe {
|
||||
::core::ptr::copy(
|
||||
x.as_ptr() as *const u8,
|
||||
self.0.as_mut_ptr().add(384),
|
||||
2048,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn h(&'a self) -> ::flatbuffers::Array<'a, TestEnum, 64> {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
use ::flatbuffers::Follow;
|
||||
unsafe { ::flatbuffers::Array::follow(&self.0, 2432) }
|
||||
}
|
||||
|
||||
pub fn set_h(&mut self, x: &[TestEnum; 64]) {
|
||||
// Safety:
|
||||
// Created from a valid Table for this object
|
||||
// Which contains a valid array in this slot
|
||||
unsafe {
|
||||
::core::ptr::copy(
|
||||
x.as_ptr() as *const u8,
|
||||
self.0.as_mut_ptr().add(2432),
|
||||
64,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unpack(&self) -> LargeArrayStructT {
|
||||
LargeArrayStructT {
|
||||
d: self.d().into(),
|
||||
e: self.e().into(),
|
||||
f: self.f().into(),
|
||||
g: { let g = self.g(); ::flatbuffers::array_init(|i| g.get(i).unpack()) },
|
||||
h: self.h().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct LargeArrayStructT {
|
||||
pub d: [u8; 64],
|
||||
pub e: [f32; 64],
|
||||
pub f: [bool; 64],
|
||||
pub g: [NestedStructT; 64],
|
||||
pub h: [TestEnum; 64],
|
||||
}
|
||||
impl Default for LargeArrayStructT {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
d: [0; 64],
|
||||
e: [0.0; 64],
|
||||
f: [false; 64],
|
||||
g: ::flatbuffers::array_init(|_| Default::default()),
|
||||
h: ::flatbuffers::array_init(|_| Default::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LargeArrayStructT {
|
||||
pub fn pack(&self) -> LargeArrayStruct {
|
||||
LargeArrayStruct::new(
|
||||
&self.d,
|
||||
&self.e,
|
||||
&self.f,
|
||||
&::flatbuffers::array_init(|i| self.g[i].pack()),
|
||||
&self.h,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
native_include "bigfoot_ref_test_impl.h";
|
||||
|
||||
namespace BigfootRefTestNS;
|
||||
|
||||
// Stands in for Bigfoot's real UUID - a `native_type` struct so RefId has a
|
||||
// distinct native/flat representation, matching the shape `bigfoot_ref`
|
||||
// requires of a wrapper's payload field.
|
||||
struct RefId (native_type: "Native::RefId") {
|
||||
value: uint64;
|
||||
}
|
||||
|
||||
// The reference-wrapper template itself. `bigfoot_ref_wrapper` marks Ref as
|
||||
// instantiable per referenced type via `bigfoot_ref` below.
|
||||
struct Ref (bigfoot_ref_wrapper: "Native::Ref") {
|
||||
uuid: RefId;
|
||||
}
|
||||
|
||||
// RefHolder references two distinct C++ types (Thing, OtherThing) that are
|
||||
// *never defined anywhere in this test* - only ever forward-declared, by
|
||||
// flatc itself, directly into the generated header. This is the property
|
||||
// `bigfoot_ref` exists to provide: a reference field never requires the
|
||||
// referenced type to be complete. It also references `Thing` twice (once as
|
||||
// a plain field, once in a vector), exercising the include-guard dedup for
|
||||
// two fields that resolve to the identical Pack/UnPack pair.
|
||||
table RefHolder {
|
||||
ref_a: Ref (native_inline, bigfoot_ref: "Native::Thing");
|
||||
ref_a_again: [Ref] (native_inline, bigfoot_ref: "Native::Thing");
|
||||
ref_b: Ref (native_inline, bigfoot_ref: "Native::OtherThing");
|
||||
}
|
||||
|
||||
root_type RefHolder;
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "bigfoot_ref_test_impl.h"
|
||||
|
||||
#include "bigfoot_ref_test_generated.h"
|
||||
#include "test_assert.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
BigfootRefTestNS::RefId Pack(const Native::RefId& obj) {
|
||||
return BigfootRefTestNS::RefId(obj.value);
|
||||
}
|
||||
|
||||
const Native::RefId UnPack(const BigfootRefTestNS::RefId& obj) {
|
||||
return Native::RefId(obj.value());
|
||||
}
|
||||
} // namespace flatbuffers
|
||||
|
||||
namespace flatbuffers {
|
||||
namespace tests {
|
||||
|
||||
// Exercises the --bigfoot_ref/--bigfoot_ref_wrapper flatc attributes (see
|
||||
// tests/bigfoot_ref_test.fbs): a reference field never requires the
|
||||
// referenced native type to be complete, and the generated header supplies
|
||||
// its own forward declaration plus inline Pack/UnPack definitions, with no
|
||||
// hand-written boilerplate anywhere in this file for `Thing`/`OtherThing`.
|
||||
void BigfootRefTest() {
|
||||
using BigfootRefTestNS::RefHolder;
|
||||
using BigfootRefTestNS::RefHolderT;
|
||||
|
||||
RefHolderT src;
|
||||
src.ref_a = Native::Ref<Native::Thing>(Native::RefId(1));
|
||||
src.ref_a_again.push_back(Native::Ref<Native::Thing>(Native::RefId(2)));
|
||||
src.ref_a_again.push_back(Native::Ref<Native::Thing>(Native::RefId(3)));
|
||||
src.ref_b = Native::Ref<Native::OtherThing>(Native::RefId(4));
|
||||
|
||||
flatbuffers::FlatBufferBuilder fbb;
|
||||
fbb.Finish(RefHolder::Pack(fbb, &src));
|
||||
|
||||
auto dst = BigfootRefTestNS::UnPackRefHolder(fbb.GetBufferPointer());
|
||||
|
||||
TEST_EQ(dst->ref_a.uuid.value, 1u);
|
||||
TEST_EQ(dst->ref_a_again.size(), 2u);
|
||||
TEST_EQ(dst->ref_a_again[0].uuid.value, 2u);
|
||||
TEST_EQ(dst->ref_a_again[1].uuid.value, 3u);
|
||||
TEST_EQ(dst->ref_b.uuid.value, 4u);
|
||||
}
|
||||
|
||||
} // namespace tests
|
||||
} // namespace flatbuffers
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef BIGFOOT_REF_TEST_IMPL_H
|
||||
#define BIGFOOT_REF_TEST_IMPL_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Native {
|
||||
// Stands in for Bigfoot's real UUID.
|
||||
struct RefId {
|
||||
uint64_t value;
|
||||
|
||||
RefId() : value(0) {}
|
||||
explicit RefId(uint64_t _value) : value(_value) {}
|
||||
|
||||
bool operator==(const RefId& other) const { return value == other.value; }
|
||||
};
|
||||
|
||||
// `Thing`/`OtherThing` are intentionally *never* defined anywhere in this
|
||||
// test (see bigfoot_ref_test.fbs) - Ref<T> must compile and round-trip
|
||||
// without T ever being a complete type, exactly like Bigfoot's
|
||||
// HardReference<T>/SoftReference<T>. Their forward declarations are emitted
|
||||
// automatically by flatc (GenerateBigfootRefForwardDecls in
|
||||
// idl_gen_cpp.cpp) directly into bigfoot_ref_test_generated.h - no manual
|
||||
// forward declaration belongs here.
|
||||
|
||||
// The reference-wrapper template `bigfoot_ref_wrapper`/`bigfoot_ref` (see
|
||||
// idl_parser.cpp/idl_gen_cpp.cpp) instantiate per referenced type. Only
|
||||
// needs a `GetUUID()` accessor and a constructor from RefId - never needs T
|
||||
// complete.
|
||||
template <typename T>
|
||||
struct Ref {
|
||||
RefId uuid;
|
||||
|
||||
Ref() : uuid() {}
|
||||
Ref(const RefId& _uuid) : uuid(_uuid) {}
|
||||
|
||||
const RefId& GetUUID() const { return uuid; }
|
||||
|
||||
bool operator==(const Ref& other) const { return uuid == other.uuid; }
|
||||
};
|
||||
} // namespace Native
|
||||
|
||||
namespace BigfootRefTestNS {
|
||||
struct RefId;
|
||||
} // namespace BigfootRefTestNS
|
||||
|
||||
namespace flatbuffers {
|
||||
BigfootRefTestNS::RefId Pack(const Native::RefId& obj);
|
||||
const Native::RefId UnPack(const BigfootRefTestNS::RefId& obj);
|
||||
|
||||
namespace tests {
|
||||
void BigfootRefTest();
|
||||
} // namespace tests
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // BIGFOOT_REF_TEST_IMPL_H
|
||||
@@ -0,0 +1,29 @@
|
||||
// Schema used to test the --cpp-vector-type flatc option, which lets the
|
||||
// generated Object API use a custom vector-like container (e.g.
|
||||
// eastl::vector) instead of std::vector. See tests/test_vector_type.h for
|
||||
// the stand-in container used by the test, and
|
||||
// tests/cpp_vector_type_test.cpp for the test itself.
|
||||
|
||||
namespace CppVectorTypeNS;
|
||||
|
||||
enum CppVectorTypeColor : byte { Red = 0, Green, Blue }
|
||||
|
||||
struct CppVectorTypeVec2 {
|
||||
x: float;
|
||||
y: float;
|
||||
}
|
||||
|
||||
table CppVectorTypeMonster {
|
||||
id: int32;
|
||||
}
|
||||
|
||||
table CppVectorTypeTest {
|
||||
ints: [int32];
|
||||
flags: [bool];
|
||||
colors: [CppVectorTypeColor];
|
||||
strings: [string];
|
||||
positions: [CppVectorTypeVec2];
|
||||
monsters: [CppVectorTypeMonster];
|
||||
}
|
||||
|
||||
root_type CppVectorTypeTest;
|
||||
@@ -0,0 +1,143 @@
|
||||
#include "cpp_vector_type_test.h"
|
||||
|
||||
#include "cpp_vector_type_generated.h"
|
||||
#include "test_assert.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
namespace tests {
|
||||
|
||||
// Exercises the --cpp-vector-type flatc option (see
|
||||
// tests/cpp_vector_type.fbs and tests/test_vector_type.h), which replaces
|
||||
// std::vector with a custom vector-like container in the generated Object
|
||||
// API. This covers every CreateVector*-family code path in Pack(): plain
|
||||
// scalars, bool, enum-cast, vector-of-string, vector-of-struct and
|
||||
// vector-of-table, then round-trips everything back through UnPackTo().
|
||||
void CppVectorTypeTest() {
|
||||
using CppVectorTypeNS::CppVectorTypeColor_Blue;
|
||||
using CppVectorTypeNS::CppVectorTypeColor_Green;
|
||||
using CppVectorTypeNS::CppVectorTypeColor_Red;
|
||||
using CppVectorTypeNS::CppVectorTypeMonsterT;
|
||||
using CppVectorTypeNS::CppVectorTypeTest;
|
||||
using CppVectorTypeNS::CppVectorTypeTestT;
|
||||
using CppVectorTypeNS::CppVectorTypeVec2;
|
||||
|
||||
// ---------------------------------------
|
||||
// 1) Build a native object using the custom vector container for every
|
||||
// vector field (scalars, bools, enums, strings, structs and tables).
|
||||
// ---------------------------------------
|
||||
CppVectorTypeTestT src;
|
||||
src.ints.push_back(1);
|
||||
src.ints.push_back(2);
|
||||
src.ints.push_back(3);
|
||||
|
||||
src.flags.push_back(true);
|
||||
src.flags.push_back(false);
|
||||
src.flags.push_back(true);
|
||||
|
||||
src.colors.push_back(CppVectorTypeColor_Red);
|
||||
src.colors.push_back(CppVectorTypeColor_Green);
|
||||
src.colors.push_back(CppVectorTypeColor_Blue);
|
||||
|
||||
src.strings.push_back("hello");
|
||||
src.strings.push_back("world");
|
||||
|
||||
src.positions.push_back(CppVectorTypeVec2(1.0f, 2.0f));
|
||||
src.positions.push_back(CppVectorTypeVec2(3.0f, 4.0f));
|
||||
|
||||
src.monsters.emplace_back(new CppVectorTypeMonsterT());
|
||||
src.monsters[0]->id = 111;
|
||||
src.monsters.emplace_back(new CppVectorTypeMonsterT());
|
||||
src.monsters[1]->id = 222;
|
||||
|
||||
// ---------------------------------------
|
||||
// 2) Exercise the copy constructor / copy assignment operator generated
|
||||
// for object-API types (--gen-compare requires these too), which rely
|
||||
// on the custom vector's own copy ctor plus reserve()/emplace_back()
|
||||
// for the vector-of-pointer (table) field.
|
||||
// ---------------------------------------
|
||||
CppVectorTypeTestT copy_of_src(src);
|
||||
TEST_EQ(copy_of_src == src, true);
|
||||
TEST_ASSERT(copy_of_src.monsters[0].get() != src.monsters[0].get());
|
||||
TEST_EQ(copy_of_src.monsters[0]->id, 111);
|
||||
|
||||
// ---------------------------------------
|
||||
// 3) Pack into a FlatBuffer and verify the wire-format contents.
|
||||
// ---------------------------------------
|
||||
flatbuffers::FlatBufferBuilder fbb;
|
||||
fbb.Finish(CppVectorTypeTest::Pack(fbb, &src));
|
||||
|
||||
const auto* fb =
|
||||
flatbuffers::GetRoot<CppVectorTypeTest>(fbb.GetBufferPointer());
|
||||
|
||||
TEST_EQ(fb->ints()->size(), 3u);
|
||||
TEST_EQ(fb->ints()->Get(0), 1);
|
||||
TEST_EQ(fb->ints()->Get(1), 2);
|
||||
TEST_EQ(fb->ints()->Get(2), 3);
|
||||
|
||||
TEST_EQ(fb->flags()->size(), 3u);
|
||||
TEST_EQ(fb->flags()->Get(0) != 0, true);
|
||||
TEST_EQ(fb->flags()->Get(1) != 0, false);
|
||||
TEST_EQ(fb->flags()->Get(2) != 0, true);
|
||||
|
||||
TEST_EQ(fb->colors()->size(), 3u);
|
||||
TEST_EQ(fb->colors()->Get(0), CppVectorTypeColor_Red);
|
||||
TEST_EQ(fb->colors()->Get(1), CppVectorTypeColor_Green);
|
||||
TEST_EQ(fb->colors()->Get(2), CppVectorTypeColor_Blue);
|
||||
|
||||
TEST_EQ(fb->strings()->size(), 2u);
|
||||
TEST_EQ_STR(fb->strings()->Get(0)->c_str(), "hello");
|
||||
TEST_EQ_STR(fb->strings()->Get(1)->c_str(), "world");
|
||||
|
||||
TEST_EQ(fb->positions()->size(), 2u);
|
||||
TEST_EQ(fb->positions()->Get(0)->x(), 1.0f);
|
||||
TEST_EQ(fb->positions()->Get(0)->y(), 2.0f);
|
||||
TEST_EQ(fb->positions()->Get(1)->x(), 3.0f);
|
||||
TEST_EQ(fb->positions()->Get(1)->y(), 4.0f);
|
||||
|
||||
TEST_EQ(fb->monsters()->size(), 2u);
|
||||
TEST_EQ(fb->monsters()->Get(0)->id(), 111);
|
||||
TEST_EQ(fb->monsters()->Get(1)->id(), 222);
|
||||
|
||||
// ---------------------------------------
|
||||
// 4) Unpack back into a fresh native object and verify a full round-trip
|
||||
// through the custom vector container.
|
||||
// ---------------------------------------
|
||||
CppVectorTypeTestT dst;
|
||||
fb->UnPackTo(&dst);
|
||||
|
||||
TEST_EQ(dst == src, true);
|
||||
|
||||
TEST_EQ(dst.ints.size(), 3u);
|
||||
TEST_EQ(dst.ints[0], 1);
|
||||
TEST_EQ(dst.ints[1], 2);
|
||||
TEST_EQ(dst.ints[2], 3);
|
||||
|
||||
TEST_EQ(dst.flags.size(), 3u);
|
||||
TEST_EQ(dst.flags[0], true);
|
||||
TEST_EQ(dst.flags[1], false);
|
||||
TEST_EQ(dst.flags[2], true);
|
||||
|
||||
TEST_EQ(dst.colors.size(), 3u);
|
||||
TEST_EQ(dst.colors[0], CppVectorTypeColor_Red);
|
||||
TEST_EQ(dst.colors[1], CppVectorTypeColor_Green);
|
||||
TEST_EQ(dst.colors[2], CppVectorTypeColor_Blue);
|
||||
|
||||
TEST_EQ(dst.strings.size(), 2u);
|
||||
TEST_EQ_STR(dst.strings[0].c_str(), "hello");
|
||||
TEST_EQ_STR(dst.strings[1].c_str(), "world");
|
||||
|
||||
TEST_EQ(dst.positions.size(), 2u);
|
||||
TEST_EQ(dst.positions[0].x(), 1.0f);
|
||||
TEST_EQ(dst.positions[0].y(), 2.0f);
|
||||
TEST_EQ(dst.positions[1].x(), 3.0f);
|
||||
TEST_EQ(dst.positions[1].y(), 4.0f);
|
||||
|
||||
TEST_EQ(dst.monsters.size(), 2u);
|
||||
TEST_ASSERT(dst.monsters[0] != nullptr);
|
||||
TEST_ASSERT(dst.monsters[1] != nullptr);
|
||||
TEST_EQ(dst.monsters[0]->id, 111);
|
||||
TEST_EQ(dst.monsters[1]->id, 222);
|
||||
}
|
||||
|
||||
} // namespace tests
|
||||
} // namespace flatbuffers
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef TESTS_CPP_VECTOR_TYPE_TEST_H
|
||||
#define TESTS_CPP_VECTOR_TYPE_TEST_H
|
||||
|
||||
namespace flatbuffers {
|
||||
namespace tests {
|
||||
|
||||
void CppVectorTypeTest();
|
||||
|
||||
} // namespace tests
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // TESTS_CPP_VECTOR_TYPE_TEST_H
|
||||
@@ -0,0 +1,18 @@
|
||||
// Test for cross-namespace Pack() code generation (issue #8948).
|
||||
// Verifies that Create* calls in Pack() are properly namespace-qualified
|
||||
// when referencing tables from different namespaces.
|
||||
|
||||
namespace native;
|
||||
|
||||
table TableWithNative {
|
||||
value: int;
|
||||
}
|
||||
|
||||
namespace foo;
|
||||
|
||||
table Consumer {
|
||||
c1: native.TableWithNative;
|
||||
c2: [native.TableWithNative];
|
||||
}
|
||||
|
||||
root_type Consumer;
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
enum ABC: int { A, B, C }
|
||||
|
||||
struct EvenMoreStruct {
|
||||
g:[int64:2];
|
||||
}
|
||||
|
||||
table EvenMoreDefaults {
|
||||
str: EvenMoreStruct;
|
||||
ints: [int] = [];
|
||||
floats: [float] = [ ];
|
||||
float_optional: [float];
|
||||
bytes_optional: [ubyte];
|
||||
floats_required: [float] (required);
|
||||
empty_string: string = "";
|
||||
some_string: string = "some";
|
||||
zero_string: string = "0";
|
||||
a_string:string (key);
|
||||
required_string: string (required);
|
||||
abcs: [ABC] = [];
|
||||
bools: [bool] = [];
|
||||
one_bool: bool = true;
|
||||
}
|
||||
@@ -31,14 +31,6 @@ struct ApplicationDataT;
|
||||
bool operator==(const ApplicationDataT &lhs, const ApplicationDataT &rhs);
|
||||
bool operator!=(const ApplicationDataT &lhs, const ApplicationDataT &rhs);
|
||||
|
||||
inline const ::flatbuffers::TypeTable *Vector3DTypeTable();
|
||||
|
||||
inline const ::flatbuffers::TypeTable *Vector3DAltTypeTable();
|
||||
|
||||
inline const ::flatbuffers::TypeTable *MatrixTypeTable();
|
||||
|
||||
inline const ::flatbuffers::TypeTable *ApplicationDataTypeTable();
|
||||
|
||||
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3D FLATBUFFERS_FINAL_CLASS {
|
||||
private:
|
||||
float x_;
|
||||
@@ -46,9 +38,7 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3D FLATBUFFERS_FINAL_CLASS {
|
||||
float z_;
|
||||
|
||||
public:
|
||||
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
|
||||
return Vector3DTypeTable();
|
||||
}
|
||||
struct Traits;
|
||||
Vector3D()
|
||||
: x_(0),
|
||||
y_(0),
|
||||
@@ -62,24 +52,19 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3D FLATBUFFERS_FINAL_CLASS {
|
||||
float x() const {
|
||||
return ::flatbuffers::EndianScalar(x_);
|
||||
}
|
||||
void mutate_x(float _x) {
|
||||
::flatbuffers::WriteScalar(&x_, _x);
|
||||
}
|
||||
float y() const {
|
||||
return ::flatbuffers::EndianScalar(y_);
|
||||
}
|
||||
void mutate_y(float _y) {
|
||||
::flatbuffers::WriteScalar(&y_, _y);
|
||||
}
|
||||
float z() const {
|
||||
return ::flatbuffers::EndianScalar(z_);
|
||||
}
|
||||
void mutate_z(float _z) {
|
||||
::flatbuffers::WriteScalar(&z_, _z);
|
||||
}
|
||||
};
|
||||
FLATBUFFERS_STRUCT_END(Vector3D, 12);
|
||||
|
||||
struct Vector3D::Traits {
|
||||
using type = Vector3D;
|
||||
};
|
||||
|
||||
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3DAlt FLATBUFFERS_FINAL_CLASS {
|
||||
private:
|
||||
float a_;
|
||||
@@ -87,9 +72,7 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3DAlt FLATBUFFERS_FINAL_CLASS {
|
||||
float c_;
|
||||
|
||||
public:
|
||||
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
|
||||
return Vector3DAltTypeTable();
|
||||
}
|
||||
struct Traits;
|
||||
Vector3DAlt()
|
||||
: a_(0),
|
||||
b_(0),
|
||||
@@ -103,30 +86,23 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3DAlt FLATBUFFERS_FINAL_CLASS {
|
||||
float a() const {
|
||||
return ::flatbuffers::EndianScalar(a_);
|
||||
}
|
||||
void mutate_a(float _a) {
|
||||
::flatbuffers::WriteScalar(&a_, _a);
|
||||
}
|
||||
float b() const {
|
||||
return ::flatbuffers::EndianScalar(b_);
|
||||
}
|
||||
void mutate_b(float _b) {
|
||||
::flatbuffers::WriteScalar(&b_, _b);
|
||||
}
|
||||
float c() const {
|
||||
return ::flatbuffers::EndianScalar(c_);
|
||||
}
|
||||
void mutate_c(float _c) {
|
||||
::flatbuffers::WriteScalar(&c_, _c);
|
||||
}
|
||||
};
|
||||
FLATBUFFERS_STRUCT_END(Vector3DAlt, 12);
|
||||
|
||||
struct Vector3DAlt::Traits {
|
||||
using type = Vector3DAlt;
|
||||
};
|
||||
|
||||
struct Matrix FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
typedef Native::Matrix NativeTableType;
|
||||
typedef MatrixBuilder Builder;
|
||||
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
|
||||
return MatrixTypeTable();
|
||||
}
|
||||
struct Traits;
|
||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||
VT_ROWS = 4,
|
||||
VT_COLUMNS = 6,
|
||||
@@ -135,21 +111,12 @@ struct Matrix FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
int32_t rows() const {
|
||||
return GetField<int32_t>(VT_ROWS, 0);
|
||||
}
|
||||
bool mutate_rows(int32_t _rows = 0) {
|
||||
return SetField<int32_t>(VT_ROWS, _rows, 0);
|
||||
}
|
||||
int32_t columns() const {
|
||||
return GetField<int32_t>(VT_COLUMNS, 0);
|
||||
}
|
||||
bool mutate_columns(int32_t _columns = 0) {
|
||||
return SetField<int32_t>(VT_COLUMNS, _columns, 0);
|
||||
}
|
||||
const ::flatbuffers::Vector<float> *values() const {
|
||||
return GetPointer<const ::flatbuffers::Vector<float> *>(VT_VALUES);
|
||||
}
|
||||
::flatbuffers::Vector<float> *mutable_values() {
|
||||
return GetPointer<::flatbuffers::Vector<float> *>(VT_VALUES);
|
||||
}
|
||||
template <bool B = false>
|
||||
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
@@ -200,6 +167,11 @@ inline ::flatbuffers::Offset<Matrix> CreateMatrix(
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
struct Matrix::Traits {
|
||||
using type = Matrix;
|
||||
static auto constexpr Create = CreateMatrix;
|
||||
};
|
||||
|
||||
inline ::flatbuffers::Offset<Matrix> CreateMatrixDirect(
|
||||
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||
int32_t rows = 0,
|
||||
@@ -232,9 +204,7 @@ struct ApplicationDataT : public ::flatbuffers::NativeTable {
|
||||
struct ApplicationData FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
typedef ApplicationDataT NativeTableType;
|
||||
typedef ApplicationDataBuilder Builder;
|
||||
static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {
|
||||
return ApplicationDataTypeTable();
|
||||
}
|
||||
struct Traits;
|
||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||
VT_VECTORS = 4,
|
||||
VT_VECTORS_ALT = 6,
|
||||
@@ -246,39 +216,21 @@ struct ApplicationData FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
const ::flatbuffers::Vector<const Geometry::Vector3D *> *vectors() const {
|
||||
return GetPointer<const ::flatbuffers::Vector<const Geometry::Vector3D *> *>(VT_VECTORS);
|
||||
}
|
||||
::flatbuffers::Vector<const Geometry::Vector3D *> *mutable_vectors() {
|
||||
return GetPointer<::flatbuffers::Vector<const Geometry::Vector3D *> *>(VT_VECTORS);
|
||||
}
|
||||
const ::flatbuffers::Vector<const Geometry::Vector3DAlt *> *vectors_alt() const {
|
||||
return GetPointer<const ::flatbuffers::Vector<const Geometry::Vector3DAlt *> *>(VT_VECTORS_ALT);
|
||||
}
|
||||
::flatbuffers::Vector<const Geometry::Vector3DAlt *> *mutable_vectors_alt() {
|
||||
return GetPointer<::flatbuffers::Vector<const Geometry::Vector3DAlt *> *>(VT_VECTORS_ALT);
|
||||
}
|
||||
const Geometry::Vector3D *position() const {
|
||||
return GetStruct<const Geometry::Vector3D *>(VT_POSITION);
|
||||
}
|
||||
Geometry::Vector3D *mutable_position() {
|
||||
return GetStruct<Geometry::Vector3D *>(VT_POSITION);
|
||||
}
|
||||
const Geometry::Vector3D *position_inline() const {
|
||||
return GetStruct<const Geometry::Vector3D *>(VT_POSITION_INLINE);
|
||||
}
|
||||
Geometry::Vector3D *mutable_position_inline() {
|
||||
return GetStruct<Geometry::Vector3D *>(VT_POSITION_INLINE);
|
||||
}
|
||||
const Geometry::Matrix *matrix() const {
|
||||
return GetPointer<const Geometry::Matrix *>(VT_MATRIX);
|
||||
}
|
||||
Geometry::Matrix *mutable_matrix() {
|
||||
return GetPointer<Geometry::Matrix *>(VT_MATRIX);
|
||||
}
|
||||
const ::flatbuffers::Vector<::flatbuffers::Offset<Geometry::Matrix>> *matrices() const {
|
||||
return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<Geometry::Matrix>> *>(VT_MATRICES);
|
||||
}
|
||||
::flatbuffers::Vector<::flatbuffers::Offset<Geometry::Matrix>> *mutable_matrices() {
|
||||
return GetPointer<::flatbuffers::Vector<::flatbuffers::Offset<Geometry::Matrix>> *>(VT_MATRICES);
|
||||
}
|
||||
template <bool B = false>
|
||||
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
@@ -351,6 +303,11 @@ inline ::flatbuffers::Offset<ApplicationData> CreateApplicationData(
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
struct ApplicationData::Traits {
|
||||
using type = ApplicationData;
|
||||
static auto constexpr Create = CreateApplicationData;
|
||||
};
|
||||
|
||||
inline ::flatbuffers::Offset<ApplicationData> CreateApplicationDataDirect(
|
||||
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const std::vector<Geometry::Vector3D> *vectors = nullptr,
|
||||
@@ -375,7 +332,7 @@ inline ::flatbuffers::Offset<ApplicationData> CreateApplicationDataDirect(
|
||||
::flatbuffers::Offset<ApplicationData> CreateApplicationData(::flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
|
||||
inline Native::Matrix *Matrix::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
|
||||
auto _o = std::unique_ptr<Native::Matrix>(new Native::Matrix());
|
||||
auto _o = std::make_unique<Native::Matrix>();
|
||||
UnPackTo(_o.get(), _resolver);
|
||||
return _o.release();
|
||||
}
|
||||
@@ -421,7 +378,7 @@ inline ApplicationDataT &ApplicationDataT::operator=(ApplicationDataT o) FLATBUF
|
||||
}
|
||||
|
||||
inline ApplicationDataT *ApplicationData::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
|
||||
auto _o = std::unique_ptr<ApplicationDataT>(new ApplicationDataT());
|
||||
auto _o = std::make_unique<ApplicationDataT>();
|
||||
UnPackTo(_o.get(), _resolver);
|
||||
return _o.release();
|
||||
}
|
||||
@@ -461,87 +418,6 @@ inline ::flatbuffers::Offset<ApplicationData> ApplicationData::Pack(::flatbuffer
|
||||
_matrices);
|
||||
}
|
||||
|
||||
inline const ::flatbuffers::TypeTable *Vector3DTypeTable() {
|
||||
static const ::flatbuffers::TypeCode type_codes[] = {
|
||||
{ ::flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ ::flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ ::flatbuffers::ET_FLOAT, 0, -1 }
|
||||
};
|
||||
static const int64_t values[] = { 0, 4, 8, 12 };
|
||||
static const char * const names[] = {
|
||||
"x",
|
||||
"y",
|
||||
"z"
|
||||
};
|
||||
static const ::flatbuffers::TypeTable tt = {
|
||||
::flatbuffers::ST_STRUCT, 3, type_codes, nullptr, nullptr, values, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
inline const ::flatbuffers::TypeTable *Vector3DAltTypeTable() {
|
||||
static const ::flatbuffers::TypeCode type_codes[] = {
|
||||
{ ::flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ ::flatbuffers::ET_FLOAT, 0, -1 },
|
||||
{ ::flatbuffers::ET_FLOAT, 0, -1 }
|
||||
};
|
||||
static const int64_t values[] = { 0, 4, 8, 12 };
|
||||
static const char * const names[] = {
|
||||
"a",
|
||||
"b",
|
||||
"c"
|
||||
};
|
||||
static const ::flatbuffers::TypeTable tt = {
|
||||
::flatbuffers::ST_STRUCT, 3, type_codes, nullptr, nullptr, values, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
inline const ::flatbuffers::TypeTable *MatrixTypeTable() {
|
||||
static const ::flatbuffers::TypeCode type_codes[] = {
|
||||
{ ::flatbuffers::ET_INT, 0, -1 },
|
||||
{ ::flatbuffers::ET_INT, 0, -1 },
|
||||
{ ::flatbuffers::ET_FLOAT, 1, -1 }
|
||||
};
|
||||
static const char * const names[] = {
|
||||
"rows",
|
||||
"columns",
|
||||
"values"
|
||||
};
|
||||
static const ::flatbuffers::TypeTable tt = {
|
||||
::flatbuffers::ST_TABLE, 3, type_codes, nullptr, nullptr, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
inline const ::flatbuffers::TypeTable *ApplicationDataTypeTable() {
|
||||
static const ::flatbuffers::TypeCode type_codes[] = {
|
||||
{ ::flatbuffers::ET_SEQUENCE, 1, 0 },
|
||||
{ ::flatbuffers::ET_SEQUENCE, 1, 1 },
|
||||
{ ::flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||
{ ::flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||
{ ::flatbuffers::ET_SEQUENCE, 0, 2 },
|
||||
{ ::flatbuffers::ET_SEQUENCE, 1, 2 }
|
||||
};
|
||||
static const ::flatbuffers::TypeFunction type_refs[] = {
|
||||
Geometry::Vector3DTypeTable,
|
||||
Geometry::Vector3DAltTypeTable,
|
||||
Geometry::MatrixTypeTable
|
||||
};
|
||||
static const char * const names[] = {
|
||||
"vectors",
|
||||
"vectors_alt",
|
||||
"position",
|
||||
"position_inline",
|
||||
"matrix",
|
||||
"matrices"
|
||||
};
|
||||
static const ::flatbuffers::TypeTable tt = {
|
||||
::flatbuffers::ST_TABLE, 6, type_codes, type_refs, nullptr, nullptr, names
|
||||
};
|
||||
return &tt;
|
||||
}
|
||||
|
||||
inline const Geometry::ApplicationData *GetApplicationData(const void *buf) {
|
||||
return ::flatbuffers::GetRoot<Geometry::ApplicationData>(buf);
|
||||
}
|
||||
@@ -550,14 +426,6 @@ inline const Geometry::ApplicationData *GetSizePrefixedApplicationData(const voi
|
||||
return ::flatbuffers::GetSizePrefixedRoot<Geometry::ApplicationData>(buf);
|
||||
}
|
||||
|
||||
inline ApplicationData *GetMutableApplicationData(void *buf) {
|
||||
return ::flatbuffers::GetMutableRoot<ApplicationData>(buf);
|
||||
}
|
||||
|
||||
inline Geometry::ApplicationData *GetMutableSizePrefixedApplicationData(void *buf) {
|
||||
return ::flatbuffers::GetMutableSizePrefixedRoot<Geometry::ApplicationData>(buf);
|
||||
}
|
||||
|
||||
template <bool B = false>
|
||||
inline bool VerifyApplicationDataBuffer(
|
||||
::flatbuffers::VerifierTemplate<B> &verifier) {
|
||||
@@ -570,6 +438,10 @@ inline bool VerifySizePrefixedApplicationDataBuffer(
|
||||
return verifier.template VerifySizePrefixedBuffer<Geometry::ApplicationData>(nullptr);
|
||||
}
|
||||
|
||||
inline const char *ApplicationDataExtension() {
|
||||
return "bfbs";
|
||||
}
|
||||
|
||||
inline void FinishApplicationDataBuffer(
|
||||
::flatbuffers::FlatBufferBuilder &fbb,
|
||||
::flatbuffers::Offset<Geometry::ApplicationData> root) {
|
||||
|
||||
@@ -43,6 +43,7 @@ struct Matrix {
|
||||
(values == other.values);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Native
|
||||
|
||||
namespace Geometry {
|
||||
|
||||
@@ -97,6 +97,17 @@ void ErrorTest() {
|
||||
"datatype already");
|
||||
TestError("struct X (force_align: 7) { Y:int; }", "force_align");
|
||||
TestError("struct X {}", "size 0");
|
||||
TestError(
|
||||
"struct X { Y:int; } table T { y:X (bigfoot_ref:\"::Foo::Bar\"); "
|
||||
"}",
|
||||
"'bigfoot_ref_wrapper' attribute");
|
||||
TestError(
|
||||
"table T { y:int (bigfoot_ref:\"::Foo::Bar\"); }",
|
||||
"struct-typed fields");
|
||||
TestError(
|
||||
"struct X (bigfoot_ref_wrapper: \"Foo\") { Y:int; } "
|
||||
"table T { y:X (bigfoot_ref:\"\"); }",
|
||||
"cannot be empty");
|
||||
TestError("{}", "no root");
|
||||
TestError("table X { Y:byte; } root_type X; { Y:1 } { Y:1 }", "end of file");
|
||||
TestError("table X { Y:byte; } root_type X; { Y:1 } table Y{ Z:int }",
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "required_table_default_test.h"
|
||||
|
||||
#include "required_table_default_test_generated.h"
|
||||
#include "test_assert.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
namespace tests {
|
||||
|
||||
// Exercises the (required) table-field default member initializer added to
|
||||
// GenMember() in idl_gen_cpp.cpp: a `(required)` table field can never
|
||||
// legally be missing once Pack()/Verify() succeed, so a plain native default
|
||||
// constructor must not leave it null - callers should never have to
|
||||
// remember to allocate it themselves before the first Pack(). The sibling
|
||||
// `optional_inner` field (same type, no `required`) is checked alongside it
|
||||
// to confirm the change is scoped to required fields only.
|
||||
void RequiredTableDefaultTest() {
|
||||
using RequiredTableDefaultTestNS::Holder;
|
||||
using RequiredTableDefaultTestNS::HolderT;
|
||||
|
||||
HolderT src;
|
||||
TEST_NOTNULL(src.required_inner.get());
|
||||
TEST_NULL(src.optional_inner.get());
|
||||
|
||||
// Never manually allocated required_inner - only relying on the default
|
||||
// constructor above - yet Pack() must still succeed and round-trip it.
|
||||
src.required_inner->value = 42;
|
||||
|
||||
flatbuffers::FlatBufferBuilder fbb;
|
||||
fbb.Finish(Holder::Pack(fbb, &src));
|
||||
|
||||
auto dst = RequiredTableDefaultTestNS::UnPackHolder(fbb.GetBufferPointer());
|
||||
|
||||
TEST_NOTNULL(dst->required_inner.get());
|
||||
TEST_EQ(dst->required_inner->value, 42u);
|
||||
TEST_NULL(dst->optional_inner.get());
|
||||
}
|
||||
|
||||
} // namespace tests
|
||||
} // namespace flatbuffers
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace RequiredTableDefaultTestNS;
|
||||
|
||||
table Inner {
|
||||
value: uint32;
|
||||
}
|
||||
|
||||
// `required_inner` has no default in the wire format (tables can't have one),
|
||||
// but Pack()/Verify() both reject a buffer where it is missing - so the
|
||||
// native default constructor must never leave it null. `optional_inner` is
|
||||
// the same field type without `required`, kept alongside it to confirm the
|
||||
// fix only changes required table fields, not every table pointer field.
|
||||
table Holder {
|
||||
required_inner: Inner (required);
|
||||
optional_inner: Inner;
|
||||
}
|
||||
|
||||
root_type Holder;
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef REQUIRED_TABLE_DEFAULT_TEST_H
|
||||
#define REQUIRED_TABLE_DEFAULT_TEST_H
|
||||
|
||||
namespace flatbuffers {
|
||||
namespace tests {
|
||||
|
||||
void RequiredTableDefaultTest();
|
||||
|
||||
} // namespace tests
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // REQUIRED_TABLE_DEFAULT_TEST_H
|
||||
@@ -0,0 +1,67 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
// swiftlint:disable all
|
||||
// swiftformat:disable all
|
||||
|
||||
#if canImport(Common)
|
||||
import Common
|
||||
#endif
|
||||
|
||||
import FlatBuffers
|
||||
|
||||
public struct DataModel_A: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_25_12_19() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
private var _accessor: Table
|
||||
|
||||
private init(_ t: Table) { _accessor = t }
|
||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||
|
||||
private struct VT {
|
||||
}
|
||||
|
||||
public static func startA(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
||||
public static func endA(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
|
||||
public static func createA(
|
||||
_ fbb: inout FlatBufferBuilder
|
||||
) -> Offset {
|
||||
let __start = DataModel_A.startA(&fbb)
|
||||
return DataModel_A.endA(&fbb, start: __start)
|
||||
}
|
||||
|
||||
public func unpack() -> DataModel_AT {
|
||||
return DataModel_AT(self)
|
||||
}
|
||||
public static func pack(_ builder: inout FlatBufferBuilder, obj: inout DataModel_AT?) -> Offset {
|
||||
guard var obj = obj else { return Offset() }
|
||||
return pack(&builder, obj: &obj)
|
||||
}
|
||||
|
||||
public static func pack(_ builder: inout FlatBufferBuilder, obj: inout DataModel_AT) -> Offset {
|
||||
let __root = DataModel_A.startA(&builder)
|
||||
return DataModel_A.endA(&builder, start: __root)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
extension DataModel_A: Encodable {
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
}
|
||||
}
|
||||
|
||||
public class DataModel_AT: NativeObject {
|
||||
|
||||
|
||||
public init(_ _t: borrowing DataModel_A) {
|
||||
}
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
||||
public func serialize() -> ByteBuffer { return serialize(type: DataModel_A.self) }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace DataModel;
|
||||
|
||||
table A {
|
||||
a:int (deprecated);
|
||||
}
|
||||
+7
-1
@@ -66,6 +66,9 @@
|
||||
#include "native_type_test_generated.h"
|
||||
#include "test_assert.h"
|
||||
#include "util_test.h"
|
||||
#include "cpp_vector_type_test.h"
|
||||
#include "bigfoot_ref_test_impl.h"
|
||||
#include "required_table_default_test.h"
|
||||
#include "vector_table_naked_ptr_test.h"
|
||||
|
||||
void FlatBufferBuilderTest();
|
||||
@@ -950,7 +953,6 @@ void NativeTypeTest() {
|
||||
TEST_EQ(dstDataT->position_inline.x, 4.0f);
|
||||
TEST_EQ(dstDataT->position_inline.y, 5.0f);
|
||||
TEST_EQ(dstDataT->position_inline.z, 6.0f);
|
||||
|
||||
for (int i = 0; i < N; ++i) {
|
||||
const Native::Vector3D& v = dstDataT->vectors[i];
|
||||
TEST_EQ(v.x, 10 * i + 0.1f);
|
||||
@@ -1744,6 +1746,8 @@ int FlatBufferTests(const std::string& tests_data_path) {
|
||||
|
||||
AlignmentTest();
|
||||
|
||||
CppVectorTypeTest();
|
||||
|
||||
#ifndef FLATBUFFERS_NO_FILE_TESTS
|
||||
ParseAndGenerateTextTest(tests_data_path, false);
|
||||
ParseAndGenerateTextTest(tests_data_path, true);
|
||||
@@ -1813,6 +1817,8 @@ int FlatBufferTests(const std::string& tests_data_path) {
|
||||
InvalidFloatTest();
|
||||
FixedLengthArrayTest();
|
||||
NativeTypeTest();
|
||||
flatbuffers::tests::BigfootRefTest();
|
||||
flatbuffers::tests::RequiredTableDefaultTest();
|
||||
OptionalScalarsTest();
|
||||
ParseFlexbuffersFromJsonWithNullTest();
|
||||
FlatbuffersSpanTest();
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
#ifndef TESTS_TEST_VECTOR_TYPE_H_
|
||||
#define TESTS_TEST_VECTOR_TYPE_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
|
||||
namespace flatbuffers {
|
||||
namespace tests {
|
||||
|
||||
// A minimal stand-in for a custom vector-like container (e.g.
|
||||
// eastl::vector), used to exercise the --cpp-vector-type flatc option.
|
||||
//
|
||||
// This is deliberately its own contiguous container rather than a wrapper
|
||||
// around std::vector, so that:
|
||||
// - generated code can't silently keep depending on any of the
|
||||
// std::vector-specific overloads in flatbuffer_builder.h (e.g.
|
||||
// CreateVector(const std::vector<T,Alloc>&)), and
|
||||
// - CustomVector<bool> stores plain contiguous bools accessible via
|
||||
// data(), unlike std::vector<bool>'s bit-packed specialization, matching
|
||||
// how real alternative containers such as eastl::vector behave.
|
||||
template<typename T>
|
||||
class CustomVector {
|
||||
public:
|
||||
using value_type = T;
|
||||
using iterator = T*;
|
||||
using const_iterator = const T*;
|
||||
|
||||
CustomVector() = default;
|
||||
CustomVector(const CustomVector& o) { assign_copy(o); }
|
||||
CustomVector(CustomVector&& o) noexcept { steal(o); }
|
||||
|
||||
CustomVector& operator=(const CustomVector& o) {
|
||||
if (this != &o) {
|
||||
destroy_all();
|
||||
deallocate();
|
||||
assign_copy(o);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
CustomVector& operator=(CustomVector&& o) noexcept {
|
||||
if (this != &o) {
|
||||
destroy_all();
|
||||
deallocate();
|
||||
steal(o);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~CustomVector() {
|
||||
destroy_all();
|
||||
deallocate();
|
||||
}
|
||||
|
||||
void reserve(size_t n) {
|
||||
if (n > capacity_) grow_to(n);
|
||||
}
|
||||
|
||||
void resize(size_t n) {
|
||||
if (n > capacity_) grow_to(n);
|
||||
for (size_t i = n; i < size_; ++i) data_[i].~T();
|
||||
for (size_t i = size_; i < n; ++i) new (&data_[i]) T();
|
||||
size_ = n;
|
||||
}
|
||||
|
||||
size_t size() const { return size_; }
|
||||
bool empty() const { return size_ == 0; }
|
||||
|
||||
T* data() { return data_; }
|
||||
const T* data() const { return data_; }
|
||||
|
||||
T& operator[](size_t i) { return data_[i]; }
|
||||
const T& operator[](size_t i) const { return data_[i]; }
|
||||
|
||||
template<typename... Args>
|
||||
void emplace_back(Args&&... args) {
|
||||
if (size_ == capacity_) grow_to(capacity_ == 0 ? 1 : capacity_ * 2);
|
||||
new (&data_[size_]) T(std::forward<Args>(args)...);
|
||||
++size_;
|
||||
}
|
||||
void push_back(const T& v) { emplace_back(v); }
|
||||
|
||||
iterator begin() { return data_; }
|
||||
iterator end() { return data_ + size_; }
|
||||
const_iterator begin() const { return data_; }
|
||||
const_iterator end() const { return data_ + size_; }
|
||||
const_iterator cbegin() const { return data_; }
|
||||
const_iterator cend() const { return data_ + size_; }
|
||||
|
||||
private:
|
||||
void grow_to(size_t n) {
|
||||
T* new_data = static_cast<T*>(::operator new(n * sizeof(T)));
|
||||
for (size_t i = 0; i < size_; ++i) {
|
||||
new (&new_data[i]) T(std::move(data_[i]));
|
||||
data_[i].~T();
|
||||
}
|
||||
::operator delete(data_);
|
||||
data_ = new_data;
|
||||
capacity_ = n;
|
||||
}
|
||||
|
||||
void assign_copy(const CustomVector& o) {
|
||||
data_ = o.size_ ? static_cast<T*>(::operator new(o.size_ * sizeof(T)))
|
||||
: nullptr;
|
||||
capacity_ = o.size_;
|
||||
for (size_t i = 0; i < o.size_; ++i) new (&data_[i]) T(o.data_[i]);
|
||||
size_ = o.size_;
|
||||
}
|
||||
|
||||
void steal(CustomVector& o) {
|
||||
data_ = o.data_;
|
||||
size_ = o.size_;
|
||||
capacity_ = o.capacity_;
|
||||
o.data_ = nullptr;
|
||||
o.size_ = o.capacity_ = 0;
|
||||
}
|
||||
|
||||
void destroy_all() {
|
||||
for (size_t i = 0; i < size_; ++i) data_[i].~T();
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
void deallocate() {
|
||||
::operator delete(data_);
|
||||
data_ = nullptr;
|
||||
capacity_ = 0;
|
||||
}
|
||||
|
||||
T* data_ = nullptr;
|
||||
size_t size_ = 0;
|
||||
size_t capacity_ = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
bool operator==(const CustomVector<T>& lhs, const CustomVector<T>& rhs) {
|
||||
if (lhs.size() != rhs.size()) return false;
|
||||
for (size_t i = 0; i < lhs.size(); ++i) {
|
||||
if (!(lhs[i] == rhs[i])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool operator!=(const CustomVector<T>& lhs, const CustomVector<T>& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
} // namespace tests
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // TESTS_TEST_VECTOR_TYPE_H_
|
||||
@@ -0,0 +1,28 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { dirname, resolve } from "node:path";
|
||||
|
||||
const here = dirname(fileURLToPath(import.meta.url));
|
||||
const headerPath = resolve(here, "relative_imports/transit/three/header.ts");
|
||||
|
||||
const contents = readFileSync(headerPath, "utf8");
|
||||
|
||||
const expectedImports = [
|
||||
"from '../one/info.js';",
|
||||
"from '../two/identity.js';",
|
||||
];
|
||||
|
||||
for (const expected of expectedImports) {
|
||||
if (!contents.includes(expected)) {
|
||||
throw new Error(`Missing relative import "${expected}" in ${headerPath}`);
|
||||
}
|
||||
}
|
||||
|
||||
const forbidden = "../transit/";
|
||||
if (contents.includes(forbidden)) {
|
||||
throw new Error(
|
||||
`Found unexpected namespace segment in import path within ${headerPath}`
|
||||
);
|
||||
}
|
||||
|
||||
console.log("JavaScriptRelativeImportPathTest: OK");
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace Transit.One;
|
||||
|
||||
table Info {
|
||||
timestamp:ulong;
|
||||
}
|
||||
|
||||
namespace Transit.Two;
|
||||
|
||||
table Identity {
|
||||
id:uint;
|
||||
}
|
||||
|
||||
namespace Transit.Three;
|
||||
|
||||
table Header {
|
||||
info:Transit.One.Info;
|
||||
id:Transit.Two.Identity;
|
||||
}
|
||||
|
||||
root_type Header;
|
||||
@@ -0,0 +1,21 @@
|
||||
// Test for union creator naming consistency (issue #8843).
|
||||
// Uses non-UpperCamel union name to verify that Function() naming
|
||||
// is used consistently for both definition and call site.
|
||||
|
||||
namespace union_name_test;
|
||||
|
||||
table Foo {
|
||||
val: int;
|
||||
}
|
||||
|
||||
table Bar {
|
||||
name: string;
|
||||
}
|
||||
|
||||
union my_test_union { Foo, Bar }
|
||||
|
||||
table Container {
|
||||
u: my_test_union;
|
||||
}
|
||||
|
||||
root_type Container;
|
||||
@@ -0,0 +1,93 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace: union_name_test
|
||||
|
||||
import flatbuffers
|
||||
from flatbuffers.compat import import_numpy
|
||||
np = import_numpy()
|
||||
|
||||
class Bar(object):
|
||||
__slots__ = ['_tab']
|
||||
|
||||
@classmethod
|
||||
def GetRootAs(cls, buf, offset=0):
|
||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
||||
x = Bar()
|
||||
x.Init(buf, n + offset)
|
||||
return x
|
||||
|
||||
@classmethod
|
||||
def GetRootAsBar(cls, buf, offset=0):
|
||||
"""This method is deprecated. Please switch to GetRootAs."""
|
||||
return cls.GetRootAs(buf, offset)
|
||||
# Bar
|
||||
def Init(self, buf, pos):
|
||||
self._tab = flatbuffers.table.Table(buf, pos)
|
||||
|
||||
# Bar
|
||||
def Name(self):
|
||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
||||
if o != 0:
|
||||
return self._tab.String(o + self._tab.Pos)
|
||||
return None
|
||||
|
||||
def BarStart(builder):
|
||||
builder.StartObject(1)
|
||||
|
||||
def Start(builder):
|
||||
BarStart(builder)
|
||||
|
||||
def BarAddName(builder, name):
|
||||
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
|
||||
|
||||
def AddName(builder, name):
|
||||
BarAddName(builder, name)
|
||||
|
||||
def BarEnd(builder):
|
||||
return builder.EndObject()
|
||||
|
||||
def End(builder):
|
||||
return BarEnd(builder)
|
||||
|
||||
|
||||
class BarT(object):
|
||||
|
||||
# BarT
|
||||
def __init__(
|
||||
self,
|
||||
name = None,
|
||||
):
|
||||
self.name = name # type: Optional[str]
|
||||
|
||||
@classmethod
|
||||
def InitFromBuf(cls, buf, pos):
|
||||
bar = Bar()
|
||||
bar.Init(buf, pos)
|
||||
return cls.InitFromObj(bar)
|
||||
|
||||
@classmethod
|
||||
def InitFromPackedBuf(cls, buf, pos=0):
|
||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
|
||||
return cls.InitFromBuf(buf, pos+n)
|
||||
|
||||
@classmethod
|
||||
def InitFromObj(cls, bar):
|
||||
x = BarT()
|
||||
x._UnPack(bar)
|
||||
return x
|
||||
|
||||
# BarT
|
||||
def _UnPack(self, bar):
|
||||
if bar is None:
|
||||
return
|
||||
self.name = bar.Name()
|
||||
|
||||
# BarT
|
||||
def Pack(self, builder):
|
||||
if self.name is not None:
|
||||
name = builder.CreateString(self.name)
|
||||
BarStart(builder)
|
||||
if self.name is not None:
|
||||
BarAddName(builder, name)
|
||||
bar = BarEnd(builder)
|
||||
return bar
|
||||
@@ -0,0 +1,120 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace: union_name_test
|
||||
|
||||
import flatbuffers
|
||||
from flatbuffers.compat import import_numpy
|
||||
np = import_numpy()
|
||||
|
||||
class Container(object):
|
||||
__slots__ = ['_tab']
|
||||
|
||||
@classmethod
|
||||
def GetRootAs(cls, buf, offset=0):
|
||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
||||
x = Container()
|
||||
x.Init(buf, n + offset)
|
||||
return x
|
||||
|
||||
@classmethod
|
||||
def GetRootAsContainer(cls, buf, offset=0):
|
||||
"""This method is deprecated. Please switch to GetRootAs."""
|
||||
return cls.GetRootAs(buf, offset)
|
||||
# Container
|
||||
def Init(self, buf, pos):
|
||||
self._tab = flatbuffers.table.Table(buf, pos)
|
||||
|
||||
# Container
|
||||
def UType(self):
|
||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
||||
if o != 0:
|
||||
return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
|
||||
return 0
|
||||
|
||||
# Container
|
||||
def U(self):
|
||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
||||
if o != 0:
|
||||
from flatbuffers.table import Table
|
||||
obj = Table(bytearray(), 0)
|
||||
self._tab.Union(obj, o)
|
||||
return obj
|
||||
return None
|
||||
|
||||
def ContainerStart(builder):
|
||||
builder.StartObject(2)
|
||||
|
||||
def Start(builder):
|
||||
ContainerStart(builder)
|
||||
|
||||
def ContainerAddUType(builder, uType):
|
||||
builder.PrependUint8Slot(0, uType, 0)
|
||||
|
||||
def AddUType(builder, uType):
|
||||
ContainerAddUType(builder, uType)
|
||||
|
||||
def ContainerAddU(builder, u):
|
||||
builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(u), 0)
|
||||
|
||||
def AddU(builder, u):
|
||||
ContainerAddU(builder, u)
|
||||
|
||||
def ContainerEnd(builder):
|
||||
return builder.EndObject()
|
||||
|
||||
def End(builder):
|
||||
return ContainerEnd(builder)
|
||||
|
||||
import union_name_test.Bar
|
||||
import union_name_test.Foo
|
||||
import union_name_test.my_test_union
|
||||
try:
|
||||
from typing import Union
|
||||
except:
|
||||
pass
|
||||
|
||||
class ContainerT(object):
|
||||
|
||||
# ContainerT
|
||||
def __init__(
|
||||
self,
|
||||
uType = 0,
|
||||
u = None,
|
||||
):
|
||||
self.uType = uType # type: int
|
||||
self.u = u # type: Union[None, 'union_name_test.Foo.FooT', 'union_name_test.Bar.BarT']
|
||||
|
||||
@classmethod
|
||||
def InitFromBuf(cls, buf, pos):
|
||||
container = Container()
|
||||
container.Init(buf, pos)
|
||||
return cls.InitFromObj(container)
|
||||
|
||||
@classmethod
|
||||
def InitFromPackedBuf(cls, buf, pos=0):
|
||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
|
||||
return cls.InitFromBuf(buf, pos+n)
|
||||
|
||||
@classmethod
|
||||
def InitFromObj(cls, container):
|
||||
x = ContainerT()
|
||||
x._UnPack(container)
|
||||
return x
|
||||
|
||||
# ContainerT
|
||||
def _UnPack(self, container):
|
||||
if container is None:
|
||||
return
|
||||
self.uType = container.UType()
|
||||
self.u = union_name_test.my_test_union.MyTestUnionCreator(self.uType, container.U())
|
||||
|
||||
# ContainerT
|
||||
def Pack(self, builder):
|
||||
if self.u is not None:
|
||||
u = self.u.Pack(builder)
|
||||
ContainerStart(builder)
|
||||
ContainerAddUType(builder, self.uType)
|
||||
if self.u is not None:
|
||||
ContainerAddU(builder, u)
|
||||
container = ContainerEnd(builder)
|
||||
return container
|
||||
@@ -0,0 +1,90 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace: union_name_test
|
||||
|
||||
import flatbuffers
|
||||
from flatbuffers.compat import import_numpy
|
||||
np = import_numpy()
|
||||
|
||||
class Foo(object):
|
||||
__slots__ = ['_tab']
|
||||
|
||||
@classmethod
|
||||
def GetRootAs(cls, buf, offset=0):
|
||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
||||
x = Foo()
|
||||
x.Init(buf, n + offset)
|
||||
return x
|
||||
|
||||
@classmethod
|
||||
def GetRootAsFoo(cls, buf, offset=0):
|
||||
"""This method is deprecated. Please switch to GetRootAs."""
|
||||
return cls.GetRootAs(buf, offset)
|
||||
# Foo
|
||||
def Init(self, buf, pos):
|
||||
self._tab = flatbuffers.table.Table(buf, pos)
|
||||
|
||||
# Foo
|
||||
def Val(self):
|
||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
||||
if o != 0:
|
||||
return self._tab.Get(flatbuffers.number_types.Int32Flags, o + self._tab.Pos)
|
||||
return 0
|
||||
|
||||
def FooStart(builder):
|
||||
builder.StartObject(1)
|
||||
|
||||
def Start(builder):
|
||||
FooStart(builder)
|
||||
|
||||
def FooAddVal(builder, val):
|
||||
builder.PrependInt32Slot(0, val, 0)
|
||||
|
||||
def AddVal(builder, val):
|
||||
FooAddVal(builder, val)
|
||||
|
||||
def FooEnd(builder):
|
||||
return builder.EndObject()
|
||||
|
||||
def End(builder):
|
||||
return FooEnd(builder)
|
||||
|
||||
|
||||
class FooT(object):
|
||||
|
||||
# FooT
|
||||
def __init__(
|
||||
self,
|
||||
val = 0,
|
||||
):
|
||||
self.val = val # type: int
|
||||
|
||||
@classmethod
|
||||
def InitFromBuf(cls, buf, pos):
|
||||
foo = Foo()
|
||||
foo.Init(buf, pos)
|
||||
return cls.InitFromObj(foo)
|
||||
|
||||
@classmethod
|
||||
def InitFromPackedBuf(cls, buf, pos=0):
|
||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
|
||||
return cls.InitFromBuf(buf, pos+n)
|
||||
|
||||
@classmethod
|
||||
def InitFromObj(cls, foo):
|
||||
x = FooT()
|
||||
x._UnPack(foo)
|
||||
return x
|
||||
|
||||
# FooT
|
||||
def _UnPack(self, foo):
|
||||
if foo is None:
|
||||
return
|
||||
self.val = foo.Val()
|
||||
|
||||
# FooT
|
||||
def Pack(self, builder):
|
||||
FooStart(builder)
|
||||
FooAddVal(builder, self.val)
|
||||
foo = FooEnd(builder)
|
||||
return foo
|
||||
@@ -0,0 +1,20 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace: union_name_test
|
||||
|
||||
class my_test_union(object):
|
||||
NONE = 0
|
||||
Foo = 1
|
||||
Bar = 2
|
||||
|
||||
def MyTestUnionCreator(unionType, table):
|
||||
from flatbuffers.table import Table
|
||||
if not isinstance(table, Table):
|
||||
return None
|
||||
if unionType == my_test_union.Foo:
|
||||
import union_name_test.Foo
|
||||
return union_name_test.Foo.FooT.InitFromBuf(table.Bytes, table.Pos)
|
||||
if unionType == my_test_union.Bar:
|
||||
import union_name_test.Bar
|
||||
return union_name_test.Bar.BarT.InitFromBuf(table.Bytes, table.Pos)
|
||||
return None
|
||||
Reference in New Issue
Block a user