From 63cc0eec4e59015c91ab09894cb6822191a28151 Mon Sep 17 00:00:00 2001 From: mustiikhalil Date: Tue, 4 Aug 2020 13:53:40 +0300 Subject: [PATCH] Adds a serialize helper function to native table (#6059) * Adds a serialize helper function to native table * Updated version --- src/idl_gen_swift.cpp | 46 +++++++++++-------- swift/FlatBuffers.podspec | 2 +- .../FlatBuffers/FlatBufferObject.swift | 2 - swift/Sources/FlatBuffers/NativeTable.swift | 29 ++++++++++++ .../FlatBuffersMonsterWriterTests.swift | 8 ++-- .../monster_test_generated.swift | 28 ++++++++--- .../union_vector_generated.swift | 8 +++- 7 files changed, 86 insertions(+), 37 deletions(-) create mode 100644 swift/Sources/FlatBuffers/NativeTable.swift diff --git a/src/idl_gen_swift.cpp b/src/idl_gen_swift.cpp index 76749d714b5..25d9fc43c99 100644 --- a/src/idl_gen_swift.cpp +++ b/src/idl_gen_swift.cpp @@ -147,9 +147,7 @@ class SwiftGenerator : public BaseGenerator { for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); ++it) { const auto &enum_def = **it; - if (!enum_def.generated) { - GenEnum(enum_def); - } + if (!enum_def.generated) { GenEnum(enum_def); } } for (auto it = parser_.structs_.vec.begin(); @@ -284,7 +282,10 @@ class SwiftGenerator : public BaseGenerator { code_.SetValue("PROTOCOL", struct_def.fixed ? "Readable" : "FlatBufferObject"); code_.SetValue("OBJECTTYPE", struct_def.fixed ? "Struct" : "Table"); - code_ += "public struct {{STRUCTNAME}}: {{PROTOCOL}} {\n"; + code_ += "public struct {{STRUCTNAME}}: {{PROTOCOL}}\\"; + if (!struct_def.fixed && parser_.opts.generate_object_based_api) + code_ += ", ObjectAPI\\"; + code_ += " {\n"; Indent(); code_ += ValidateFunc(); code_ += "public var __buffer: ByteBuffer! { return {{ACCESS}}.bb }"; @@ -452,7 +453,8 @@ class SwiftGenerator : public BaseGenerator { ++it) { code_ += *it; } - code_ += "return {{STRUCTNAME}}.end{{SHORT_STRUCTNAME}}(&fbb, start: __start)"; + code_ += + "return {{STRUCTNAME}}.end{{SHORT_STRUCTNAME}}(&fbb, start: __start)"; Outdent(); code_ += "}"; } @@ -848,9 +850,14 @@ class SwiftGenerator : public BaseGenerator { base_constructor); } code_ += ""; - BuildObjectAPIConstructor(buffer_constructor, - "_ _t: inout " + NameWrappedInNameSpace(struct_def)); + BuildObjectAPIConstructor( + buffer_constructor, + "_ _t: inout " + NameWrappedInNameSpace(struct_def)); BuildObjectAPIConstructor(base_constructor); + if (!struct_def.fixed) + code_ += + "func serialize() -> ByteBuffer { return serialize(type: " + "{{STRUCTNAME}}.self) }\n"; Outdent(); code_ += "}"; } @@ -899,8 +906,10 @@ class SwiftGenerator : public BaseGenerator { GenerateStructArgs(*field.value.type.struct_def, &code, "", "", "$0", true); code = code.substr(0, code.size() - 2); - code_ += "let __" + name + " = obj." + name + ".map { " + NameWrappedInNameSpace(*field.value.type.struct_def) + ".create" + - Name(*field.value.type.struct_def) + "(" + code + ") }"; + code_ += "let __" + name + " = obj." + name + ".map { " + + NameWrappedInNameSpace(*field.value.type.struct_def) + + ".create" + Name(*field.value.type.struct_def) + "(" + + code + ") }"; } else { code_ += "let __" + name + " = " + type + ".pack(&builder, obj: &obj." + name + ")"; @@ -978,8 +987,10 @@ class SwiftGenerator : public BaseGenerator { code_ += "for i in obj." + name + " {"; Indent(); code_ += "guard let _o = i else { continue }"; - code_ += "__" + name + "__.append(" + NameWrappedInNameSpace(*field.value.type.struct_def) + ".create" + - Name(*field.value.type.struct_def) + "(" + code + "))"; + code_ += "__" + name + "__.append(" + + NameWrappedInNameSpace(*field.value.type.struct_def) + + ".create" + Name(*field.value.type.struct_def) + "(" + code + + "))"; Outdent(); code_ += "}"; code_ += "let __" + name + " = builder.createVector(structs: __" + @@ -1356,8 +1367,7 @@ class SwiftGenerator : public BaseGenerator { return WrapInNameSpace(struct_.defined_namespace, ObjectAPIName(Name(struct_))); } - return WrapInNameSpace(struct_.defined_namespace, - Name(struct_)); + return WrapInNameSpace(struct_.defined_namespace, Name(struct_)); } case BASE_TYPE_UNION: default: return "FlatBufferObject"; @@ -1377,13 +1387,11 @@ class SwiftGenerator : public BaseGenerator { void Outdent() { code_.DecrementIdentLevel(); } std::string NameWrappedInNameSpace(const EnumDef &enum_def) const { - return WrapInNameSpace(enum_def.defined_namespace, - Name(enum_def)); + return WrapInNameSpace(enum_def.defined_namespace, Name(enum_def)); } std::string NameWrappedInNameSpace(const StructDef &struct_def) const { - return WrapInNameSpace(struct_def.defined_namespace, - Name(struct_def)); + return WrapInNameSpace(struct_def.defined_namespace, Name(struct_def)); } std::string GenTypeBasic(const Type &type, bool can_override) const { @@ -1397,8 +1405,7 @@ class SwiftGenerator : public BaseGenerator { }; // clang-format on if (can_override) { - if (type.enum_def) - return NameWrappedInNameSpace(*type.enum_def); + if (type.enum_def) return NameWrappedInNameSpace(*type.enum_def); if (type.base_type == BASE_TYPE_BOOL) return "Bool"; } return swift_type[static_cast(type.base_type)]; @@ -1419,7 +1426,6 @@ class SwiftGenerator : public BaseGenerator { std::string Name(const Definition &def) const { return EscapeKeyword(MakeCamel(def.name, false)); } - }; } // namespace swift bool GenerateSwift(const Parser &parser, const std::string &path, diff --git a/swift/FlatBuffers.podspec b/swift/FlatBuffers.podspec index ac799464b75..af78966002e 100644 --- a/swift/FlatBuffers.podspec +++ b/swift/FlatBuffers.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'FlatBuffers' - s.version = '0.7.0' + s.version = '0.7.1' s.summary = 'FlatBuffers: Memory Efficient Serialization Library' s.description = "FlatBuffers is a cross platform serialization library architected for diff --git a/swift/Sources/FlatBuffers/FlatBufferObject.swift b/swift/Sources/FlatBuffers/FlatBufferObject.swift index 8fc23221ab1..52ca396ade6 100644 --- a/swift/Sources/FlatBuffers/FlatBufferObject.swift +++ b/swift/Sources/FlatBuffers/FlatBufferObject.swift @@ -6,8 +6,6 @@ public protocol FlatBufferObject { init(_ bb: ByteBuffer, o: Int32) } -public protocol NativeTable {} - public protocol ObjectAPI { associatedtype T static func pack(_ builder: inout FlatBufferBuilder, obj: inout T) -> Offset diff --git a/swift/Sources/FlatBuffers/NativeTable.swift b/swift/Sources/FlatBuffers/NativeTable.swift new file mode 100644 index 00000000000..057b3766ec7 --- /dev/null +++ b/swift/Sources/FlatBuffers/NativeTable.swift @@ -0,0 +1,29 @@ +import Foundation + +public protocol NativeTable {} + +extension NativeTable { + + /// 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 { + var builder = FlatBufferBuilder(initialSize: 1024) + return serialize(builder: &builder, type: type.self) + } + + /// Serialize is a helper function that serailizes the data from the Object API to a bytebuffer directly. + /// + /// - Parameters: + /// - builder: A FlatBufferBuilder + /// - type: Type of the Flatbuffer object + /// - Returns: returns the encoded sized ByteBuffer + /// - Note: The `serialize(builder:type)` can be considered as a function that allows you to create smaller builder instead of the default `1024`. + /// It can be considered less expensive in terms of memory allocation + public func serialize(builder: inout FlatBufferBuilder, type: T.Type) -> ByteBuffer where T.T == Self { + var s = self + let root = type.pack(&builder, obj: &s) + builder.finish(offset: root) + return builder.sizedBuffer + } +} 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 6cd140504f0..12fd48ee37a 100644 --- a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersMonsterWriterTests.swift +++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersMonsterWriterTests.swift @@ -81,12 +81,10 @@ class FlatBuffersMonsterWriterTests: XCTestCase { func readMonster(fb: ByteBuffer) { var monster = Monster.getRootAsMonster(bb: fb) readFlatbufferMonster(monster: &monster) - var unpacked: MyGame_Example_MonsterT? = monster.unpack() + let unpacked: MyGame_Example_MonsterT? = monster.unpack() readObjectApi(monster: unpacked!) - var builder = FlatBufferBuilder() - let root = Monster.pack(&builder, obj: &unpacked) - builder.finish(offset: root) - var newMonster = Monster.getRootAsMonster(bb: builder.sizedBuffer) + 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/monster_test_generated.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/monster_test_generated.swift index ae8015e053f..e96f8db3865 100644 --- a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/monster_test_generated.swift +++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/monster_test_generated.swift @@ -334,7 +334,7 @@ extension MyGame_Example_Ability { } -public struct MyGame_InParentNamespace: FlatBufferObject { +public struct MyGame_InParentNamespace: FlatBufferObject, ObjectAPI { static func validateVersion() { FlatBuffersVersion_1_12_0() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -373,8 +373,10 @@ public class MyGame_InParentNamespaceT: NativeTable { init() { } + func serialize() -> ByteBuffer { return serialize(type: MyGame_InParentNamespace.self) } + } -public struct MyGame_Example2_Monster: FlatBufferObject { +public struct MyGame_Example2_Monster: FlatBufferObject, ObjectAPI { static func validateVersion() { FlatBuffersVersion_1_12_0() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -413,8 +415,10 @@ public class MyGame_Example2_MonsterT: NativeTable { init() { } + func serialize() -> ByteBuffer { return serialize(type: MyGame_Example2_Monster.self) } + } -public struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferObject { +public struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferObject, ObjectAPI { static func validateVersion() { FlatBuffersVersion_1_12_0() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -474,8 +478,10 @@ public class MyGame_Example_TestSimpleTableWithEnumT: NativeTable { color = .green } + func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_TestSimpleTableWithEnum.self) } + } -public struct MyGame_Example_Stat: FlatBufferObject { +public struct MyGame_Example_Stat: FlatBufferObject, ObjectAPI { static func validateVersion() { FlatBuffersVersion_1_12_0() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -561,8 +567,10 @@ public class MyGame_Example_StatT: NativeTable { count = 0 } + func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Stat.self) } + } -public struct MyGame_Example_Referrable: FlatBufferObject { +public struct MyGame_Example_Referrable: FlatBufferObject, ObjectAPI { static func validateVersion() { FlatBuffersVersion_1_12_0() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -646,9 +654,11 @@ public class MyGame_Example_ReferrableT: NativeTable { id = 0 } + func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Referrable.self) } + } /// an example documentation comment: "monster object" -public struct MyGame_Example_Monster: FlatBufferObject { +public struct MyGame_Example_Monster: FlatBufferObject, ObjectAPI { static func validateVersion() { FlatBuffersVersion_1_12_0() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -1364,8 +1374,10 @@ public class MyGame_Example_MonsterT: NativeTable { signedEnum = .none_ } + func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Monster.self) } + } -public struct MyGame_Example_TypeAliases: FlatBufferObject { +public struct MyGame_Example_TypeAliases: FlatBufferObject, ObjectAPI { static func validateVersion() { FlatBuffersVersion_1_12_0() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -1547,4 +1559,6 @@ public class MyGame_Example_TypeAliasesT: NativeTable { vf64 = [] } + func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_TypeAliases.self) } + } diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/union_vector_generated.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/union_vector_generated.swift index e73b736a313..5048cf5fb04 100644 --- a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/union_vector_generated.swift +++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/union_vector_generated.swift @@ -145,7 +145,7 @@ extension BookReader { } -public struct Attacker: FlatBufferObject { +public struct Attacker: FlatBufferObject, ObjectAPI { static func validateVersion() { FlatBuffersVersion_1_12_0() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -205,8 +205,10 @@ public class AttackerT: NativeTable { swordAttackDamage = 0 } + func serialize() -> ByteBuffer { return serialize(type: Attacker.self) } + } -public struct Movie: FlatBufferObject { +public struct Movie: FlatBufferObject, ObjectAPI { static func validateVersion() { FlatBuffersVersion_1_12_0() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -329,4 +331,6 @@ public class MovieT: NativeTable { characters = [] } + func serialize() -> ByteBuffer { return serialize(type: Movie.self) } + }