From f63c130c287312f54e9c4969be793c7674964833 Mon Sep 17 00:00:00 2001 From: mustiikhalil Date: Mon, 27 Sep 2021 20:59:19 +0200 Subject: [PATCH] Improves documentation, and adding DocC (#6784) Finished documenting flatbuffersbuilder Replaces swift 5.5 with 5.2 packages Starts building the tutorial for xcode 13 Finishes building the tutorial for xcode 13 Removes docc files from old swift versions Updates swift style guide --- .../swift/Greeter/Sources/client/main.swift | 6 +- .../swift/Greeter/Sources/server/main.swift | 16 +- swift.swiftformat | 3 +- swift/Package.swift | 3 +- swift/Package@swift-5.5.swift | 36 ++ swift/Sources/FlatBuffers/ByteBuffer.swift | 20 +- swift/Sources/FlatBuffers/Constants.swift | 6 +- .../Documentation.docc/Documentation.md | 22 + .../Resources/code/fbs/monster_step_1.fbs | 1 + .../Resources/code/fbs/monster_step_2.fbs | 1 + .../Resources/code/fbs/monster_step_3.fbs | 6 + .../Resources/code/fbs/monster_step_4.fbs | 12 + .../Resources/code/fbs/monster_step_5.fbs | 18 + .../Resources/code/fbs/monster_step_6.fbs | 25 ++ .../Resources/code/fbs/monster_step_7.fbs | 27 ++ .../Resources/code/swift/swift_code_1.swift | 1 + .../Resources/code/swift/swift_code_10.swift | 71 ++++ .../Resources/code/swift/swift_code_11.swift | 11 + .../Resources/code/swift/swift_code_12.swift | 19 + .../Resources/code/swift/swift_code_13.swift | 26 ++ .../Resources/code/swift/swift_code_2.swift | 2 + .../Resources/code/swift/swift_code_3.swift | 7 + .../Resources/code/swift/swift_code_4.swift | 10 + .../Resources/code/swift/swift_code_5.swift | 22 + .../Resources/code/swift/swift_code_6.swift | 26 ++ .../Resources/code/swift/swift_code_7.swift | 29 ++ .../Resources/code/swift/swift_code_8.swift | 40 ++ .../Resources/code/swift/swift_code_9.swift | 62 +++ .../images/tutorial_cover_image_1.png | Bin 0 -> 20176 bytes .../Tutorial_Table_of_Contents.tutorial | 14 + .../create_your_first_buffer.tutorial | 72 ++++ .../creating_flatbuffer_schema.tutorial | 47 ++ .../Tutorials/reading_bytebuffer.tutorial | 27 ++ swift/Sources/FlatBuffers/Enum.swift | 3 +- .../FlatBuffers/FlatBufferBuilder.swift | 400 +++++++++++++++--- .../FlatBuffers/FlatBufferObject.swift | 20 +- .../FlatBuffers/FlatBuffersUtils.swift | 2 + .../FlatBuffers/FlatbuffersErrors.swift | 5 +- swift/Sources/FlatBuffers/Message.swift | 6 +- swift/Sources/FlatBuffers/Mutable.swift | 8 +- swift/Sources/FlatBuffers/NativeObject.swift | 4 +- swift/Sources/FlatBuffers/Root.swift | 20 +- .../FlatBuffers/String+extension.swift | 18 +- swift/Sources/FlatBuffers/Table.swift | 28 +- swift/Sources/FlatBuffers/TableVerifier.swift | 9 +- swift/Sources/FlatBuffers/Verifier.swift | 10 +- .../FlatBuffers.Benchmarks.swift/main.swift | 3 +- tests/FlatBuffers.Test.Swift/Package.swift | 2 +- .../FlatBuffersMonsterWriterTests.swift | 30 +- .../FlatBuffersStructsTests.swift | 3 +- .../FlatBuffersTests.swift | 11 +- .../FlatBuffersUnionTests.swift | 55 ++- .../FlatBuffersVectorsTests.swift | 32 +- .../FlatbuffersDoubleTests.swift | 5 +- .../FlatbuffersVerifierTests.swift | 11 +- .../XCTestManifests.swift | 4 +- 56 files changed, 1214 insertions(+), 163 deletions(-) create mode 100644 swift/Package@swift-5.5.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Documentation.md create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_1.fbs create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_2.fbs create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_3.fbs create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_4.fbs create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_5.fbs create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_6.fbs create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_7.fbs create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_1.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_10.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_11.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_12.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_13.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_2.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_3.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_4.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_5.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_6.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_7.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_8.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_9.swift create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Resources/images/tutorial_cover_image_1.png create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Tutorials/Tutorial_Table_of_Contents.tutorial create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Tutorials/create_your_first_buffer.tutorial create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Tutorials/creating_flatbuffer_schema.tutorial create mode 100644 swift/Sources/FlatBuffers/Documentation.docc/Tutorials/reading_bytebuffer.tutorial diff --git a/grpc/examples/swift/Greeter/Sources/client/main.swift b/grpc/examples/swift/Greeter/Sources/client/main.swift index a6b113000..168b0713c 100644 --- a/grpc/examples/swift/Greeter/Sources/client/main.swift +++ b/grpc/examples/swift/Greeter/Sources/client/main.swift @@ -37,7 +37,8 @@ func greet(name: String, client greeter: models_GreeterServiceClient) { builder.finish(offset: root) // Make the RPC call to the server. - let sayHello = greeter.SayHello(Message(builder: &builder)) + let sayHello = greeter + .SayHello(Message(builder: &builder)) // wait() on the response to stop the program from exiting before the response is received. do { @@ -54,7 +55,8 @@ func greet(name: String, client greeter: models_GreeterServiceClient) { builder.finish(offset: manyRoot) let call = greeter.SayManyHellos(Message(builder: &builder)) { message in - print("Greeter SayManyHellos received: \(message.object.message ?? "Unknown")") + print( + "Greeter SayManyHellos received: \(message.object.message ?? "Unknown")") } let status = try! call.status.recover { _ in .processingError }.wait() diff --git a/grpc/examples/swift/Greeter/Sources/server/main.swift b/grpc/examples/swift/Greeter/Sources/server/main.swift index af1c5557f..fca623f5a 100644 --- a/grpc/examples/swift/Greeter/Sources/server/main.swift +++ b/grpc/examples/swift/Greeter/Sources/server/main.swift @@ -32,7 +32,8 @@ class Greeter: models_GreeterProvider { func SayHello( request: Message, - context: StatusOnlyCallContext) -> EventLoopFuture> + context: StatusOnlyCallContext) + -> EventLoopFuture> { let recipient = request.object.name ?? "Stranger" @@ -40,17 +41,22 @@ class Greeter: models_GreeterProvider { let off = builder.create(string: "Hello \(recipient)") let root = models_HelloReply.createHelloReply(&builder, messageOffset: off) builder.finish(offset: root) - return context.eventLoop.makeSucceededFuture(Message(builder: &builder)) + return context.eventLoop + .makeSucceededFuture(Message(builder: &builder)) } func SayManyHellos( request: Message, - context: StreamingResponseCallContext>) -> EventLoopFuture + context: StreamingResponseCallContext>) + -> EventLoopFuture { for name in greetings { var builder = FlatBufferBuilder() - let off = builder.create(string: "\(name) \(request.object.name ?? "Unknown")") - let root = models_HelloReply.createHelloReply(&builder, messageOffset: off) + let off = builder + .create(string: "\(name) \(request.object.name ?? "Unknown")") + let root = models_HelloReply.createHelloReply( + &builder, + messageOffset: off) builder.finish(offset: root) _ = context.sendResponse(Message(builder: &builder)) } diff --git a/swift.swiftformat b/swift.swiftformat index 3f4c45d14..b198b9292 100644 --- a/swift.swiftformat +++ b/swift.swiftformat @@ -17,10 +17,11 @@ --typeattributes prev-line # wrapAttributes # rules ---rules todos,anyObjectProtocol,redundantParens,redundantReturn,redundantSelf,sortedImports,strongifiedSelf,trailingCommas,trailingSpace,wrapArguments,wrapMultilineStatementBraces,indent,wrapAttributes,void,fileHeader +--rules wrap,todos,anyObjectProtocol,redundantParens,redundantReturn,redundantSelf,sortedImports,strongifiedSelf,trailingCommas,trailingSpace,wrapArguments,wrapMultilineStatementBraces,indent,wrapAttributes,void,fileHeader --disable trailingclosures --exclude **/*_generated.swift +--exclude **/swift_code_*.swift --exclude **/*.grpc.swift --header "/*\n * Copyright {year} Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */" \ No newline at end of file diff --git a/swift/Package.swift b/swift/Package.swift index 5d4c7cc2a..d2d2d5c6f 100644 --- a/swift/Package.swift +++ b/swift/Package.swift @@ -31,5 +31,6 @@ let package = Package( targets: [ .target( name: "FlatBuffers", - dependencies: []), + dependencies: [], + exclude: ["Documentation.docc/Resources/code/swift"]), ]) diff --git a/swift/Package@swift-5.5.swift b/swift/Package@swift-5.5.swift new file mode 100644 index 000000000..3cfdcf602 --- /dev/null +++ b/swift/Package@swift-5.5.swift @@ -0,0 +1,36 @@ +// swift-tools-version:5.5 +/* + * Copyright 2020 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 PackageDescription + +let package = Package( + name: "FlatBuffers", + platforms: [ + .iOS(.v11), + .macOS(.v10_14), + ], + products: [ + .library( + name: "FlatBuffers", + targets: ["FlatBuffers"]), + ], + targets: [ + .target( + name: "FlatBuffers", + dependencies: []), + ]) + diff --git a/swift/Sources/FlatBuffers/ByteBuffer.swift b/swift/Sources/FlatBuffers/ByteBuffer.swift index c658d4679..f0ba5d099 100644 --- a/swift/Sources/FlatBuffers/ByteBuffer.swift +++ b/swift/Sources/FlatBuffers/ByteBuffer.swift @@ -164,7 +164,10 @@ public struct ByteBuffer { /// Constructor that creates a Flatbuffer from unsafe memory region without copying /// - Parameter assumingMemoryBound: The unsafe memory region /// - Parameter capacity: The size of the given memory region - public init(assumingMemoryBound memory: UnsafeMutableRawPointer, capacity: Int) { + public init( + assumingMemoryBound memory: UnsafeMutableRawPointer, + capacity: Int) + { _storage = Storage(memory: memory, capacity: capacity, unowned: true) _writerSize = capacity } @@ -244,7 +247,10 @@ public struct ByteBuffer { @usableFromInline mutating func push(string str: String, len: Int) { ensureSpace(size: len) - if str.utf8.withContiguousStorageIfAvailable({ self.push(bytes: $0, len: len) }) != nil { + if str.utf8 + .withContiguousStorageIfAvailable({ self.push(bytes: $0, len: len) }) != + nil + { } else { let utf8View = str.utf8 for c in utf8View.reversed() { @@ -304,7 +310,9 @@ public struct ByteBuffer { /// - Parameter size: size of the `VTable` @inline(__always) mutating func pop(_ size: Int) { - assert((_writerSize &- size) > 0, "New size should NOT be a negative number") + assert( + (_writerSize &- size) > 0, + "New size should NOT be a negative number") memset(_storage.memory.advanced(by: writerIndex), 0, _writerSize &- size) _writerSize = size } @@ -341,7 +349,8 @@ public struct ByteBuffer { assert( index + count <= _storage.capacity, "Reading out of bounds is illegal") - let start = _storage.memory.advanced(by: index).assumingMemoryBound(to: T.self) + let start = _storage.memory.advanced(by: index) + .assumingMemoryBound(to: T.self) let array = UnsafeBufferPointer(start: start, count: count) return Array(array) } @@ -359,7 +368,8 @@ public struct ByteBuffer { assert( index + count <= _storage.capacity, "Reading out of bounds is illegal") - let start = _storage.memory.advanced(by: index).assumingMemoryBound(to: UInt8.self) + let start = _storage.memory.advanced(by: index) + .assumingMemoryBound(to: UInt8.self) let bufprt = UnsafeBufferPointer(start: start, count: count) return String(bytes: Array(bufprt), encoding: type) } diff --git a/swift/Sources/FlatBuffers/Constants.swift b/swift/Sources/FlatBuffers/Constants.swift index 50a58178a..8e643fdf8 100644 --- a/swift/Sources/FlatBuffers/Constants.swift +++ b/swift/Sources/FlatBuffers/Constants.swift @@ -21,7 +21,8 @@ import Foundation #endif /// A boolean to see if the system is littleEndian -let isLitteEndian = CFByteOrderGetCurrent() == Int(CFByteOrderLittleEndian.rawValue) +let isLitteEndian = CFByteOrderGetCurrent() == + Int(CFByteOrderLittleEndian.rawValue) /// Constant for the file id length let FileIdLength = 4 /// Type aliases @@ -30,7 +31,8 @@ public typealias UOffset = UInt32 public typealias SOffset = Int32 public typealias VOffset = UInt16 /// Maximum size for a buffer -public let FlatBufferMaxSize = UInt32.max << ((MemoryLayout.size * 8 - 1) - 1) +public let FlatBufferMaxSize = UInt32 + .max << ((MemoryLayout.size * 8 - 1) - 1) /// Protocol that All Scalars should conform to /// diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Documentation.md b/swift/Sources/FlatBuffers/Documentation.docc/Documentation.md new file mode 100644 index 000000000..a1510808e --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Documentation.md @@ -0,0 +1,22 @@ +# ``FlatBuffers`` + +FlatBuffers: Memory Efficient Serialization Library + +## Overview + +- Access to serialized data without parsing/unpacking - What sets FlatBuffers apart is that it represents hierarchical data in a flat binary buffer in such a way that it can still be accessed directly without parsing/unpacking, while also still supporting data structure evolution (forwards/backwards compatibility). +- Memory efficiency and speed - The only memory needed to access your data is that of the buffer. It requires 0 additional allocations (in C++, other languages may vary). FlatBuffers is also very suitable for use with mmap (or streaming), requiring only part of the buffer to be in memory. Access is close to the speed of raw struct access with only one extra indirection (a kind of vtable) to allow for format evolution and optional fields. It is aimed at projects where spending time and space (many memory allocations) to be able to access or construct serialized data is undesirable, such as in games or any other performance sensitive applications. See the benchmarks for details. +- Flexible - Optional fields means not only do you get great forwards and backwards compatibility (increasingly important for long-lived games: don't have to update all data with each new version!). It also means you have a lot of choice in what data you write and what data you don't, and how you design data structures. +- Tiny code footprint - Small amounts of generated code, and just a single small header as the minimum dependency, which is very easy to integrate. Again, see the benchmark section for details. +- Strongly typed - Errors happen at compile time rather than manually having to write repetitive and error prone run-time checks. Useful code can be generated for you. + +## Topics + +### Read this first + +- + +### Where to start + +- ``FlatBufferBuilder`` +- ``ByteBuffer`` diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_1.fbs b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_1.fbs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_1.fbs @@ -0,0 +1 @@ + diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_2.fbs b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_2.fbs new file mode 100644 index 000000000..a43897845 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_2.fbs @@ -0,0 +1 @@ +enum Color:byte { red, green, blue } diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_3.fbs b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_3.fbs new file mode 100644 index 000000000..d31a29cd0 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_3.fbs @@ -0,0 +1,6 @@ +enum Color:byte { red, green, blue } + +struct Vec3 { + x:float; + y:float; +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_4.fbs b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_4.fbs new file mode 100644 index 000000000..51f7bb1aa --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_4.fbs @@ -0,0 +1,12 @@ +enum Color:byte { red, green, blue } + +struct Vec3 { + x:float; + y:float; +} + +table Monster { + pos:Vec3; + color:Color = Blue; +} + diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_5.fbs b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_5.fbs new file mode 100644 index 000000000..8d0b72956 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_5.fbs @@ -0,0 +1,18 @@ +enum Color:byte { red, green, blue } + +struct Vec3 { + x:float; + y:float; +} + +table Monster { + pos:Vec3; + color:Color = Blue; + + mana:short = 150; + hp:short = 100; + name:string; + equipped:Equipment; + weapons:[Weapon]; + path:[Vec3]; +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_6.fbs b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_6.fbs new file mode 100644 index 000000000..10c3eaf67 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_6.fbs @@ -0,0 +1,25 @@ +enum Color:byte { red, green, blue } + +union Equipment { Weapon } // Optionally add more tables. + +struct Vec3 { + x:float; + y:float; +} + +table Monster { + pos:Vec3; + color:Color = Blue; + + mana:short = 150; + hp:short = 100; + name:string; + equipped:Equipment; + weapons:[Weapon]; + path:[Vec3]; +} + +table Weapon { + name:string; + damage:short; +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_7.fbs b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_7.fbs new file mode 100644 index 000000000..b4dde6ced --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/fbs/monster_step_7.fbs @@ -0,0 +1,27 @@ +enum Color:byte { red, green, blue } + +union Equipment { Weapon } // Optionally add more tables. + +struct Vec3 { + x:float; + y:float; +} + +table Monster { + pos:Vec3; + color:Color = Blue; + + mana:short = 150; + hp:short = 100; + name:string; + equipped:Equipment; + weapons:[Weapon]; + path:[Vec3]; +} + +table Weapon { + name:string; + damage:short; +} + +root_type Monster; // flatc --swift monster.fbs diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_1.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_1.swift new file mode 100644 index 000000000..fecc4ab44 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_1.swift @@ -0,0 +1 @@ +import Foundation diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_10.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_10.swift new file mode 100644 index 000000000..51d4fbfcd --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_10.swift @@ -0,0 +1,71 @@ +import FlatBuffers +import Foundation + +func run() { + // create a `FlatBufferBuilder`, which will be used to serialize objects + let builder = FlatBufferBuilder(initialSize: 1024) + + let weapon1Name = builder.create(string: "Sword") + let weapon2Name = builder.create(string: "Axe") + + // start creating the weapon by calling startWeapon + let weapon1Start = Weapon.startWeapon(&builder) + Weapon.add(name: weapon1Name, &builder) + Weapon.add(damage: 3, &builder) + // end the object by passing the start point for the weapon 1 + let sword = Weapon.endWeapon(&builder, start: weapon1Start) + + let weapon2Start = Weapon.startWeapon(&builder) + Weapon.add(name: weapon2Name, &builder) + Weapon.add(damage: 5, &builder) + let axe = Weapon.endWeapon(&builder, start: weapon2Start) + + // Create a FlatBuffer `vector` that contains offsets to the sword and axe + // we created above. + let weaponsOffset = builder.createVector(ofOffsets: [sword, axe]) + + // Name of the Monster. + let name = builder.create(string: "Orc") + + let pathOffset = fbb.createVector(ofStructs: [ + Vec3(x: 0, y: 0), + Vec3(x: 5, y: 5), + ]) + + // startVector(len, elementSize: MemoryLayout.size) + // for o in offsets.reversed() { + // push(element: o) + // } + // endVector(len: len) + + let orc = Monster.createMonster( + &builder, + pos: Vec3(x: 1, y: 2), + hp: 300, + nameOffset: name, + color: .red, + weaponsVectorOffset: weaponsOffset, + equippedType: .weapon, + equippedOffset: axe, + pathOffset: pathOffset) + + // let start = Monster.startMonster(&builder) + // Monster.add(pos: Vec3(x: 1, y: 2), &builder) + // Monster.add(hp: 300, &builder) + // Monster.add(name: name, &builder) + // Monster.add(color: .red, &builder) + // Monster.addVectorOf(weapons: weaponsOffset, &builder) + // Monster.add(equippedType: .weapon, &builder) + // Monster.addVectorOf(paths: weaponsOffset, &builder) + // Monster.add(equipped: axe, &builder) + // var orc = Monster.endMonster(&builder, start: start) + + // Call `finish(offset:)` to instruct the builder that this monster is complete. + builder.finish(offset: orc) + // This must be called after `finish()`. + // `sizedByteArray` returns the finished buf of type [UInt8]. + let buf = builder.sizedByteArray + + // or you can use to get an object of type Data + let bufData = ByteBuffer(data: builder.sizedBuffer) +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_11.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_11.swift new file mode 100644 index 000000000..3ed7ea242 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_11.swift @@ -0,0 +1,11 @@ +import FlatBuffers +import Foundation + +func run() { + // create a ByteBuffer(:) from an [UInt8] or Data() + let buf = [] // Get your data + + // Get an accessor to the root object inside the buffer. + let monster: Monster = try! getCheckedRoot(byteBuffer: ByteBuffer(bytes: buf)) + // let monster: Monster = getRoot(byteBuffer: ByteBuffer(bytes: buf)) +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_12.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_12.swift new file mode 100644 index 000000000..895653ebf --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_12.swift @@ -0,0 +1,19 @@ +import FlatBuffers +import Foundation + +func run() { + // create a ByteBuffer(:) from an [UInt8] or Data() + let buf = [] // Get your data + + // Get an accessor to the root object inside the buffer. + let monster: Monster = try! getCheckedRoot(byteBuffer: ByteBuffer(bytes: buf)) + // let monster: Monster = getRoot(byteBuffer: ByteBuffer(bytes: buf)) + + let hp = monster.hp + let mana = monster.mana + let name = monster.name // returns an optional string + + let pos = monster.pos + let x = pos.x + let y = pos.y +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_13.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_13.swift new file mode 100644 index 000000000..7aac982cf --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_13.swift @@ -0,0 +1,26 @@ +import FlatBuffers +import Foundation + +func run() { + // create a ByteBuffer(:) from an [UInt8] or Data() + let buf = [] // Get your data + + // Get an accessor to the root object inside the buffer. + let monster: Monster = try! getCheckedRoot(byteBuffer: ByteBuffer(bytes: buf)) + // let monster: Monster = getRoot(byteBuffer: ByteBuffer(bytes: buf)) + + let hp = monster.hp + let mana = monster.mana + let name = monster.name // returns an optional string + + let pos = monster.pos + let x = pos.x + let y = pos.y + + // Get and check if the monster has an equipped item + if monster.equippedType == .weapon { + let _weapon = monster.equipped(type: Weapon.self) + let name = _weapon.name // should return "Axe" + let dmg = _weapon.damage // should return 5 + } +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_2.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_2.swift new file mode 100644 index 000000000..ddd066e7a --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_2.swift @@ -0,0 +1,2 @@ +import FlatBuffers +import Foundation diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_3.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_3.swift new file mode 100644 index 000000000..bacdaa551 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_3.swift @@ -0,0 +1,7 @@ +import FlatBuffers +import Foundation + +func run() { + // create a `FlatBufferBuilder`, which will be used to serialize objects + let builder = FlatBufferBuilder(initialSize: 1024) +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_4.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_4.swift new file mode 100644 index 000000000..87546993b --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_4.swift @@ -0,0 +1,10 @@ +import FlatBuffers +import Foundation + +func run() { + // create a `FlatBufferBuilder`, which will be used to serialize objects + let builder = FlatBufferBuilder(initialSize: 1024) + + let weapon1Name = builder.create(string: "Sword") + let weapon2Name = builder.create(string: "Axe") +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_5.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_5.swift new file mode 100644 index 000000000..12e0d4ca6 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_5.swift @@ -0,0 +1,22 @@ +import FlatBuffers +import Foundation + +func run() { + // create a `FlatBufferBuilder`, which will be used to serialize objects + let builder = FlatBufferBuilder(initialSize: 1024) + + let weapon1Name = builder.create(string: "Sword") + let weapon2Name = builder.create(string: "Axe") + + // start creating the weapon by calling startWeapon + let weapon1Start = Weapon.startWeapon(&builder) + Weapon.add(name: weapon1Name, &builder) + Weapon.add(damage: 3, &builder) + // end the object by passing the start point for the weapon 1 + let sword = Weapon.endWeapon(&builder, start: weapon1Start) + + let weapon2Start = Weapon.startWeapon(&builder) + Weapon.add(name: weapon2Name, &builder) + Weapon.add(damage: 5, &builder) + let axe = Weapon.endWeapon(&builder, start: weapon2Start) +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_6.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_6.swift new file mode 100644 index 000000000..bfb4f7e51 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_6.swift @@ -0,0 +1,26 @@ +import FlatBuffers +import Foundation + +func run() { + // create a `FlatBufferBuilder`, which will be used to serialize objects + let builder = FlatBufferBuilder(initialSize: 1024) + + let weapon1Name = builder.create(string: "Sword") + let weapon2Name = builder.create(string: "Axe") + + // start creating the weapon by calling startWeapon + let weapon1Start = Weapon.startWeapon(&builder) + Weapon.add(name: weapon1Name, &builder) + Weapon.add(damage: 3, &builder) + // end the object by passing the start point for the weapon 1 + let sword = Weapon.endWeapon(&builder, start: weapon1Start) + + let weapon2Start = Weapon.startWeapon(&builder) + Weapon.add(name: weapon2Name, &builder) + Weapon.add(damage: 5, &builder) + let axe = Weapon.endWeapon(&builder, start: weapon2Start) + + // Create a FlatBuffer `vector` that contains offsets to the sword and axe + // we created above. + let weaponsOffset = builder.createVector(ofOffsets: [sword, axe]) +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_7.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_7.swift new file mode 100644 index 000000000..97264b018 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_7.swift @@ -0,0 +1,29 @@ +import FlatBuffers +import Foundation + +func run() { + // create a `FlatBufferBuilder`, which will be used to serialize objects + let builder = FlatBufferBuilder(initialSize: 1024) + + let weapon1Name = builder.create(string: "Sword") + let weapon2Name = builder.create(string: "Axe") + + // start creating the weapon by calling startWeapon + let weapon1Start = Weapon.startWeapon(&builder) + Weapon.add(name: weapon1Name, &builder) + Weapon.add(damage: 3, &builder) + // end the object by passing the start point for the weapon 1 + let sword = Weapon.endWeapon(&builder, start: weapon1Start) + + let weapon2Start = Weapon.startWeapon(&builder) + Weapon.add(name: weapon2Name, &builder) + Weapon.add(damage: 5, &builder) + let axe = Weapon.endWeapon(&builder, start: weapon2Start) + + // Create a FlatBuffer `vector` that contains offsets to the sword and axe + // we created above. + let weaponsOffset = builder.createVector(ofOffsets: [sword, axe]) + + // Name of the Monster. + let name = builder.create(string: "Orc") +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_8.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_8.swift new file mode 100644 index 000000000..a0c281980 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_8.swift @@ -0,0 +1,40 @@ +import FlatBuffers +import Foundation + +func run() { + // create a `FlatBufferBuilder`, which will be used to serialize objects + let builder = FlatBufferBuilder(initialSize: 1024) + + let weapon1Name = builder.create(string: "Sword") + let weapon2Name = builder.create(string: "Axe") + + // start creating the weapon by calling startWeapon + let weapon1Start = Weapon.startWeapon(&builder) + Weapon.add(name: weapon1Name, &builder) + Weapon.add(damage: 3, &builder) + // end the object by passing the start point for the weapon 1 + let sword = Weapon.endWeapon(&builder, start: weapon1Start) + + let weapon2Start = Weapon.startWeapon(&builder) + Weapon.add(name: weapon2Name, &builder) + Weapon.add(damage: 5, &builder) + let axe = Weapon.endWeapon(&builder, start: weapon2Start) + + // Create a FlatBuffer `vector` that contains offsets to the sword and axe + // we created above. + let weaponsOffset = builder.createVector(ofOffsets: [sword, axe]) + + // Name of the Monster. + let name = builder.create(string: "Orc") + + let pathOffset = fbb.createVector(ofStructs: [ + Vec3(x: 0, y: 0), + Vec3(x: 5, y: 5), + ]) + + // startVector(len, elementSize: MemoryLayout.size) + // for o in offsets.reversed() { + // push(element: o) + // } + // endVector(len: len) +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_9.swift b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_9.swift new file mode 100644 index 000000000..51ce8fd2c --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Resources/code/swift/swift_code_9.swift @@ -0,0 +1,62 @@ +import FlatBuffers +import Foundation + +func run() { + // create a `FlatBufferBuilder`, which will be used to serialize objects + let builder = FlatBufferBuilder(initialSize: 1024) + + let weapon1Name = builder.create(string: "Sword") + let weapon2Name = builder.create(string: "Axe") + + // start creating the weapon by calling startWeapon + let weapon1Start = Weapon.startWeapon(&builder) + Weapon.add(name: weapon1Name, &builder) + Weapon.add(damage: 3, &builder) + // end the object by passing the start point for the weapon 1 + let sword = Weapon.endWeapon(&builder, start: weapon1Start) + + let weapon2Start = Weapon.startWeapon(&builder) + Weapon.add(name: weapon2Name, &builder) + Weapon.add(damage: 5, &builder) + let axe = Weapon.endWeapon(&builder, start: weapon2Start) + + // Create a FlatBuffer `vector` that contains offsets to the sword and axe + // we created above. + let weaponsOffset = builder.createVector(ofOffsets: [sword, axe]) + + // Name of the Monster. + let name = builder.create(string: "Orc") + + let pathOffset = fbb.createVector(ofStructs: [ + Vec3(x: 0, y: 0), + Vec3(x: 5, y: 5), + ]) + + // startVector(len, elementSize: MemoryLayout.size) + // for o in offsets.reversed() { + // push(element: o) + // } + // endVector(len: len) + + let orc = Monster.createMonster( + &builder, + pos: Vec3(x: 1, y: 2), + hp: 300, + nameOffset: name, + color: .red, + weaponsVectorOffset: weaponsOffset, + equippedType: .weapon, + equippedOffset: axe, + pathOffset: pathOffset) + + // let start = Monster.startMonster(&builder) + // Monster.add(pos: Vec3(x: 1, y: 2), &builder) + // Monster.add(hp: 300, &builder) + // Monster.add(name: name, &builder) + // Monster.add(color: .red, &builder) + // Monster.addVectorOf(weapons: weaponsOffset, &builder) + // Monster.add(equippedType: .weapon, &builder) + // Monster.addVectorOf(paths: weaponsOffset, &builder) + // Monster.add(equipped: axe, &builder) + // var orc = Monster.endMonster(&builder, start: start) +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Resources/images/tutorial_cover_image_1.png b/swift/Sources/FlatBuffers/Documentation.docc/Resources/images/tutorial_cover_image_1.png new file mode 100644 index 0000000000000000000000000000000000000000..0e64fe601486ac93ce649ff9d5fc8b8ad2300944 GIT binary patch literal 20176 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�C@3%ug6|-S7ZMsAFtiKqbNK07YST6hsu{-y%6pt`qFaB zuT!!|Tv&6620zBRn>kOumAz*I?fw97|HA>GtYGj^FmyO`8KdF{vj7TlfOEK)QsFa? z?|Ts|9AxL!&)AC(#hr1;DZ4-|p)JOQc(T>LVb7m|7@*y`M6X(#^`-5yo~Y5^t9WNu zRR4qQ&s1SD$=EoXwf>f%9n_6;$~(+mTQiFc$qbc*9LPuvqP<#s8lr;HJaYW_@t(HW zf;v}GIH4yyJL_h?4Yd{iXLqcECL8Oyqmr4P?)q_S5PN$_ak9><&<@N2P(L|TK5BK8 z$Ud{-G(6F#I4B8aI00p8z}vy(?=vEgows`(P68{Thw{^}ZQGX8}zQOSN{dG=a*&x literal 0 HcmV?d00001 diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Tutorials/Tutorial_Table_of_Contents.tutorial b/swift/Sources/FlatBuffers/Documentation.docc/Tutorials/Tutorial_Table_of_Contents.tutorial new file mode 100644 index 000000000..009116fc4 --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Tutorials/Tutorial_Table_of_Contents.tutorial @@ -0,0 +1,14 @@ +@Tutorials(name: "Starting with FlatBuffers") { + @Intro(title: "Starting with FlatBuffers") { + FlatBuffers is an efficient cross platform serialization library for C++, + C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust and Swift. + It was originally created at Google for game development and other performance-critical applications. + } + @Chapter(name: "Generating your code") { + Start by generating your first FlatBuffers objects. + @Image(source: tutorial_cover_image_1.png, alt: "A code structure for a base struct in flatbuffers") + @TutorialReference(tutorial: "doc:creating_flatbuffer_schema") + @TutorialReference(tutorial: "doc:create_your_first_buffer") + @TutorialReference(tutorial: "doc:reading_bytebuffer") + } +} diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Tutorials/create_your_first_buffer.tutorial b/swift/Sources/FlatBuffers/Documentation.docc/Tutorials/create_your_first_buffer.tutorial new file mode 100644 index 000000000..2f8089f7d --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Tutorials/create_your_first_buffer.tutorial @@ -0,0 +1,72 @@ +@Tutorial(time: 5) { + @Intro(title: "After having our code generated") { + After generating the code from the previous section, we will know start creating our monster object. + We will create a monster object called orc. + } + + @Section(title: "Building your first buffer") { + @ContentAndMedia {} + @Steps { + @Step { + Starting with a new file, we will create our very first Flatbuffer. + @Code(name: "ViewController.swift", file: "swift_code_1.swift") + } + @Step { + First, we need to import ``FlatBuffers`` + @Code(name: "ViewController.swift", file: "swift_code_2.swift") + } + @Step { + We need to create an instance of the `FlatBufferBuilder`, which will contain the buffer as it grows. + You can pass an initial size of the buffer (here 1024 bytes), which will grow automatically if needed. + @Code(name: "ViewController.swift", file: "swift_code_3.swift") + } + @Step { + After creating the builder, we can start serializing our data. Before we make our orc Monster, + let's create some Weapons: a Sword and an Axe. However we will start by naming our weapons as `Sword` and `Axe` + @Code(name: "ViewController.swift", file: "swift_code_4.swift") + } + @Step { + After naming the weapons, we will create two weapon objects with the damage that the weapon is going to deal. + That's done by calling the `start` Method on each table you will be creating, in this case its called `startWeapon` + and finished by calling `end`. + @Code(name: "ViewController.swift", file: "swift_code_5.swift") + } + @Step { + We will take our (Sword and Axe) serialized data and serialize their offsets as a vector of tables into our `ByteBuffer`. + So we can reference them later on from our Monster Object + @Code(name: "ViewController.swift", file: "swift_code_6.swift") + } + @Step { + We will add our Monster name as a string value just like we did with the weapons. + @Code(name: "ViewController.swift", file: "swift_code_7.swift") + } + + @Step { + We will create a path that our monster should be using while roaming in its den. To create a vector of paths we would us + `createVector(ofStructs: [])` which will take a Native `Swift` struct that has been padded to fit the `FlatBuffers` standards. + + There are usually two ways of creating vectors in `FlatBuffers` which you can see in commented out code. + And thus there are multiple convenience methods that will cover all the bases + when trying to create a vector so that you dont have to create it with `start` and `end` + @Code(name: "ViewController.swift", file: "swift_code_8.swift") + } + + @Step { + Now to serialize our data into our `Monster` object. Which again there are two ways of doing, by calling the `create` method or + by serializing the objects yourself. What we added to our Monster were the `Equipped Type` and the `Equipped` union itself, which + allows the Monster to have the `Axe` as his equipped weapon. + + Important: Unlike structs, you should not nest tables or other objects, + which is why we created all the `strings/vectors/tables` that this monster refers to before start. + If you try to create any of them between start and end, you will get an `assert`. + @Code(name: "ViewController.swift", file: "swift_code_9.swift") + } + + @Step { + Finally you can just finalize the buffer by calling `builder.finish` and get the Byte array from the buffer. + @Code(name: "ViewController.swift", file: "swift_code_10.swift") + } + + } + } + } diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Tutorials/creating_flatbuffer_schema.tutorial b/swift/Sources/FlatBuffers/Documentation.docc/Tutorials/creating_flatbuffer_schema.tutorial new file mode 100644 index 000000000..0fcd362ef --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Tutorials/creating_flatbuffer_schema.tutorial @@ -0,0 +1,47 @@ +@Tutorial(time: 2) { + @Intro(title: "Creating a schema") { + You will need to have the FlatBuffer compiler to be installed on your device + } + + @Section(title: "Creating a schema") { + @ContentAndMedia {} + @Steps { + @Step { + Start by creating a new empty folder called `monster.fbs`. We want to create a Monster table, that contains + position, color, and basic information about the monster. + @Code(name: "monster.fbs", file: "monster_step_1.fbs") + } + @Step { + We will start by adding our Color object. We will be using an enumerate, to represent this object + @Code(name: "monster.fbs", file: "monster_step_2.fbs") + } + @Step { + We will add a position object and will use a struct to represent that type of data. Where we will need the monsters + x and y positions. + @Code(name: "monster.fbs", file: "monster_step_3.fbs") + } + @Step { + Then we will be creating our Monster object of type table. This will contain the current position of our + monster and its color + @Code(name: "monster.fbs", file: "monster_step_4.fbs") + } + @Step { + Our Monster is missing a name, mana, hp, name, equipped Weapon, weapons, and path. We will be adding these + fields to our table with a proper data type for each. Example; weapons, and path would be a vector of data. + @Code(name: "monster.fbs", file: "monster_step_5.fbs") + } + @Step { + Now we are missing two data types here, `Weapon` and `Equipment`. And since Equipment can be a weapon, we will be using + a `Union` enumerate that can contain all the equipment that you would want your monster to have. And the weapon can simply + have a name and amount of damage + @Code(name: "monster.fbs", file: "monster_step_6.fbs") + } + @Step { + And to finalize our monster table, we can add a root type of type Monster. + Then run the command `flatc --swift monster.fbs` + Note: Make sure to import the file to your xcode project. + @Code(name: "monster.fbs", file: "monster_step_7.fbs") + } + } + } + } diff --git a/swift/Sources/FlatBuffers/Documentation.docc/Tutorials/reading_bytebuffer.tutorial b/swift/Sources/FlatBuffers/Documentation.docc/Tutorials/reading_bytebuffer.tutorial new file mode 100644 index 000000000..2c4609f7e --- /dev/null +++ b/swift/Sources/FlatBuffers/Documentation.docc/Tutorials/reading_bytebuffer.tutorial @@ -0,0 +1,27 @@ +@Tutorial(time: 2) { + @Intro(title: "Reading ByteBuffers") { + After getting our ByteBuffer created, we can now read it. + } + + @Section(title: "Reading your first buffer") { + @ContentAndMedia {} + @Steps { + @Step { + After fetching the data from disk or network you need to access that data, and that can be done. + By simply calling `getCheckedRoot`, which checks if the data is valid before enabling you to read from a corrupt buffer. + however, if you are sure that the data is 100% correct you can simply call `getRoot` + @Code(name: "ViewController.swift", file: "swift_code_11.swift") + } + @Step { + Now since we have a Monster object, all the fields can be accessed by simply fetching the data. Note, Deprecated fields will not + show up + @Code(name: "ViewController.swift", file: "swift_code_12.swift") + } + @Step { + And you can access union types as easy as this + @Code(name: "ViewController.swift", file: "swift_code_13.swift") + } + } + } + } + diff --git a/swift/Sources/FlatBuffers/Enum.swift b/swift/Sources/FlatBuffers/Enum.swift index f8cbebb19..efb698b1e 100644 --- a/swift/Sources/FlatBuffers/Enum.swift +++ b/swift/Sources/FlatBuffers/Enum.swift @@ -17,7 +17,8 @@ import Foundation /// Enum is a protocol that all flatbuffers enums should conform to -/// Since it allows us to get the actual `ByteSize` and `Value` +/// Since it allows us to get the actual `ByteSize` and `Value` from +/// a swift enum. public protocol Enum { /// associatedtype that the type of the enum should conform to associatedtype T: Scalar & Verifiable diff --git a/swift/Sources/FlatBuffers/FlatBufferBuilder.swift b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift index 71b713992..f9ae83b1d 100644 --- a/swift/Sources/FlatBuffers/FlatBufferBuilder.swift +++ b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift @@ -16,9 +16,16 @@ import Foundation -/// `FlatBufferBuilder` builds a `FlatBuffer` through manipulating its internal state. -/// This is done by creating a `ByteBuffer` that hosts the incoming data and -/// has a hardcoded growth limit of `2GiB` which is set by the Flatbuffers standards +/// ``FlatBufferBuilder`` builds a `FlatBuffer` through manipulating its internal state. +/// +/// This is done by creating a ``ByteBuffer`` that hosts the incoming data and +/// has a hardcoded growth limit of `2GiB` which is set by the Flatbuffers standards. +/// +/// ```swift +/// var builder = FlatBufferBuilder() +/// ``` +/// The builder should be always created as a variable, since it would be passed into the writers +/// @frozen public struct FlatBufferBuilder { @@ -47,21 +54,30 @@ public struct FlatBufferBuilder { /// Gives a read access to the buffer's size public var size: UOffset { _bb.size } + /// Data representation of the buffer + /// + /// Should only be used after ``finish(offset:addPrefix:)`` is called public var data: Data { assert(finished, "Data shouldn't be called before finish()") return Data( bytes: _bb.memory.advanced(by: _bb.writerIndex), count: _bb.capacity &- _bb.writerIndex) } - /// Get's the fully sized buffer stored in memory + + /// Returns the underlying bytes in the ``ByteBuffer`` + /// + /// Note: This should be used with caution. public var fullSizedByteArray: [UInt8] { let ptr = UnsafeBufferPointer( start: _bb.memory.assumingMemoryBound(to: UInt8.self), count: _bb.capacity) return Array(ptr) } - /// Returns the written size of the buffer + + /// Returns the written bytes into the ``ByteBuffer`` + /// + /// Should only be used after ``finish(offset:addPrefix:)`` is called public var sizedByteArray: [UInt8] { assert(finished, "Data shouldn't be called before finish()") let cp = _bb.capacity &- _bb.writerIndex @@ -71,10 +87,17 @@ public struct FlatBufferBuilder { let ptr = UnsafeBufferPointer(start: start, count: cp) return Array(ptr) } - /// Returns the buffer + + /// Returns the original ``ByteBuffer`` + /// + /// Returns the current buffer that was just created + /// with the offsets, and data written to it. public var buffer: ByteBuffer { _bb } - /// Returns A sized Buffer from the readable bytes + /// Returns a newly created sized ``ByteBuffer`` + /// + /// returns a new buffer that is sized to the data written + /// to the main buffer public var sizedBuffer: ByteBuffer { assert(finished, "Data shouldn't be called before finish()") return ByteBuffer( @@ -84,20 +107,28 @@ public struct FlatBufferBuilder { // MARK: - Init - /// initialize the buffer with a size + /// Initialize the buffer with a size /// - Parameters: /// - initialSize: Initial size for the buffer /// - force: Allows default to be serialized into the buffer - public init(initialSize: Int32 = 1024, serializeDefaults force: Bool = false) { + /// + /// This initializes a new builder with an initialSize that would initialize + /// a new ``ByteBuffer``. ``FlatBufferBuilder`` by default doesnt serialize defaults + /// however the builder can be force by passing true for `serializeDefaults` + public init( + initialSize: Int32 = 1024, + serializeDefaults force: Bool = false) + { assert(initialSize > 0, "Size should be greater than zero!") guard isLitteEndian else { - fatalError("Reading/Writing a buffer in big endian machine is not supported on swift") + fatalError( + "Reading/Writing a buffer in big endian machine is not supported on swift") } serializeDefaults = force _bb = ByteBuffer(initialSize: Int(initialSize)) } - /// Clears the buffer and the builder from it's data + /// Clears the builder and the buffer from the written data. mutating public func clear() { _minAlignment = 0 isNested = false @@ -113,6 +144,9 @@ public struct FlatBufferBuilder { /// - Parameters: /// - table: offset for the table /// - fields: Array of all the important fields to be serialized + /// + /// *NOTE: Never call this function, this is only supposed to be called + /// by the generated code* mutating public func require(table: Offset, fields: [Int32]) { for field in fields { let start = _bb.capacity &- Int(table.o) @@ -129,6 +163,23 @@ public struct FlatBufferBuilder { /// - offset: Offset of the table /// - fileId: Takes the fileId /// - prefix: if false it wont add the size of the buffer + /// + /// ``finish(offset:fileId:addPrefix:)`` should be called at the end of creating + /// a table + /// ```swift + /// var root = SomeObject + /// .createObject(&builder, + /// name: nameOffset) + /// builder.finish( + /// offset: root, + /// fileId: "ax1a", + /// addPrefix: true) + /// ``` + /// File id would append a file id name at the end of the written bytes before, + /// finishing the buffer. + /// + /// Whereas, if `addPrefix` is true, the written bytes would + /// include the size of the current buffer. mutating public func finish( offset: Offset, fileId: String, @@ -147,6 +198,19 @@ public struct FlatBufferBuilder { /// - Parameters: /// - offset: Offset of the table /// - prefix: if false it wont add the size of the buffer + /// + /// ``finish(offset:addPrefix:)`` should be called at the end of creating + /// a table + /// ```swift + /// var root = SomeObject + /// .createObject(&builder, + /// name: nameOffset) + /// builder.finish( + /// offset: root, + /// addPrefix: true) + /// ``` + /// If `addPrefix` is true, the written bytes would + /// include the size of the current buffer. mutating public func finish( offset: Offset, addPrefix prefix: Bool = false) @@ -160,10 +224,15 @@ public struct FlatBufferBuilder { finished = true } - /// starttable will let the builder know, that a new object is being serialized. + /// ``startTable(with:)`` will let the builder know, that a new object is being serialized. /// - /// The function will fatalerror if called while there is another object being serialized + /// The function will fatalerror if called while there is another object being serialized. + /// ```swift + /// let start = Monster + /// .startMonster(&fbb) + /// ``` /// - Parameter numOfFields: Number of elements to be written to the buffer + /// - Returns: Offset of the newly started table mutating public func startTable(with numOfFields: Int) -> UOffset { notNested() isNested = true @@ -171,11 +240,14 @@ public struct FlatBufferBuilder { return _bb.size } - /// Endtable will let the builder know that the object that's written to it is completed + /// ``endTable(at:)`` will let the ``FlatBufferBuilder`` know that the + /// object that's written to it is completed + /// + /// This would be called after all the elements are serialized, + /// it will add the current vtable into the ``ByteBuffer``. + /// The functions will `fatalError` in case the object is called + /// without ``startTable(with:)``, or the object has exceeded the limit of 2GB. /// - /// This would be called after all the elements are serialized, it will add the vtable into the buffer. - /// it will fatalError in case the object is called without starttable, or the object has exceeded the limit of - /// 2GB, /// - Parameter startOffset:Start point of the object written /// - returns: The root of the table mutating public func endTable(at startOffset: UOffset) -> UOffset { @@ -239,7 +311,7 @@ public struct FlatBufferBuilder { // MARK: - Builds Buffer - /// asserts to see if the object is not nested + /// Asserts to see if the object is not nested @usableFromInline mutating internal func notNested() { assert(!isNested, "Object serialization must not be nested") @@ -259,7 +331,10 @@ public struct FlatBufferBuilder { /// - bufSize: Current size of the buffer + the offset of the object to be written /// - elementSize: Element size @inline(__always) - mutating internal func padding(bufSize: UInt32, elementSize: UInt32) -> UInt32 { + mutating internal func padding( + bufSize: UInt32, + elementSize: UInt32) -> UInt32 + { ((~bufSize) &+ 1) & (elementSize - 1) } @@ -304,7 +379,18 @@ public struct FlatBufferBuilder { // MARK: - Inserting Vectors - /// Starts a vector of length and Element size + /// ``startVector(_:elementSize:)`` creates a new vector within buffer + /// + /// The function checks if there is a current object being written, if + /// the check passes it creates a buffer alignment of `length * elementSize` + /// ```swift + /// builder.startVector( + /// int32Values.count, elementSize: 4) + /// ``` + /// + /// - Parameters: + /// - len: Length of vector to be created + /// - elementSize: Size of object type to be written mutating public func startVector(_ len: Int, elementSize: Int) { notNested() isNested = true @@ -312,46 +398,102 @@ public struct FlatBufferBuilder { preAlign(len: len &* elementSize, alignment: elementSize) } - /// Ends the vector of at length + /// ``endVector(len:)`` ends the currently created vector + /// + /// Calling ``endVector(len:)`` requires the length, of the current + /// vector. The length would be pushed to indicate the count of numbers + /// within the vector. If ``endVector(len:)`` is called without + /// ``startVector(_:elementSize:)`` it asserts. + /// + /// ```swift + /// let vectorOffset = builder. + /// endVector(len: int32Values.count) + /// ``` /// - /// The current function will fatalError if startVector is called before serializing the vector /// - Parameter len: Length of the buffer + /// - Returns: Returns the current ``Offset`` in the ``ByteBuffer`` mutating public func endVector(len: Int) -> Offset { assert(isNested, "Calling endVector without calling startVector") isNested = false return Offset(offset: push(element: Int32(len))) } - /// Creates a vector of type Scalar in the buffer + /// Creates a vector of type ``Scalar`` into the ``ByteBuffer`` + /// + /// ``createVector(_:)-4swl0`` writes a vector of type Scalars into + /// ``ByteBuffer``. This is a convenient method instead of calling, + /// ``startVector(_:elementSize:)`` and then ``endVector(len:)`` + /// ```swift + /// let vectorOffset = builder. + /// createVector([1, 2, 3, 4]) + /// ``` + /// + /// The underlying implementation simply calls ``createVector(_:size:)-4lhrv`` + /// /// - Parameter elements: elements to be written into the buffer - /// - returns: Offset of the vector + /// - returns: ``Offset`` of the vector mutating public func createVector(_ elements: [T]) -> Offset { createVector(elements, size: elements.count) } /// Creates a vector of type Scalar in the buffer + /// + /// ``createVector(_:)-4swl0`` writes a vector of type Scalars into + /// ``ByteBuffer``. This is a convenient method instead of calling, + /// ``startVector(_:elementSize:)`` and then ``endVector(len:)`` + /// ```swift + /// let vectorOffset = builder. + /// createVector([1, 2, 3, 4], size: 4) + /// ``` + /// /// - Parameter elements: Elements to be written into the buffer /// - Parameter size: Count of elements - /// - returns: Offset of the vector - mutating public func createVector(_ elements: [T], size: Int) -> Offset { + /// - returns: ``Offset`` of the vector + mutating public func createVector( + _ elements: [T], + size: Int) -> Offset + { let size = size startVector(size, elementSize: MemoryLayout.size) _bb.push(elements: elements) return endVector(len: size) } - /// Creates a vector of type Enums in the buffer + /// Creates a vector of type ``Enum`` into the ``ByteBuffer`` + /// + /// ``createVector(_:)-9h189`` writes a vector of type ``Enum`` into + /// ``ByteBuffer``. This is a convenient method instead of calling, + /// ``startVector(_:elementSize:)`` and then ``endVector(len:)`` + /// ```swift + /// let vectorOffset = builder. + /// createVector([.swift, .cpp]) + /// ``` + /// + /// The underlying implementation simply calls ``createVector(_:size:)-7cx6z`` + /// /// - Parameter elements: elements to be written into the buffer - /// - returns: Offset of the vector + /// - returns: ``Offset`` of the vector mutating public func createVector(_ elements: [T]) -> Offset { createVector(elements, size: elements.count) } - /// Creates a vector of type Enums in the buffer + /// Creates a vector of type ``Enum`` into the ``ByteBuffer`` + /// + /// ``createVector(_:)-9h189`` writes a vector of type ``Enum`` into + /// ``ByteBuffer``. This is a convenient method instead of calling, + /// ``startVector(_:elementSize:)`` and then ``endVector(len:)`` + /// ```swift + /// let vectorOffset = builder. + /// createVector([.swift, .cpp]) + /// ``` + /// /// - Parameter elements: Elements to be written into the buffer /// - Parameter size: Count of elements - /// - returns: Offset of the vector - mutating public func createVector(_ elements: [T], size: Int) -> Offset { + /// - returns: ``Offset`` of the vector + mutating public func createVector( + _ elements: [T], + size: Int) -> Offset + { let size = size startVector(size, elementSize: T.byteSize) for e in elements.reversed() { @@ -360,18 +502,42 @@ public struct FlatBufferBuilder { return endVector(len: size) } - /// Creates a vector of type Offsets in the buffer - /// - Parameter offsets:Array of offsets of type T - /// - returns: Offset of the vector + /// Creates a vector of already written offsets + /// + /// ``createVector(ofOffsets:)`` creates a vector of ``Offset`` into + /// ``ByteBuffer``. This is a convenient method instead of calling, + /// ``startVector(_:elementSize:)`` and then ``endVector(len:)``. + /// + /// The underlying implementation simply calls ``createVector(ofOffsets:len:)`` + /// + /// ```swift + /// let namesOffsets = builder. + /// createVector(ofOffsets: [name1, name2]) + /// ``` + /// - Parameter offsets: Array of offsets of type ``Offset`` + /// - returns: ``Offset`` of the vector mutating public func createVector(ofOffsets offsets: [Offset]) -> Offset { createVector(ofOffsets: offsets, len: offsets.count) } - /// Creates a vector of type Offsets in the buffer - /// - Parameter elements: Array of offsets of type T + /// Creates a vector of already written offsets + /// + /// ``createVector(ofOffsets:)`` creates a vector of ``Offset`` into + /// ``ByteBuffer``. This is a convenient method instead of calling, + /// ``startVector(_:elementSize:)`` and then ``endVector(len:)`` + /// + /// ```swift + /// let namesOffsets = builder. + /// createVector(ofOffsets: [name1, name2]) + /// ``` + /// + /// - Parameter offsets: Array of offsets of type ``Offset`` /// - Parameter size: Count of elements - /// - returns: Offset of the vector - mutating public func createVector(ofOffsets offsets: [Offset], len: Int) -> Offset { + /// - returns: ``Offset`` of the vector + mutating public func createVector( + ofOffsets offsets: [Offset], + len: Int) -> Offset + { startVector(len, elementSize: MemoryLayout.size) for o in offsets.reversed() { push(element: o) @@ -379,9 +545,21 @@ public struct FlatBufferBuilder { return endVector(len: len) } - /// Creates a vector of Strings - /// - Parameter str: a vector of strings that will be written into the buffer - /// - returns: Offset of the vector + /// Creates a vector of strings + /// + /// ``createVector(ofStrings:)`` creates a vector of `String` into + /// ``ByteBuffer``. This is a convenient method instead of manually + /// creating the string offsets, you simply pass it to this function + /// and it would write the strings into the ``ByteBuffer``. + /// After that it calls ``createVector(ofOffsets:)`` + /// + /// ```swift + /// let namesOffsets = builder. + /// createVector(ofStrings: ["Name", "surname"]) + /// ``` + /// + /// - Parameter str: Array of string + /// - returns: ``Offset`` of the vector mutating public func createVector(ofStrings str: [String]) -> Offset { var offsets: [Offset] = [] for s in str { @@ -390,10 +568,22 @@ public struct FlatBufferBuilder { return createVector(ofOffsets: offsets) } - /// Creates a vector of `Native swift structs` which were padded to flatbuffers standards - /// - Parameter structs: A vector of structs - /// - Returns: offset of the vector - mutating public func createVector(ofStructs structs: [T]) -> Offset { + /// Creates a vector of type ``NativeStruct``. + /// + /// Any swift struct in the generated code, should confirm to + /// ``NativeStruct``. Since the generated swift structs are padded + /// to the `FlatBuffers` standards. + /// + /// ```swift + /// let offsets = builder. + /// createVector(ofStructs: [NativeStr(num: 1), NativeStr(num: 2)]) + /// ``` + /// + /// - Parameter structs: A vector of ``NativeStruct`` + /// - Returns: ``Offset`` of the vector + mutating public func createVector(ofStructs structs: [T]) + -> Offset + { startVector( structs.count * MemoryLayout.size, elementSize: MemoryLayout.alignment) @@ -405,11 +595,21 @@ public struct FlatBufferBuilder { // MARK: - Inserting Structs - /// Fills the buffer with a native struct that's build and padded according to flatbuffers standards + /// Writes a ``NativeStruct`` into the ``ByteBuffer`` + /// + /// Adds a native struct that's build and padded according + /// to `FlatBuffers` standards. with a predefined position. + /// + /// ```swift + /// let offset = builder.create( + /// struct: NativeStr(num: 1), + /// position: 10) + /// ``` + /// /// - Parameters: - /// - s: `Native swift` struct to insert + /// - s: ``NativeStruct`` to be inserted into the ``ByteBuffer`` /// - position: The predefined position of the object - /// - Returns: offset of written struct + /// - Returns: ``Offset`` of written struct @discardableResult mutating public func create( struct s: T, position: VOffset) -> Offset @@ -421,10 +621,20 @@ public struct FlatBufferBuilder { return offset } - /// Fills the buffer with a native struct that's build and padded according to flatbuffers standards + /// Writes a ``NativeStruct`` into the ``ByteBuffer`` + /// + /// Adds a native struct that's build and padded according + /// to `FlatBuffers` standards, directly into the buffer without + /// a predefined position. + /// + /// ```swift + /// let offset = builder.create( + /// struct: NativeStr(num: 1)) + /// ``` + /// /// - Parameters: - /// - s: `Native swift` struct to insert - /// - Returns: offset of written struct + /// - s: ``NativeStruct`` to be inserted into the ``ByteBuffer`` + /// - Returns: ``Offset`` of written struct @discardableResult mutating public func create( struct s: T) -> Offset @@ -437,9 +647,18 @@ public struct FlatBufferBuilder { // MARK: - Inserting Strings - /// Insets a string into the buffer using UTF8 + /// Insets a string into the buffer of type `UTF8` + /// + /// Adds a swift string into ``ByteBuffer`` by encoding it + /// using `UTF8` + /// + /// ```swift + /// let nameOffset = builder + /// .create(string: "welcome") + /// ``` + /// /// - Parameter str: String to be serialized - /// - returns: The strings offset in the buffer + /// - returns: ``Offset`` of inserted string mutating public func create(string str: String?) -> Offset { guard let str = str else { return Offset() } let len = str.utf8.count @@ -451,11 +670,25 @@ public struct FlatBufferBuilder { return Offset(offset: _bb.size) } - /// Inserts a shared string to the buffer + /// Insets a shared string into the buffer of type `UTF8` + /// + /// Adds a swift string into ``ByteBuffer`` by encoding it + /// using `UTF8`. The function will check if the string, + /// is already written to the ``ByteBuffer`` + /// + /// ```swift + /// let nameOffset = builder + /// .createShared(string: "welcome") + /// + /// + /// let secondOffset = builder + /// .createShared(string: "welcome") + /// + /// assert(nameOffset.o == secondOffset.o) + /// ``` /// - /// The function checks the stringOffsetmap if it's seen a similar string before /// - Parameter str: String to be serialized - /// - returns: The strings offset in the buffer + /// - returns: ``Offset`` of inserted string mutating public func createShared(string str: String?) -> Offset { guard let str = str else { return Offset() } if let offset = stringOffsetMap[str] { @@ -468,18 +701,22 @@ public struct FlatBufferBuilder { // MARK: - Inseting offsets - /// Adds the offset of an object into the buffer + /// Writes the ``Offset`` of an already written table + /// + /// Writes the ``Offset`` of a table if not empty into the + /// ``ByteBuffer`` + /// /// - Parameters: - /// - offset: Offset of another object to be written - /// - position: The predefined position of the object + /// - offset: ``Offset`` of another object to be written + /// - position: The predefined position of the object mutating public func add(offset: Offset, at position: VOffset) { if offset.isEmpty { return } add(element: refer(to: offset.o), def: 0, at: position) } - /// Pushes a value of type offset into the buffer - /// - Parameter o: Offset - /// - returns: Position of the offset + /// Pushes a value of type ``Offset`` into the ``ByteBuffer`` + /// - Parameter o: ``Offset`` + /// - returns: Current position of the ``Offset`` @discardableResult mutating public func push(element o: Offset) -> UOffset { push(element: refer(to: o.o)) @@ -487,18 +724,42 @@ public struct FlatBufferBuilder { // MARK: - Inserting Scalars to Buffer - /// Adds a value into the buffer of type Scalar + /// Writes a ``Scalar`` value into ``ByteBuffer`` + /// + /// ``add(element:def:at:)`` takes in a default value, and current value + /// and the position within the `VTable`. The default value would not + /// be serialized if the value is the same as the current value or + /// `serializeDefaults` is equal to false. + /// + /// If serializing defaults is important ``init(initialSize:serializeDefaults:)``, + /// passing true for `serializeDefaults` would do the job. + /// + /// ```swift + /// // Adds 10 to the buffer + /// builder.add(element: Int(10), def: 1, position 12) + /// ``` + /// + /// *NOTE: Never call this manually* /// /// - Parameters: /// - element: Element to insert /// - def: Default value for that element /// - position: The predefined position of the element - mutating public func add(element: T, def: T, at position: VOffset) { + mutating public func add( + element: T, + def: T, + at position: VOffset) + { if element == def && !serializeDefaults { return } track(offset: push(element: element), at: position) } - /// Adds a value into the buffer of type optional Scalar + /// Writes a optional ``Scalar`` value into ``ByteBuffer`` + /// + /// Takes an optional value to be written into the ``ByteBuffer`` + /// + /// *NOTE: Never call this manually* + /// /// - Parameters: /// - element: Optional element of type scalar /// - position: The predefined position of the element @@ -507,7 +768,10 @@ public struct FlatBufferBuilder { track(offset: push(element: element), at: position) } - /// Pushes the values into the buffer + /// Pushes a values of type ``Scalar`` into the ``ByteBuffer`` + /// + /// *NOTE: Never call this manually* + /// /// - Parameter element: Element to insert /// - returns: Postion of the Element @discardableResult @@ -556,7 +820,9 @@ extension FlatBufferBuilder: CustomDebugStringConvertible { /// Creates the memory to store the buffer in @usableFromInline init() { - memory = UnsafeMutableRawBufferPointer.allocate(byteCount: 0, alignment: 0) + memory = UnsafeMutableRawBufferPointer.allocate( + byteCount: 0, + alignment: 0) } deinit { diff --git a/swift/Sources/FlatBuffers/FlatBufferObject.swift b/swift/Sources/FlatBuffers/FlatBufferObject.swift index cea3911eb..df8ad8dbc 100644 --- a/swift/Sources/FlatBuffers/FlatBufferObject.swift +++ b/swift/Sources/FlatBuffers/FlatBufferObject.swift @@ -23,6 +23,8 @@ public protocol NativeStruct {} /// FlatbuffersInitializable is a protocol that allows any object to be /// Initialized from a ByteBuffer public protocol FlatbuffersInitializable { + /// Any flatbuffers object that confirms to this protocol is going to be + /// initializable through this initializer init(_ bb: ByteBuffer, o: Int32) } @@ -31,26 +33,32 @@ public protocol FlatBufferObject: FlatbuffersInitializable { var __buffer: ByteBuffer! { get } } -/// `ObjectAPIPacker` is a protocol that allows object to pack and unpack from a -/// `NativeObject` to a flatbuffers Object and vice versa. +/// ``ObjectAPIPacker`` is a protocol that allows object to pack and unpack from a +/// ``NativeObject`` to a flatbuffers Object and vice versa. public protocol ObjectAPIPacker { /// associatedtype to the object that should be unpacked. associatedtype T - /// `pack` tries packs the variables of a native Object into the `ByteBuffer` by using - /// the FlatBufferBuilder + /// ``pack(_:obj:)-3ptws`` tries to pacs the variables of a native Object into the `ByteBuffer` by using + /// a FlatBufferBuilder /// - Parameters: /// - builder: FlatBufferBuilder that will host incoming data /// - obj: Object of associatedtype to the current implementer + /// + /// ``pack(_:obj:)-3ptws`` can be called by passing through an already initialized ``FlatBufferBuilder`` + /// or it can be called by using the public API that will create a new ``FlatBufferBuilder`` static func pack(_ builder: inout FlatBufferBuilder, obj: inout T?) -> Offset - /// `pack` packs the variables of a native Object into the `ByteBuffer` by using + /// ``pack(_:obj:)-20ipk`` packs the variables of a native Object into the `ByteBuffer` by using /// the FlatBufferBuilder /// - Parameters: /// - builder: FlatBufferBuilder that will host incoming data /// - obj: Object of associatedtype to the current implementer + /// + /// ``pack(_:obj:)-20ipk`` can be called by passing through an already initialized ``FlatBufferBuilder`` + /// or it can be called by using the public API that will create a new ``FlatBufferBuilder`` static func pack(_ builder: inout FlatBufferBuilder, obj: inout T) -> Offset - /// `Unpack` unpacks a flatbuffers object into a `NativeObject` + /// ``unpack()`` unpacks a ``FlatBuffers`` object into a Native swift object. mutating func unpack() -> T } diff --git a/swift/Sources/FlatBuffers/FlatBuffersUtils.swift b/swift/Sources/FlatBuffers/FlatBuffersUtils.swift index 2ab68fd26..dc5f78595 100644 --- a/swift/Sources/FlatBuffers/FlatBuffersUtils.swift +++ b/swift/Sources/FlatBuffers/FlatBuffersUtils.swift @@ -29,6 +29,8 @@ public enum FlatBuffersUtils { /// creates a new buffer use `readPrefixedSizeCheckedRoot` instead /// unless a completely new buffer is required /// - Parameter bb: Flatbuffer object + /// + /// public static func removeSizePrefix(bb: ByteBuffer) -> ByteBuffer { bb.duplicate(removing: MemoryLayout.size) } diff --git a/swift/Sources/FlatBuffers/FlatbuffersErrors.swift b/swift/Sources/FlatBuffers/FlatbuffersErrors.swift index 97188e9e8..74c06b9ae 100644 --- a/swift/Sources/FlatBuffers/FlatbuffersErrors.swift +++ b/swift/Sources/FlatBuffers/FlatbuffersErrors.swift @@ -53,7 +53,10 @@ public enum FlatbuffersErrors: Error, Equatable { fieldName: String) case apparentSizeTooLarge - public static func == (lhs: FlatbuffersErrors, rhs: FlatbuffersErrors) -> Bool { + public static func == ( + lhs: FlatbuffersErrors, + rhs: FlatbuffersErrors) -> Bool + { lhs.localizedDescription == rhs.localizedDescription } } diff --git a/swift/Sources/FlatBuffers/Message.swift b/swift/Sources/FlatBuffers/Message.swift index 76b7a622b..eb0bad972 100644 --- a/swift/Sources/FlatBuffers/Message.swift +++ b/swift/Sources/FlatBuffers/Message.swift @@ -38,10 +38,12 @@ public struct Message: FlatBufferGRPCMessage { public var object: T { T.init( buffer, - o: Int32(buffer.read(def: UOffset.self, position: buffer.reader)) + Int32(buffer.reader)) + o: Int32(buffer.read(def: UOffset.self, position: buffer.reader)) + + Int32(buffer.reader)) } - public var rawPointer: UnsafeMutableRawPointer { buffer.memory.advanced(by: buffer.reader) } + public var rawPointer: UnsafeMutableRawPointer { + buffer.memory.advanced(by: buffer.reader) } public var size: Int { Int(buffer.size) } diff --git a/swift/Sources/FlatBuffers/Mutable.swift b/swift/Sources/FlatBuffers/Mutable.swift index 60f0f1223..f77945cf0 100644 --- a/swift/Sources/FlatBuffers/Mutable.swift +++ b/swift/Sources/FlatBuffers/Mutable.swift @@ -16,17 +16,17 @@ import Foundation -/// Mutable is a protocol that allows us to mutate Scalar values within the buffer +/// Mutable is a protocol that allows us to mutate Scalar values within a ``ByteBuffer`` public protocol Mutable { /// makes Flatbuffer accessed within the Protocol var bb: ByteBuffer { get } - /// makes position of the table/struct accessed within the Protocol + /// makes position of the ``Table``/``struct`` accessed within the Protocol var postion: Int32 { get } } extension Mutable { - /// Mutates the memory in the buffer, this is only called from the access function of table and structs + /// Mutates the memory in the buffer, this is only called from the access function of ``Table`` and ``struct`` /// - Parameters: /// - value: New value to be inserted to the buffer /// - index: index of the Element @@ -39,7 +39,7 @@ extension Mutable { extension Mutable where Self == Table { - /// Mutates a value by calling mutate with respect to the position in the table + /// Mutates a value by calling mutate with respect to the position in a ``Table`` /// - Parameters: /// - value: New value to be inserted to the buffer /// - index: index of the Element diff --git a/swift/Sources/FlatBuffers/NativeObject.swift b/swift/Sources/FlatBuffers/NativeObject.swift index 724c2ebaf..bc896e637 100644 --- a/swift/Sources/FlatBuffers/NativeObject.swift +++ b/swift/Sources/FlatBuffers/NativeObject.swift @@ -26,7 +26,9 @@ extension NativeObject { /// Serialize is a helper function that serailizes the data from the Object API to a bytebuffer directly th /// - Parameter type: Type of the Flatbuffer object /// - Returns: returns the encoded sized ByteBuffer - public func serialize(type: T.Type) -> ByteBuffer where T.T == Self { + public func serialize(type: T.Type) -> ByteBuffer + where T.T == Self + { var builder = FlatBufferBuilder(initialSize: 1024) return serialize(builder: &builder, type: type.self) } diff --git a/swift/Sources/FlatBuffers/Root.swift b/swift/Sources/FlatBuffers/Root.swift index 8891cafb3..4d883b7b8 100644 --- a/swift/Sources/FlatBuffers/Root.swift +++ b/swift/Sources/FlatBuffers/Root.swift @@ -23,6 +23,9 @@ import Foundation /// - options: Verifier options /// - Throws: FlatbuffersErrors /// - Returns: Returns a valid, checked Flatbuffers object +/// +/// ``getPrefixedSizeCheckedRoot(byteBuffer:options:)`` would skip the first Bytes in +/// the ``ByteBuffer`` and verifies the buffer by calling ``getCheckedRoot(byteBuffer:options:)`` public func getPrefixedSizeCheckedRoot( byteBuffer: inout ByteBuffer, options: VerifierOptions = .init()) throws -> T @@ -35,7 +38,12 @@ public func getPrefixedSizeCheckedRoot( /// Returns a `NON-Checked` flatbuffers object /// - Parameter byteBuffer: Buffer that contains data /// - Returns: Returns a Flatbuffers object -public func getPrefixedSizeRoot(byteBuffer: inout ByteBuffer) -> T { +/// +/// ``getPrefixedSizeCheckedRoot(byteBuffer:options:)`` would skip the first Bytes in +/// the ``ByteBuffer`` and then calls ``getRoot(byteBuffer:)`` +public func getPrefixedSizeRoot(byteBuffer: inout ByteBuffer) + -> T +{ byteBuffer.skipPrefix() return getRoot(byteBuffer: &byteBuffer) @@ -47,6 +55,10 @@ public func getPrefixedSizeRoot(byteBuffer: inout ByteBuffe /// - options: Verifier options /// - Throws: FlatbuffersErrors /// - Returns: Returns a valid, checked Flatbuffers object +/// +/// ``getCheckedRoot(byteBuffer:options:)`` Takes in a ``ByteBuffer`` and verifies +/// that by creating a ``Verifier`` and checkes if all the `Bytes` and correctly aligned +/// and within the ``ByteBuffer`` range. public func getCheckedRoot( byteBuffer: inout ByteBuffer, options: VerifierOptions = .init()) throws -> T @@ -55,7 +67,8 @@ public func getCheckedRoot( try ForwardOffset.verify(&verifier, at: 0, of: T.self) return T.init( byteBuffer, - o: Int32(byteBuffer.read(def: UOffset.self, position: byteBuffer.reader)) + Int32(byteBuffer.reader)) + o: Int32(byteBuffer.read(def: UOffset.self, position: byteBuffer.reader)) + + Int32(byteBuffer.reader)) } /// Returns a `NON-Checked` flatbuffers object @@ -64,5 +77,6 @@ public func getCheckedRoot( public func getRoot(byteBuffer: inout ByteBuffer) -> T { T.init( byteBuffer, - o: Int32(byteBuffer.read(def: UOffset.self, position: byteBuffer.reader)) + Int32(byteBuffer.reader)) + o: Int32(byteBuffer.read(def: UOffset.self, position: byteBuffer.reader)) + + Int32(byteBuffer.reader)) } diff --git a/swift/Sources/FlatBuffers/String+extension.swift b/swift/Sources/FlatBuffers/String+extension.swift index 5a16a81b6..2f3168d22 100644 --- a/swift/Sources/FlatBuffers/String+extension.swift +++ b/swift/Sources/FlatBuffers/String+extension.swift @@ -47,7 +47,9 @@ extension String: Verifiable { if !verifier._options._ignoreMissingNullTerminators && !isNullTerminated { let str = verifier._buffer.readString(at: range.start, count: range.count) - throw FlatbuffersErrors.missingNullTerminator(position: position, str: str) + throw FlatbuffersErrors.missingNullTerminator( + position: position, + str: str) } } } @@ -69,12 +71,18 @@ extension String: FlatbuffersInitializable { extension String: ObjectAPIPacker { - public static func pack(_ builder: inout FlatBufferBuilder, obj: inout String?) -> Offset { + public static func pack( + _ builder: inout FlatBufferBuilder, + obj: inout String?) -> Offset + { guard var obj = obj else { return Offset() } return pack(&builder, obj: &obj) } - public static func pack(_ builder: inout FlatBufferBuilder, obj: inout String) -> Offset { + public static func pack( + _ builder: inout FlatBufferBuilder, + obj: inout String) -> Offset + { builder.create(string: obj) } @@ -86,7 +94,9 @@ extension String: ObjectAPIPacker { extension String: NativeObject { - public func serialize(type: T.Type) -> ByteBuffer where T.T == Self { + public func serialize(type: T.Type) -> ByteBuffer + where T.T == Self + { fatalError("serialize should never be called from string directly") } diff --git a/swift/Sources/FlatBuffers/Table.swift b/swift/Sources/FlatBuffers/Table.swift index 34efedd5f..ff501fc9b 100644 --- a/swift/Sources/FlatBuffers/Table.swift +++ b/swift/Sources/FlatBuffers/Table.swift @@ -34,7 +34,8 @@ public struct Table { /// - Note: This will `CRASH` if read on a big endian machine public init(bb: ByteBuffer, position: Int32 = 0) { guard isLitteEndian else { - fatalError("Reading/Writing a buffer in big endian machine is not supported on swift") + fatalError( + "Reading/Writing a buffer in big endian machine is not supported on swift") } self.bb = bb postion = position @@ -46,9 +47,10 @@ public struct Table { /// - Returns: offset of field within buffer public func offset(_ o: Int32) -> Int32 { let vtable = postion - bb.read(def: Int32.self, position: Int(postion)) - return o < bb.read(def: VOffset.self, position: Int(vtable)) ? Int32(bb.read( - def: Int16.self, - position: Int(vtable + o))) : 0 + return o < bb + .read(def: VOffset.self, position: Int(vtable)) ? Int32(bb.read( + def: Int16.self, + position: Int(vtable + o))) : 0 } /// Gets the indirect offset of the current stored object @@ -163,7 +165,11 @@ public struct Table { /// - vOffset: Field offset within a vtable /// - fbb: ByteBuffer /// - Returns: an position of a field - static public func offset(_ o: Int32, vOffset: Int32, fbb: ByteBuffer) -> Int32 { + static public func offset( + _ o: Int32, + vOffset: Int32, + fbb: ByteBuffer) -> Int32 + { let vTable = Int32(fbb.capacity) - o return vTable + Int32(fbb.read( def: Int16.self, @@ -178,7 +184,11 @@ public struct Table { /// - off2: second offset to compare /// - fbb: Bytebuffer /// - Returns: returns the difference between - static public func compare(_ off1: Int32, _ off2: Int32, fbb: ByteBuffer) -> Int32 { + static public func compare( + _ off1: Int32, + _ off2: Int32, + fbb: ByteBuffer) -> Int32 + { let memorySize = Int32(MemoryLayout.size) let _off1 = off1 + fbb.read(def: Int32.self, position: Int(off1)) let _off2 = off2 + fbb.read(def: Int32.self, position: Int(off2)) @@ -203,7 +213,11 @@ public struct Table { /// - key: bytes array to compare to /// - fbb: Bytebuffer /// - Returns: returns the difference between - static public func compare(_ off1: Int32, _ key: [Byte], fbb: ByteBuffer) -> Int32 { + static public func compare( + _ off1: Int32, + _ key: [Byte], + fbb: ByteBuffer) -> Int32 + { let memorySize = Int32(MemoryLayout.size) let _off1 = off1 + fbb.read(def: Int32.self, position: Int(off1)) let len1 = fbb.read(def: Int32.self, position: Int(_off1)) diff --git a/swift/Sources/FlatBuffers/TableVerifier.swift b/swift/Sources/FlatBuffers/TableVerifier.swift index 6749b6f06..42a37f288 100644 --- a/swift/Sources/FlatBuffers/TableVerifier.swift +++ b/swift/Sources/FlatBuffers/TableVerifier.swift @@ -64,8 +64,7 @@ public struct TableVerifier { /// Reading the offset for the field needs to be read. let offset: VOffset = try _verifier.getValue( - at: Int(clamping: _vtable &+ Int(field)) - ) + at: Int(clamping: _vtable &+ Int(field))) if offset > 0 { return Int(clamping: _position &+ Int(offset)) @@ -116,7 +115,8 @@ public struct TableVerifier { unionKeyName: String, fieldName: String, required: Bool, - completion: @escaping (inout Verifier, T, Int) throws -> Void) throws where T: UnionEnum + completion: @escaping (inout Verifier, T, Int) throws -> Void) throws + where T: UnionEnum { let keyPos = try dereference(key) let valPos = try dereference(field) @@ -170,7 +170,8 @@ public struct TableVerifier { unionKeyName: String, fieldName: String, required: Bool, - completion: @escaping (inout Verifier, T, Int) throws -> Void) throws where T: UnionEnum + completion: @escaping (inout Verifier, T, Int) throws -> Void) throws + where T: UnionEnum { let keyVectorPosition = try dereference(key) let offsetVectorPosition = try dereference(field) diff --git a/swift/Sources/FlatBuffers/Verifier.swift b/swift/Sources/FlatBuffers/Verifier.swift index e465b140d..6f65ce702 100644 --- a/swift/Sources/FlatBuffers/Verifier.swift +++ b/swift/Sources/FlatBuffers/Verifier.swift @@ -176,14 +176,18 @@ public struct Verifier { let reportedOverflow: (partialValue: UInt32, overflow: Bool) if offset > 0 { - reportedOverflow = _int32Position.subtractingReportingOverflow(offset.magnitude) + reportedOverflow = _int32Position + .subtractingReportingOverflow(offset.magnitude) } else { - reportedOverflow = _int32Position.addingReportingOverflow(offset.magnitude) + reportedOverflow = _int32Position + .addingReportingOverflow(offset.magnitude) } /// since `subtractingReportingOverflow` & `addingReportingOverflow` returns true, /// if there is overflow we return failure - if reportedOverflow.overflow || reportedOverflow.partialValue > _buffer.capacity { + if reportedOverflow.overflow || reportedOverflow.partialValue > _buffer + .capacity + { throw FlatbuffersErrors.signedOffsetOutOfBounds( offset: Int(offset), position: position) diff --git a/tests/FlatBuffers.Benchmarks.swift/Sources/FlatBuffers.Benchmarks.swift/main.swift b/tests/FlatBuffers.Benchmarks.swift/Sources/FlatBuffers.Benchmarks.swift/main.swift index da9a3d9b7..49490042e 100644 --- a/tests/FlatBuffers.Benchmarks.swift/Sources/FlatBuffers.Benchmarks.swift/main.swift +++ b/tests/FlatBuffers.Benchmarks.swift/Sources/FlatBuffers.Benchmarks.swift/main.swift @@ -21,7 +21,8 @@ struct Benchmark { var name: String var value: Double - var description: String { "\(String(format: "|\t%@\t\t|\t\t%fs\t|", name, value))"} + var description: String { + "\(String(format: "|\t%@\t\t|\t\t%fs\t|", name, value))"} } func run(name: String, runs: Int, action: () -> Void) -> Benchmark { diff --git a/tests/FlatBuffers.Test.Swift/Package.swift b/tests/FlatBuffers.Test.Swift/Package.swift index 12618cbe3..e2a53df90 100644 --- a/tests/FlatBuffers.Test.Swift/Package.swift +++ b/tests/FlatBuffers.Test.Swift/Package.swift @@ -25,7 +25,7 @@ let package = Package( ], dependencies: [ .package(path: "../../swift/"), - .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0"), + .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.4.1"), ], targets: [ .target( diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersMonsterWriterTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersMonsterWriterTests.swift index 21c3daf42..4b83e7471 100644 --- a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersMonsterWriterTests.swift +++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersMonsterWriterTests.swift @@ -35,7 +35,8 @@ class FlatBuffersMonsterWriterTests: XCTestCase { func testReadFromOtherLanguages() { let path = FileManager.default.currentDirectoryPath - let url = URL(fileURLWithPath: path, isDirectory: true).appendingPathComponent("monsterdata_test").appendingPathExtension("mon") + let url = URL(fileURLWithPath: path, isDirectory: true) + .appendingPathComponent("monsterdata_test").appendingPathExtension("mon") guard let data = try? Data(contentsOf: url) else { return } let _data = ByteBuffer(data: data) readVerifiedMonster(fb: _data) @@ -108,15 +109,16 @@ class FlatBuffersMonsterWriterTests: XCTestCase { // swiftformat:disable all var array: [UInt8] = [48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 68, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 120, 0, 0, 0, 0, 0, 80, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 64, 2, 0, 5, 0, 6, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 30, 0, 40, 0, 10, 0, 20, 0, 152, 255, 255, 255, 4, 0, 0, 0, 4, 0, 0, 0, 70, 114, 101, 100, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 50, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 49, 0, 0, 0, 9, 0, 0, 0, 77, 121, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 4, 0, 0, 0, 240, 255, 255, 255, 32, 0, 0, 0, 248, 255, 255, 255, 36, 0, 0, 0, 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 12, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 87, 105, 108, 109, 97, 0, 0, 0, 6, 0, 0, 0, 66, 97, 114, 110, 101, 121, 0, 0, 5, 0, 0, 0, 70, 114, 111, 100, 111, 0, 0, 0] // swiftformat:enable all - let unpacked = array.withUnsafeMutableBytes { (memory) -> MyGame_Example_MonsterT in - let bytes = ByteBuffer( - assumingMemoryBound: memory.baseAddress!, - capacity: memory.count) - var monster = Monster.getRootAsMonster(bb: bytes) - readFlatbufferMonster(monster: &monster) - let unpacked = monster.unpack() - return unpacked - } + let unpacked = array + .withUnsafeMutableBytes { (memory) -> MyGame_Example_MonsterT in + let bytes = ByteBuffer( + assumingMemoryBound: memory.baseAddress!, + capacity: memory.count) + var monster = Monster.getRootAsMonster(bb: bytes) + readFlatbufferMonster(monster: &monster) + let unpacked = monster.unpack() + return unpacked + } readObjectApi(monster: unpacked) } @@ -143,7 +145,10 @@ class FlatBuffersMonsterWriterTests: XCTestCase { func readVerifiedMonster(fb: ByteBuffer) { var byteBuffer = fb - XCTAssertNoThrow(try readMonster(monster: getCheckedRoot(byteBuffer: &byteBuffer) as MyGame_Example_Monster)) + XCTAssertNoThrow( + try readMonster( + monster: getCheckedRoot( + byteBuffer: &byteBuffer) as MyGame_Example_Monster)) } func readMonster(monster: Monster) { @@ -151,7 +156,8 @@ class FlatBuffersMonsterWriterTests: XCTestCase { readFlatbufferMonster(monster: &monster) let unpacked: MyGame_Example_MonsterT? = monster.unpack() readObjectApi(monster: unpacked!) - guard let buffer = unpacked?.serialize() else { fatalError("Couldnt generate bytebuffer") } + guard let buffer = unpacked?.serialize() + else { fatalError("Couldnt generate bytebuffer") } var newMonster = Monster.getRootAsMonster(bb: buffer) readFlatbufferMonster(monster: &newMonster) } diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersStructsTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersStructsTests.swift index 9b80bf3cc..203258978 100644 --- a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersStructsTests.swift +++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersStructsTests.swift @@ -26,7 +26,8 @@ final class FlatBuffersStructsTests: XCTestCase { let root = TestMutatingBool.endTestMutatingBool(&fbb, start: start) fbb.finish(offset: root) - let testMutatingBool = TestMutatingBool.getRootAsTestMutatingBool(bb: fbb.sizedBuffer) + let testMutatingBool = TestMutatingBool + .getRootAsTestMutatingBool(bb: fbb.sizedBuffer) let property = testMutatingBool.mutableB XCTAssertEqual(property?.property, false) property?.mutate(property: false) diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersTests.swift index 96cd1f737..379e73318 100644 --- a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersTests.swift +++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersTests.swift @@ -108,7 +108,8 @@ final class FlatBuffersTests: XCTestCase { justEnum: .one, maybeEnum: nil) b.finish(offset: root) - let scalarTable = optional_scalars_ScalarStuff.getRootAsScalarStuff(bb: b.sizedBuffer) + let scalarTable = optional_scalars_ScalarStuff + .getRootAsScalarStuff(bb: b.sizedBuffer) XCTAssertEqual(scalarTable.justI8, 80) XCTAssertNil(scalarTable.maybeI8) XCTAssertEqual(scalarTable.maybeBool, true) @@ -136,7 +137,8 @@ class Country { of: Int32.self, at: o) } var nameVector: [UInt8]? { __t.getVector(at: 4) } - var name: String? { let o = __t.offset(4); return o == 0 ? nil : __t.string(at: o) } + var name: String? { + let o = __t.offset(4); return o == 0 ? nil : __t.string(at: o) } @inlinable static func getRootAsCountry(_ bb: ByteBuffer) -> Country { @@ -174,7 +176,10 @@ class Country { } @inlinable - static func end(builder: inout FlatBufferBuilder, startOffset: UOffset) -> Offset { + static func end( + builder: inout FlatBufferBuilder, + startOffset: UOffset) -> Offset + { Offset(offset: builder.endTable(at: startOffset)) } diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersUnionTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersUnionTests.swift index 5b59b4ed9..3b6f194a6 100644 --- a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersUnionTests.swift +++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersUnionTests.swift @@ -51,7 +51,10 @@ final class FlatBuffersUnionTests: XCTestCase { var builder = FlatBufferBuilder(initialSize: 20) let sword = builder.create(string: "Sword") let axe = builder.create(string: "Axe") - let weaponOne = Weapon.createWeapon(builder: &builder, offset: sword, dmg: 3) + let weaponOne = Weapon.createWeapon( + builder: &builder, + offset: sword, + dmg: 3) let weaponTwo = Weapon.createWeapon(builder: &builder, offset: axe, dmg: 5) let name = builder.create(string: "Orc") let inventory: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] @@ -138,7 +141,9 @@ final class FlatBuffersUnionTests: XCTestCase { 2) var objc: MovieT? = movie.unpack() - XCTAssertEqual(movie.charactersTypeCount, Int32(objc?.characters.count ?? 0)) + XCTAssertEqual( + movie.charactersTypeCount, + Int32(objc?.characters.count ?? 0)) XCTAssertEqual( movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead, (objc?.characters[0]?.value as? BookReader)?.booksRead) @@ -219,20 +224,32 @@ public enum ColorsNameSpace { private var _accessor: Table static func getRootAsMonster(bb: ByteBuffer) -> Monster { Monster(Table( bb: bb, - position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) } + position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + + Int32(bb.reader))) } init(_ t: Table) { _accessor = t } init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) } - public var colorsCount: Int32 { let o = _accessor.offset(4); return o == 0 ? 0 : _accessor.vector(count: o) } - public func colors(at index: Int32) -> ColorsNameSpace.RGB? { let o = _accessor.offset(4); return o == 0 ? ColorsNameSpace.RGB(rawValue: 0)! : ColorsNameSpace.RGB(rawValue: _accessor.directRead( - of: Int32.self, - offset: _accessor.vector(at: o) + index * 4)) } - static func startMonster(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) } + public var colorsCount: Int32 { + let o = _accessor.offset(4); return o == 0 ? 0 : _accessor + .vector(count: o) } + public func colors(at index: Int32) -> ColorsNameSpace + .RGB? + { let o = _accessor.offset(4); return o == 0 ? ColorsNameSpace + .RGB(rawValue: 0)! : ColorsNameSpace.RGB(rawValue: _accessor.directRead( + of: Int32.self, + offset: _accessor.vector(at: o) + index * 4)) } + static func startMonster(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb + .startTable(with: 1) } static func add(colors: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add( offset: colors, at: 4) } - static func endMonster(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end } + static func endMonster( + _ fbb: inout FlatBufferBuilder, + start: UOffset) + -> Offset + { let end = Offset(offset: fbb.endTable(at: start)); return end + } } } @@ -280,9 +297,10 @@ struct LocalMonster { init(_ fb: ByteBuffer, o: Int32) { __t = Table(bb: fb, position: o) } init(_ t: Table) { __t = t } - func weapon(at index: Int32) -> Weapon? { let o = __t.offset(4); return o == 0 ? nil : Weapon.assign( - __t.indirect(__t.vector(at: o) + (index * 4)), - __t.bb) } + func weapon(at index: Int32) -> Weapon? { let o = __t + .offset(4); return o == 0 ? nil : Weapon.assign( + __t.indirect(__t.vector(at: o) + (index * 4)), + __t.bb) } func equiped() -> T? { let o = __t.offset(8); return o == 0 ? nil : __t.union(o) @@ -304,7 +322,10 @@ struct LocalMonster { let start = builder.startTable(with: 3) builder.add(element: equippedOffset, def: 0, at: 8) builder.add(offset: offset, at: 4) - builder.add(element: equipment.rawValue, def: Equipment.none.rawValue, at: 6) + builder.add( + element: equipment.rawValue, + def: Equipment.none.rawValue, + at: 6) return Offset(offset: builder.endTable(at: start)) } } @@ -323,7 +344,8 @@ struct Weapon: FlatBufferObject { of: Int16.self, at: o) } var nameVector: [UInt8]? { __t.getVector(at: 4) } - var name: String? { let o = __t.offset(4); return o == 0 ? nil : __t.string(at: o) } + var name: String? { + let o = __t.offset(4); return o == 0 ? nil : __t.string(at: o) } static func assign(_ i: Int32, _ bb: ByteBuffer) -> Weapon { Weapon(Table( bb: bb, @@ -342,7 +364,10 @@ struct Weapon: FlatBufferObject { } @inlinable - static func end(builder: inout FlatBufferBuilder, startOffset: UOffset) -> Offset { + static func end( + builder: inout FlatBufferBuilder, + startOffset: UOffset) -> Offset + { Offset(offset: builder.endTable(at: startOffset)) } diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersVectorsTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersVectorsTests.swift index ccccf7519..4cb245f2f 100644 --- a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersVectorsTests.swift +++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersVectorsTests.swift @@ -25,8 +25,16 @@ final class FlatBuffersVectors: XCTestCase { var b = FlatBufferBuilder(initialSize: 20) let noStr = b.create(string: norway) let deStr = b.create(string: denmark) - let n = Country.createCountry(builder: &b, offset: noStr, log: 888, lan: 700) - let d = Country.createCountry(builder: &b, offset: deStr, log: 200, lan: 100) + let n = Country.createCountry( + builder: &b, + offset: noStr, + log: 888, + lan: 700) + let d = Country.createCountry( + builder: &b, + offset: deStr, + log: 200, + lan: 100) let vector = [n, d] let vectorOffset = b.createVector(ofOffsets: vector) b.finish(offset: vectorOffset) @@ -119,19 +127,31 @@ struct Numbers { var vArrayDouble: [Double]? { __t.getVector(at: 4) } var vArrayFloat: [Float32]? { __t.getVector(at: 4) } - static func createNumbersVector(b: inout FlatBufferBuilder, array: [Int]) -> Offset { + static func createNumbersVector( + b: inout FlatBufferBuilder, + array: [Int]) -> Offset + { b.createVector(array, size: array.count) } - static func createNumbersVector(b: inout FlatBufferBuilder, array: [Int32]) -> Offset { + static func createNumbersVector( + b: inout FlatBufferBuilder, + array: [Int32]) -> Offset + { b.createVector(array, size: array.count) } - static func createNumbersVector(b: inout FlatBufferBuilder, array: [Double]) -> Offset { + static func createNumbersVector( + b: inout FlatBufferBuilder, + array: [Double]) -> Offset + { b.createVector(array, size: array.count) } - static func createNumbersVector(b: inout FlatBufferBuilder, array: [Float32]) -> Offset { + static func createNumbersVector( + b: inout FlatBufferBuilder, + array: [Float32]) -> Offset + { b.createVector(array, size: array.count) } diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatbuffersDoubleTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatbuffersDoubleTests.swift index 660d52452..a6e1cb09b 100644 --- a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatbuffersDoubleTests.swift +++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatbuffersDoubleTests.swift @@ -99,7 +99,10 @@ class CountryDouble { return CountryDouble.end(builder: &builder, startOffset: _start) } - static func end(builder: inout FlatBufferBuilder, startOffset: UOffset) -> Offset { + static func end( + builder: inout FlatBufferBuilder, + startOffset: UOffset) -> Offset + { Offset(offset: builder.endTable(at: startOffset)) } diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatbuffersVerifierTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatbuffersVerifierTests.swift index dd80abf8d..750f97b97 100644 --- a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatbuffersVerifierTests.swift +++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatbuffersVerifierTests.swift @@ -143,7 +143,8 @@ final class FlatbuffersVerifierTests: XCTestCase { field: 22, fieldName: "test4", required: false, - type: ForwardOffset>.self)) + type: ForwardOffset> + .self)) XCTAssertNoThrow(try tableVerifer.visit( field: 24, @@ -201,11 +202,15 @@ final class FlatbuffersVerifierTests: XCTestCase { } func testFullVerifier() { - XCTAssertNoThrow(try getCheckedRoot(byteBuffer: &validFlatbuffersObject) as MyGame_Example_Monster) + XCTAssertNoThrow( + try getCheckedRoot( + byteBuffer: &validFlatbuffersObject) as MyGame_Example_Monster) } func testInvalidBuffer() { - XCTAssertThrowsError(try getCheckedRoot(byteBuffer: &invalidFlatbuffersObject) as MyGame_Example_Monster) + XCTAssertThrowsError( + try getCheckedRoot( + byteBuffer: &invalidFlatbuffersObject) as MyGame_Example_Monster) } func testValidUnionBuffer() { diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/XCTestManifests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/XCTestManifests.swift index 9c04bb81b..41347628c 100644 --- a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/XCTestManifests.swift +++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/XCTestManifests.swift @@ -136,7 +136,9 @@ extension FlatbuffersVerifierTests { public func __allTests() -> [XCTestCaseEntry] { [ testCase(FlatBuffersDoubleTests.__allTests__FlatBuffersDoubleTests), - testCase(FlatBuffersMonsterWriterTests.__allTests__FlatBuffersMonsterWriterTests), + testCase( + FlatBuffersMonsterWriterTests + .__allTests__FlatBuffersMonsterWriterTests), testCase(FlatBuffersMoreDefaults.__allTests__FlatBuffersMoreDefaults), testCase(FlatBuffersStructsTests.__allTests__FlatBuffersStructsTests), testCase(FlatBuffersTests.__allTests__FlatBuffersTests),