Adds a serialize helper function to native table (#6059)
authormustiikhalil <mustii@mmk.one>
Tue, 4 Aug 2020 10:53:40 +0000 (13:53 +0300)
committerGitHub <noreply@github.com>
Tue, 4 Aug 2020 10:53:40 +0000 (13:53 +0300)
* Adds a serialize helper function to native table
* Updated version

src/idl_gen_swift.cpp
swift/FlatBuffers.podspec
swift/Sources/FlatBuffers/FlatBufferObject.swift
swift/Sources/FlatBuffers/NativeTable.swift [new file with mode: 0644]
tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersMonsterWriterTests.swift
tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/monster_test_generated.swift
tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/union_vector_generated.swift

index 76749d7..25d9fc4 100644 (file)
@@ -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<int>(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,
index ac79946..af78966 100644 (file)
@@ -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
index 8fc2322..52ca396 100644 (file)
@@ -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<UOffset>
diff --git a/swift/Sources/FlatBuffers/NativeTable.swift b/swift/Sources/FlatBuffers/NativeTable.swift
new file mode 100644 (file)
index 0000000..057b376
--- /dev/null
@@ -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<T: ObjectAPI>(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<T: ObjectAPI>(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
+    }
+}
index 6cd1405..12fd48e 100644 (file)
@@ -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)
     }
     
index ae8015e..e96f8db 100644 (file)
@@ -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) }
+
 }
index e73b736..5048cf5 100644 (file)
@@ -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) }
+
 }