forked from BigfootDev/flatbuffers
[Swift] Object API support (#5826)
* Adds Object-api support to swift * Fixed indentation issues * Removed indentation within namespaces
This commit is contained in:
@@ -22,7 +22,7 @@ Feature | C++ | Java | C# | Go | Python | JS
|
|||||||
------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | --------- | ------ | --- | ------- | ------- | ------- | ------
|
------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | --------- | ------ | --- | ------- | ------- | ------- | ------
|
||||||
Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | Yes | Yes | Yes | Yes
|
Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | Yes | Yes | Yes | Yes
|
||||||
JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | Yes | No | No
|
JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | Yes | No | No
|
||||||
Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No | No | No
|
Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No | No | Yes
|
||||||
Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No | No
|
Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No | No
|
||||||
Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No | No
|
Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No | No
|
||||||
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes | Yes
|
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes | Yes
|
||||||
|
|||||||
@@ -75,6 +75,10 @@ class CodeWriter {
|
|||||||
void DecrementIdentLevel() {
|
void DecrementIdentLevel() {
|
||||||
if (cur_ident_lvl_) cur_ident_lvl_--;
|
if (cur_ident_lvl_) cur_ident_lvl_--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetPadding(const std::string &padding) {
|
||||||
|
pad_ = padding;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, std::string> value_map_;
|
std::map<std::string, std::string> value_map_;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ inline std::string GenIndirect(const std::string &reading) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline std::string GenArrayMainBody(const std::string &optional) {
|
inline std::string GenArrayMainBody(const std::string &optional) {
|
||||||
return "\tpublic func {{VALUENAME}}(at index: Int32) -> {{VALUETYPE}}" +
|
return "public func {{VALUENAME}}(at index: Int32) -> {{VALUETYPE}}" +
|
||||||
optional + " { ";
|
optional + " { ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +52,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
: BaseGenerator(parser, path, file_name, "", ".", "swift"),
|
: BaseGenerator(parser, path, file_name, "", ".", "swift"),
|
||||||
cur_name_space_(nullptr) {
|
cur_name_space_(nullptr) {
|
||||||
namespace_depth = 0;
|
namespace_depth = 0;
|
||||||
|
code_.SetPadding(" ");
|
||||||
static const char *const keywords[] = {
|
static const char *const keywords[] = {
|
||||||
"associatedtype",
|
"associatedtype",
|
||||||
"class",
|
"class",
|
||||||
@@ -158,6 +159,9 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
if (struct_def.fixed && !struct_def.generated) {
|
if (struct_def.fixed && !struct_def.generated) {
|
||||||
SetNameSpace(struct_def.defined_namespace);
|
SetNameSpace(struct_def.defined_namespace);
|
||||||
GenStructReader(struct_def);
|
GenStructReader(struct_def);
|
||||||
|
if (parser_.opts.generate_object_based_api) {
|
||||||
|
GenObjectAPI(struct_def);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,6 +180,9 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
if (!struct_def.fixed && !struct_def.generated) {
|
if (!struct_def.fixed && !struct_def.generated) {
|
||||||
SetNameSpace(struct_def.defined_namespace);
|
SetNameSpace(struct_def.defined_namespace);
|
||||||
GenTable(struct_def);
|
GenTable(struct_def);
|
||||||
|
if (parser_.opts.generate_object_based_api) {
|
||||||
|
GenObjectAPI(struct_def);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,17 +204,19 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
std::string static_type = this->namespace_depth == 0 ? "" : "static ";
|
std::string static_type = this->namespace_depth == 0 ? "" : "static ";
|
||||||
code_ += "public " + static_type + "func create{{STRUCTNAME}}(\\";
|
code_ += "public " + static_type + "func create{{STRUCTNAME}}(\\";
|
||||||
std::string func_header = "";
|
std::string func_header = "";
|
||||||
GenerateStructArgs(struct_def, &func_header, "");
|
GenerateStructArgs(struct_def, &func_header, "", "");
|
||||||
code_ += func_header.substr(0, func_header.size() - 2) + "\\";
|
code_ += func_header.substr(0, func_header.size() - 2) + "\\";
|
||||||
code_ += ") -> UnsafeMutableRawPointer {";
|
code_ += ") -> UnsafeMutableRawPointer {";
|
||||||
|
Indent();
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tlet memory = UnsafeMutableRawPointer.allocate(byteCount: "
|
"let memory = UnsafeMutableRawPointer.allocate(byteCount: "
|
||||||
"{{STRUCTNAME}}.size, alignment: {{STRUCTNAME}}.alignment)";
|
"{{STRUCTNAME}}.size, alignment: {{STRUCTNAME}}.alignment)";
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tmemory.initializeMemory(as: UInt8.self, repeating: 0, count: "
|
"memory.initializeMemory(as: UInt8.self, repeating: 0, count: "
|
||||||
"{{STRUCTNAME}}.size)";
|
"{{STRUCTNAME}}.size)";
|
||||||
GenerateStructBody(struct_def, "");
|
GenerateStructBody(struct_def, "");
|
||||||
code_ += "\treturn memory";
|
code_ += "return memory";
|
||||||
|
Outdent();
|
||||||
code_ += "}\n";
|
code_ += "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +234,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
static_cast<int>(field.value.offset));
|
static_cast<int>(field.value.offset));
|
||||||
} else {
|
} else {
|
||||||
auto off = NumToString(offset + field.value.offset);
|
auto off = NumToString(offset + field.value.offset);
|
||||||
code_ += "\tmemory.storeBytes(of: " + name +
|
code_ += "memory.storeBytes(of: " + name +
|
||||||
(field_type.enum_def ? ".rawValue" : "") +
|
(field_type.enum_def ? ".rawValue" : "") +
|
||||||
", toByteOffset: " + off + ", as: " + type + ".self)";
|
", toByteOffset: " + off + ", as: " + type + ".self)";
|
||||||
}
|
}
|
||||||
@@ -233,7 +242,10 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GenerateStructArgs(const StructDef &struct_def, std::string *code_ptr,
|
void GenerateStructArgs(const StructDef &struct_def, std::string *code_ptr,
|
||||||
const std::string &nameprefix) {
|
const std::string &nameprefix,
|
||||||
|
const std::string &object_name,
|
||||||
|
const std::string &obj_api_named = "",
|
||||||
|
bool is_obj_api = false) {
|
||||||
auto &code = *code_ptr;
|
auto &code = *code_ptr;
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
@@ -241,12 +253,19 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
const auto &field_type = field.value.type;
|
const auto &field_type = field.value.type;
|
||||||
if (IsStruct(field.value.type)) {
|
if (IsStruct(field.value.type)) {
|
||||||
GenerateStructArgs(*field_type.struct_def, code_ptr,
|
GenerateStructArgs(
|
||||||
(nameprefix + field.name));
|
*field_type.struct_def, code_ptr, (nameprefix + field.name),
|
||||||
|
(object_name + "." + field.name), obj_api_named, is_obj_api);
|
||||||
} else {
|
} else {
|
||||||
auto name = Name(field);
|
auto name = Name(field);
|
||||||
auto type = GenType(field.value.type);
|
auto type = GenType(field.value.type);
|
||||||
code += nameprefix + name + ": " + type;
|
if (!is_obj_api) {
|
||||||
|
code += nameprefix + name + ": " + type;
|
||||||
|
code += ", ";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
code +=
|
||||||
|
nameprefix + name + ": " + obj_api_named + object_name + "." + name;
|
||||||
code += ", ";
|
code += ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,32 +278,33 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
struct_def.fixed ? "Readable" : "FlatBufferObject");
|
struct_def.fixed ? "Readable" : "FlatBufferObject");
|
||||||
code_.SetValue("OBJECTTYPE", struct_def.fixed ? "Struct" : "Table");
|
code_.SetValue("OBJECTTYPE", struct_def.fixed ? "Struct" : "Table");
|
||||||
code_ += "public struct {{STRUCTNAME}}: {{PROTOCOL}} {\n";
|
code_ += "public struct {{STRUCTNAME}}: {{PROTOCOL}} {\n";
|
||||||
|
Indent();
|
||||||
code_ += ValidateFunc();
|
code_ += ValidateFunc();
|
||||||
code_ += "\tpublic var __buffer: ByteBuffer! { return {{ACCESS}}.bb }";
|
code_ += "public var __buffer: ByteBuffer! { return {{ACCESS}}.bb }";
|
||||||
code_ += "\n\tprivate var {{ACCESS}}: {{OBJECTTYPE}}";
|
code_ += "private var {{ACCESS}}: {{OBJECTTYPE}}\n";
|
||||||
if (struct_def.fixed) {
|
if (struct_def.fixed) {
|
||||||
code_.SetValue("BYTESIZE", NumToString(struct_def.bytesize));
|
code_.SetValue("BYTESIZE", NumToString(struct_def.bytesize));
|
||||||
code_.SetValue("MINALIGN", NumToString(struct_def.minalign));
|
code_.SetValue("MINALIGN", NumToString(struct_def.minalign));
|
||||||
code_ += "\tpublic static var size = {{BYTESIZE}}";
|
code_ += "public static var size = {{BYTESIZE}}";
|
||||||
code_ += "\tpublic static var alignment = {{MINALIGN}}\t";
|
code_ += "public static var alignment = {{MINALIGN}}";
|
||||||
} else {
|
} else {
|
||||||
if (parser_.file_identifier_.length()) {
|
if (parser_.file_identifier_.length()) {
|
||||||
code_.SetValue("FILENAME", parser_.file_identifier_);
|
code_.SetValue("FILENAME", parser_.file_identifier_);
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tpublic static func finish(_ fbb: inout FlatBufferBuilder, end: "
|
"public static func finish(_ fbb: inout FlatBufferBuilder, end: "
|
||||||
"Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, "
|
"Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, "
|
||||||
"fileId: "
|
"fileId: "
|
||||||
"\"{{FILENAME}}\", addPrefix: prefix) }";
|
"\"{{FILENAME}}\", addPrefix: prefix) }";
|
||||||
}
|
}
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tpublic static func getRootAs{{STRUCTNAME}}(bb: ByteBuffer) -> "
|
"public static func getRootAs{{STRUCTNAME}}(bb: ByteBuffer) -> "
|
||||||
"{{STRUCTNAME}} { return {{STRUCTNAME}}(Table(bb: bb, position: "
|
"{{STRUCTNAME}} { return {{STRUCTNAME}}(Table(bb: bb, position: "
|
||||||
"Int32(bb.read(def: UOffset.self, position: bb.reader)) + "
|
"Int32(bb.read(def: UOffset.self, position: bb.reader)) + "
|
||||||
"Int32(bb.reader))) }\n";
|
"Int32(bb.reader))) }\n";
|
||||||
code_ += "\tprivate init(_ t: Table) { {{ACCESS}} = t }";
|
code_ += "private init(_ t: Table) { {{ACCESS}} = t }";
|
||||||
}
|
}
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tpublic init(_ bb: ByteBuffer, o: Int32) { {{ACCESS}} = "
|
"public init(_ bb: ByteBuffer, o: Int32) { {{ACCESS}} = "
|
||||||
"{{OBJECTTYPE}}(bb: "
|
"{{OBJECTTYPE}}(bb: "
|
||||||
"bb, position: o) }";
|
"bb, position: o) }";
|
||||||
code_ += "";
|
code_ += "";
|
||||||
@@ -295,9 +315,38 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
GenObjectHeader(struct_def);
|
GenObjectHeader(struct_def);
|
||||||
GenTableReader(struct_def);
|
GenTableReader(struct_def);
|
||||||
GenTableWriter(struct_def);
|
GenTableWriter(struct_def);
|
||||||
|
if (parser_.opts.generate_object_based_api)
|
||||||
|
GenerateObjectAPITableExtension(struct_def);
|
||||||
|
Outdent();
|
||||||
code_ += "}\n";
|
code_ += "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenerateObjectAPIExtensionHeader() {
|
||||||
|
code_ += "\n";
|
||||||
|
code_ += "public mutating func unpack() -> {{STRUCTNAME}}T {";
|
||||||
|
Indent();
|
||||||
|
code_ += "return {{STRUCTNAME}}T(&self)";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
code_ +=
|
||||||
|
"public static func pack(_ builder: inout FlatBufferBuilder, obj: "
|
||||||
|
"inout {{STRUCTNAME}}T?) -> Offset<UOffset> {";
|
||||||
|
Indent();
|
||||||
|
code_ += "guard let obj = obj else { return Offset<UOffset>() }";
|
||||||
|
code_ += "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateObjectAPIStructExtension(const StructDef &struct_def) {
|
||||||
|
GenerateObjectAPIExtensionHeader();
|
||||||
|
std::string code;
|
||||||
|
GenerateStructArgs(struct_def, &code, "", "", "obj", true);
|
||||||
|
code_ += "return builder.create(struct: create{{STRUCTNAME}}(\\";
|
||||||
|
code_ += code.substr(0, code.size() - 2) + "\\";
|
||||||
|
code_ += "), type: {{STRUCTNAME}}.self)";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
}
|
||||||
|
|
||||||
void GenTableReader(const StructDef &struct_def) {
|
void GenTableReader(const StructDef &struct_def) {
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
@@ -310,13 +359,14 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
void GenTableWriter(const StructDef &struct_def) {
|
void GenTableWriter(const StructDef &struct_def) {
|
||||||
flatbuffers::FieldDef *key_field = nullptr;
|
flatbuffers::FieldDef *key_field = nullptr;
|
||||||
std::vector<std::string> require_fields;
|
std::vector<std::string> require_fields;
|
||||||
std::string create_func_body;
|
std::vector<std::string> create_func_body;
|
||||||
std::string create_func_header;
|
std::vector<std::string> create_func_header;
|
||||||
auto should_generate_create = struct_def.fields.vec.size() != 0;
|
auto should_generate_create = struct_def.fields.vec.size() != 0;
|
||||||
|
|
||||||
code_.SetValue("NUMBEROFFIELDS", NumToString(struct_def.fields.vec.size()));
|
code_.SetValue("NUMBEROFFIELDS", NumToString(struct_def.fields.vec.size()));
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tpublic static func start{{STRUCTNAME}}(_ fbb: inout FlatBufferBuilder) -> "
|
"public static func start{{STRUCTNAME}}(_ fbb: inout "
|
||||||
|
"FlatBufferBuilder) -> "
|
||||||
"UOffset { fbb.startTable(with: {{NUMBEROFFIELDS}}) }";
|
"UOffset { fbb.startTable(with: {{NUMBEROFFIELDS}}) }";
|
||||||
|
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
@@ -332,7 +382,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
static_cast<int>(it - struct_def.fields.vec.begin()));
|
static_cast<int>(it - struct_def.fields.vec.begin()));
|
||||||
}
|
}
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tpublic static func end{{STRUCTNAME}}(_ fbb: inout FlatBufferBuilder, "
|
"public static func end{{STRUCTNAME}}(_ fbb: inout "
|
||||||
|
"FlatBufferBuilder, "
|
||||||
"start: "
|
"start: "
|
||||||
"UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: "
|
"UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: "
|
||||||
"fbb.endTable(at: start))\\";
|
"fbb.endTable(at: start))\\";
|
||||||
@@ -345,29 +396,38 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
code_ += "; return end }";
|
code_ += "; return end }";
|
||||||
|
|
||||||
code_ +=
|
if (should_generate_create) {
|
||||||
"\tpublic static func create{{STRUCTNAME}}(_ fbb: inout FlatBufferBuilder\\";
|
code_ +=
|
||||||
if (should_generate_create)
|
"public static func create{{STRUCTNAME}}(_ fbb: inout "
|
||||||
code_ += ",\n" +
|
"FlatBufferBuilder,";
|
||||||
create_func_header.substr(0, create_func_header.size() - 2) +
|
for (auto it = create_func_header.begin(); it < create_func_header.end();
|
||||||
"\\";
|
++it) {
|
||||||
code_ += ") -> Offset<UOffset> {";
|
code_ += *it + "\\";
|
||||||
code_ += "\t\tlet __start = {{STRUCTNAME}}.start{{STRUCTNAME}}(&fbb)";
|
if (it < create_func_header.end() - 1) code_ += ",";
|
||||||
if (should_generate_create)
|
}
|
||||||
code_ += create_func_body.substr(0, create_func_body.size() - 1);
|
code_ += ") -> Offset<UOffset> {";
|
||||||
code_ += "\t\treturn {{STRUCTNAME}}.end{{STRUCTNAME}}(&fbb, start: __start)";
|
Indent();
|
||||||
code_ += "\t}";
|
code_ += "let __start = {{STRUCTNAME}}.start{{STRUCTNAME}}(&fbb)";
|
||||||
|
for (auto it = create_func_body.begin(); it < create_func_body.end();
|
||||||
|
++it) {
|
||||||
|
code_ += *it;
|
||||||
|
}
|
||||||
|
code_ += "return {{STRUCTNAME}}.end{{STRUCTNAME}}(&fbb, start: __start)";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
}
|
||||||
|
|
||||||
std::string spacing = "\t\t";
|
std::string spacing = "";
|
||||||
|
|
||||||
if (key_field != nullptr && !struct_def.fixed && struct_def.has_key) {
|
if (key_field != nullptr && !struct_def.fixed && struct_def.has_key) {
|
||||||
code_.SetValue("VALUENAME", struct_def.name);
|
code_.SetValue("VALUENAME", struct_def.name);
|
||||||
code_.SetValue("VOFFSET", NumToString(key_field->value.offset));
|
code_.SetValue("VOFFSET", NumToString(key_field->value.offset));
|
||||||
|
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tpublic static func "
|
"public static func "
|
||||||
"sortVectorOf{{VALUENAME}}(offsets:[Offset<UOffset>], "
|
"sortVectorOf{{VALUENAME}}(offsets:[Offset<UOffset>], "
|
||||||
"_ fbb: inout FlatBufferBuilder) -> Offset<UOffset> {";
|
"_ fbb: inout FlatBufferBuilder) -> Offset<UOffset> {";
|
||||||
|
Indent();
|
||||||
code_ += spacing + "var off = offsets";
|
code_ += spacing + "var off = offsets";
|
||||||
code_ +=
|
code_ +=
|
||||||
spacing +
|
spacing +
|
||||||
@@ -375,13 +435,16 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
"{{VOFFSET}}, fbb: fbb.buffer), Table.offset(Int32($0.o), vOffset: "
|
"{{VOFFSET}}, fbb: fbb.buffer), Table.offset(Int32($0.o), vOffset: "
|
||||||
"{{VOFFSET}}, fbb: fbb.buffer), fbb: fbb.buffer) < 0 } ";
|
"{{VOFFSET}}, fbb: fbb.buffer), fbb: fbb.buffer) < 0 } ";
|
||||||
code_ += spacing + "return fbb.createVector(ofOffsets: off)";
|
code_ += spacing + "return fbb.createVector(ofOffsets: off)";
|
||||||
code_ += "\t}";
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
GenLookup(*key_field);
|
GenLookup(*key_field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenTableWriterFields(const FieldDef &field, std::string *create_body,
|
void GenTableWriterFields(const FieldDef &field,
|
||||||
std::string *create_header, const int position) {
|
std::vector<std::string> *create_body,
|
||||||
|
std::vector<std::string> *create_header,
|
||||||
|
const int position) {
|
||||||
std::string builder_string = ", _ fbb: inout FlatBufferBuilder) { fbb.add(";
|
std::string builder_string = ", _ fbb: inout FlatBufferBuilder) { fbb.add(";
|
||||||
auto &create_func_body = *create_body;
|
auto &create_func_body = *create_body;
|
||||||
auto &create_func_header = *create_header;
|
auto &create_func_header = *create_header;
|
||||||
@@ -396,10 +459,10 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
field.value.type.base_type == BASE_TYPE_ARRAY)
|
field.value.type.base_type == BASE_TYPE_ARRAY)
|
||||||
? "VectorOf("
|
? "VectorOf("
|
||||||
: "(";
|
: "(";
|
||||||
std::string body = "add" + check_if_vector + name + ": ";
|
auto body = "add" + check_if_vector + name + ": ";
|
||||||
code_ += "\tpublic static func " + body + "\\";
|
code_ += "public static func " + body + "\\";
|
||||||
|
|
||||||
create_func_body += "\t\t{{STRUCTNAME}}." + body + name + ", &fbb)\n";
|
create_func_body.push_back("{{STRUCTNAME}}." + body + name + ", &fbb)");
|
||||||
|
|
||||||
if (IsScalar(field.value.type.base_type) &&
|
if (IsScalar(field.value.type.base_type) &&
|
||||||
!IsBool(field.value.type.base_type)) {
|
!IsBool(field.value.type.base_type)) {
|
||||||
@@ -408,8 +471,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
auto is_enum = IsEnum(field.value.type) ? ".rawValue" : "";
|
auto is_enum = IsEnum(field.value.type) ? ".rawValue" : "";
|
||||||
code_ += "{{VALUETYPE}}" + builder_string + "element: {{VALUENAME}}" +
|
code_ += "{{VALUETYPE}}" + builder_string + "element: {{VALUENAME}}" +
|
||||||
is_enum + ", def: {{CONSTANT}}, at: {{OFFSET}}) }";
|
is_enum + ", def: {{CONSTANT}}, at: {{OFFSET}}) }";
|
||||||
create_func_header +=
|
create_func_header.push_back("" + name + ": " + type + " = " +
|
||||||
"\t\t" + name + ": " + type + " = " + default_value + ",\n";
|
default_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,8 +483,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_.SetValue("CONSTANT", default_value);
|
code_.SetValue("CONSTANT", default_value);
|
||||||
code_ += "{{VALUETYPE}}" + builder_string +
|
code_ += "{{VALUETYPE}}" + builder_string +
|
||||||
"condition: {{VALUENAME}}, def: {{CONSTANT}}, at: {{OFFSET}}) }";
|
"condition: {{VALUENAME}}, def: {{CONSTANT}}, at: {{OFFSET}}) }";
|
||||||
create_func_header +=
|
create_func_header.push_back(name + ": " + type + " = " + default_value);
|
||||||
"\t\t" + name + ": " + type + " = " + default_value + ",\n";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,8 +496,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
? "vectorOf"
|
? "vectorOf"
|
||||||
: "offsetOf") +
|
: "offsetOf") +
|
||||||
MakeCamel(name, true);
|
MakeCamel(name, true);
|
||||||
create_func_header += "\t\t" + camel_case_name + " " + name + ": " +
|
create_func_header.push_back(camel_case_name + " " + name + ": " +
|
||||||
offset_type + " = Offset(),\n";
|
offset_type + " = Offset()");
|
||||||
auto reader_type =
|
auto reader_type =
|
||||||
IsStruct(field.value.type) && field.value.type.struct_def->fixed
|
IsStruct(field.value.type) && field.value.type.struct_def->fixed
|
||||||
? "structOffset: {{OFFSET}}) }"
|
? "structOffset: {{OFFSET}}) }"
|
||||||
@@ -452,7 +514,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_.SetValue("OFFSET", offset);
|
code_.SetValue("OFFSET", offset);
|
||||||
code_.SetValue("CONSTANT", field.value.constant);
|
code_.SetValue("CONSTANT", field.value.constant);
|
||||||
std::string const_string = "return o == 0 ? {{CONSTANT}} : ";
|
std::string const_string = "return o == 0 ? {{CONSTANT}} : ";
|
||||||
GenComment(field.doc_comment, "\t");
|
GenComment(field.doc_comment);
|
||||||
if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type) &&
|
if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type) &&
|
||||||
!IsBool(field.value.type.base_type)) {
|
!IsBool(field.value.type.base_type)) {
|
||||||
code_ += GenReaderMainBody() + GenOffset() + const_string +
|
code_ += GenReaderMainBody() + GenOffset() + const_string +
|
||||||
@@ -504,7 +566,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += GenReaderMainBody("?") + GenOffset() + const_string +
|
code_ += GenReaderMainBody("?") + GenOffset() + const_string +
|
||||||
"{{ACCESS}}.string(at: o) }";
|
"{{ACCESS}}.string(at: o) }";
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tpublic var {{VALUENAME}}SegmentArray: [UInt8]? { return "
|
"public var {{VALUENAME}}SegmentArray: [UInt8]? { return "
|
||||||
"{{ACCESS}}.getVector(at: {{OFFSET}}) }";
|
"{{ACCESS}}.getVector(at: {{OFFSET}}) }";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -515,7 +577,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
case BASE_TYPE_UNION:
|
case BASE_TYPE_UNION:
|
||||||
code_.SetValue("CONSTANT", "nil");
|
code_.SetValue("CONSTANT", "nil");
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tpublic func {{VALUENAME}}<T: FlatBufferObject>(type: "
|
"public func {{VALUENAME}}<T: FlatBufferObject>(type: "
|
||||||
"T.Type) -> T? { " +
|
"T.Type) -> T? { " +
|
||||||
GenOffset() + const_string + "{{ACCESS}}.union(o) }";
|
GenOffset() + const_string + "{{ACCESS}}.union(o) }";
|
||||||
break;
|
break;
|
||||||
@@ -527,7 +589,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
const std::string &const_string) {
|
const std::string &const_string) {
|
||||||
auto vectortype = field.value.type.VectorType();
|
auto vectortype = field.value.type.VectorType();
|
||||||
code_.SetValue("SIZE", NumToString(InlineSize(vectortype)));
|
code_.SetValue("SIZE", NumToString(InlineSize(vectortype)));
|
||||||
code_ += "\tpublic var {{VALUENAME}}Count: Int32 { " + GenOffset() +
|
code_ += "public var {{VALUENAME}}Count: Int32 { " + GenOffset() +
|
||||||
const_string + "{{ACCESS}}.vector(count: o) }";
|
const_string + "{{ACCESS}}.vector(count: o) }";
|
||||||
code_.SetValue("CONSTANT", IsScalar(vectortype.base_type) == true
|
code_.SetValue("CONSTANT", IsScalar(vectortype.base_type) == true
|
||||||
? field.value.constant
|
? field.value.constant
|
||||||
@@ -538,7 +600,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += GenArrayMainBody(nullable) + GenOffset() + "\\";
|
code_ += GenArrayMainBody(nullable) + GenOffset() + "\\";
|
||||||
} else {
|
} else {
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tpublic func {{VALUENAME}}<T: FlatBufferObject>(at index: "
|
"public func {{VALUENAME}}<T: FlatBufferObject>(at index: "
|
||||||
"Int32, type: T.Type) -> T? { " +
|
"Int32, type: T.Type) -> T? { " +
|
||||||
GenOffset() + "\\";
|
GenOffset() + "\\";
|
||||||
}
|
}
|
||||||
@@ -557,7 +619,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
"{{ACCESS}}.directRead(of: {{VALUETYPE}}.self, offset: "
|
"{{ACCESS}}.directRead(of: {{VALUETYPE}}.self, offset: "
|
||||||
"{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }";
|
"{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }";
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tpublic var {{VALUENAME}}: [{{VALUETYPE}}] { return "
|
"public var {{VALUENAME}}: [{{VALUETYPE}}] { return "
|
||||||
"{{ACCESS}}.getVector(at: {{OFFSET}}) ?? [] }";
|
"{{ACCESS}}.getVector(at: {{OFFSET}}) ?? [] }";
|
||||||
if (parser_.opts.mutable_buffer) code_ += GenMutateArray();
|
if (parser_.opts.mutable_buffer) code_ += GenMutateArray();
|
||||||
return;
|
return;
|
||||||
@@ -610,7 +672,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
void GenByKeyFunctions(const FieldDef &key_field) {
|
void GenByKeyFunctions(const FieldDef &key_field) {
|
||||||
code_.SetValue("TYPE", GenType(key_field.value.type));
|
code_.SetValue("TYPE", GenType(key_field.value.type));
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tpublic func {{VALUENAME}}By(key: {{TYPE}}) -> {{VALUETYPE}}? { \\";
|
"public func {{VALUENAME}}By(key: {{TYPE}}) -> {{VALUETYPE}}? { \\";
|
||||||
code_ += GenOffset() +
|
code_ += GenOffset() +
|
||||||
"return o == 0 ? nil : {{VALUETYPE}}.lookupByKey(vector: "
|
"return o == 0 ? nil : {{VALUETYPE}}.lookupByKey(vector: "
|
||||||
"{{ACCESS}}.vector(at: o), key: key, fbb: {{ACCESS}}.bb) }";
|
"{{ACCESS}}.vector(at: o), key: key, fbb: {{ACCESS}}.bb) }";
|
||||||
@@ -629,7 +691,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_.SetValue("VALUENAME", name);
|
code_.SetValue("VALUENAME", name);
|
||||||
code_.SetValue("VALUETYPE", type);
|
code_.SetValue("VALUETYPE", type);
|
||||||
code_.SetValue("OFFSET", offset);
|
code_.SetValue("OFFSET", offset);
|
||||||
GenComment(field.doc_comment, "\t");
|
GenComment(field.doc_comment);
|
||||||
if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type)) {
|
if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type)) {
|
||||||
code_ +=
|
code_ +=
|
||||||
GenReaderMainBody() + "return " + GenReader("VALUETYPE") + " }";
|
GenReaderMainBody() + "return " + GenReader("VALUETYPE") + " }";
|
||||||
@@ -645,7 +707,9 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
GenConstructor("{{ACCESS}}.postion + {{OFFSET}}");
|
GenConstructor("{{ACCESS}}.postion + {{OFFSET}}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (parser_.opts.generate_object_based_api)
|
||||||
|
GenerateObjectAPIStructExtension(struct_def);
|
||||||
|
Outdent();
|
||||||
code_ += "}\n";
|
code_ += "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,26 +719,412 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_.SetValue("BASE_TYPE", GenTypeBasic(enum_def.underlying_type, false));
|
code_.SetValue("BASE_TYPE", GenTypeBasic(enum_def.underlying_type, false));
|
||||||
GenComment(enum_def.doc_comment);
|
GenComment(enum_def.doc_comment);
|
||||||
code_ += "public enum {{ENUM_NAME}}: {{BASE_TYPE}}, Enum { ";
|
code_ += "public enum {{ENUM_NAME}}: {{BASE_TYPE}}, Enum { ";
|
||||||
code_ += "\tpublic typealias T = {{BASE_TYPE}}";
|
Indent();
|
||||||
|
code_ += "public typealias T = {{BASE_TYPE}}";
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tpublic static var byteSize: Int { return "
|
"public static var byteSize: Int { return "
|
||||||
"MemoryLayout<{{BASE_TYPE}}>.size "
|
"MemoryLayout<{{BASE_TYPE}}>.size "
|
||||||
"}";
|
"}";
|
||||||
code_ += "\tpublic var value: {{BASE_TYPE}} { return self.rawValue }";
|
code_ += "public var value: {{BASE_TYPE}} { return self.rawValue }";
|
||||||
|
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||||
const auto &ev = **it;
|
const auto &ev = **it;
|
||||||
auto name = Name(ev);
|
auto name = Name(ev);
|
||||||
std::transform(name.begin(), name.end(), name.begin(), LowerCase);
|
std::transform(name.begin(), name.end(), name.begin(), LowerCase);
|
||||||
code_.SetValue("KEY", name);
|
code_.SetValue("KEY", name);
|
||||||
code_.SetValue("VALUE", enum_def.ToString(ev));
|
code_.SetValue("VALUE", enum_def.ToString(ev));
|
||||||
GenComment(ev.doc_comment, "\t");
|
GenComment(ev.doc_comment);
|
||||||
code_ += "\tcase {{KEY}} = {{VALUE}}";
|
code_ += "case {{KEY}} = {{VALUE}}";
|
||||||
}
|
}
|
||||||
code_ += "\n";
|
code_ += "\n";
|
||||||
AddMinOrMaxEnumValue(enum_def.MaxValue()->name, "max");
|
AddMinOrMaxEnumValue(enum_def.MaxValue()->name, "max");
|
||||||
AddMinOrMaxEnumValue(enum_def.MinValue()->name, "min");
|
AddMinOrMaxEnumValue(enum_def.MinValue()->name, "min");
|
||||||
|
Outdent();
|
||||||
code_ += "}\n";
|
code_ += "}\n";
|
||||||
|
if (parser_.opts.generate_object_based_api && enum_def.is_union) {
|
||||||
|
code_ += "struct {{ENUM_NAME}}Union {";
|
||||||
|
Indent();
|
||||||
|
code_ += "var type: {{ENUM_NAME}}";
|
||||||
|
code_ += "var value: NativeTable?";
|
||||||
|
code_ += "init(_ v: NativeTable?, type: {{ENUM_NAME}}) {";
|
||||||
|
Indent();
|
||||||
|
code_ += "self.type = type";
|
||||||
|
code_ += "self.value = v";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
code_ +=
|
||||||
|
"func pack(builder: inout FlatBufferBuilder) -> Offset<UOffset> {";
|
||||||
|
Indent();
|
||||||
|
BuildUnionEnumSwitchCaseWritter(enum_def);
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenObjectAPI(const StructDef &struct_def) {
|
||||||
|
code_ += "public class {{STRUCTNAME}}T: NativeTable {\n";
|
||||||
|
std::vector<std::string> buffer_constructor;
|
||||||
|
std::vector<std::string> base_constructor;
|
||||||
|
Indent();
|
||||||
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
|
auto &field = **it;
|
||||||
|
if (field.deprecated) continue;
|
||||||
|
BuildObjectAPIConstructorBody(field, struct_def.fixed, buffer_constructor,
|
||||||
|
base_constructor);
|
||||||
|
}
|
||||||
|
code_ += "";
|
||||||
|
BuildObjectAPIConstructor(buffer_constructor,
|
||||||
|
"_ _t: inout " + struct_def.name);
|
||||||
|
BuildObjectAPIConstructor(base_constructor);
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateObjectAPITableExtension(const StructDef &struct_def) {
|
||||||
|
GenerateObjectAPIExtensionHeader();
|
||||||
|
std::vector<std::string> unpack_body;
|
||||||
|
std::string builder = ", &builder)";
|
||||||
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
|
auto &field = **it;
|
||||||
|
if (field.deprecated) continue;
|
||||||
|
auto name = Name(field);
|
||||||
|
auto type = GenType(field.value.type);
|
||||||
|
std::string check_if_vector =
|
||||||
|
(field.value.type.base_type == BASE_TYPE_VECTOR ||
|
||||||
|
field.value.type.base_type == BASE_TYPE_ARRAY)
|
||||||
|
? "VectorOf("
|
||||||
|
: "(";
|
||||||
|
std::string body = "add" + check_if_vector + name + ": ";
|
||||||
|
switch (field.value.type.base_type) {
|
||||||
|
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();
|
||||||
|
case BASE_TYPE_VECTOR: {
|
||||||
|
GenerateVectorObjectAPITableExtension(field, name, type);
|
||||||
|
unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + name +
|
||||||
|
builder);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_UNION: {
|
||||||
|
code_ += "let __" + name + " = obj." + name +
|
||||||
|
"?.pack(builder: &builder) ?? Offset()";
|
||||||
|
unpack_body.push_back("if let o = obj." + name + "?.type {");
|
||||||
|
unpack_body.push_back(" {{STRUCTNAME}}.add(" + name + "Type: o" +
|
||||||
|
builder);
|
||||||
|
unpack_body.push_back(" {{STRUCTNAME}}." + body + "__" + name +
|
||||||
|
builder);
|
||||||
|
unpack_body.push_back("}\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_STRUCT: {
|
||||||
|
if (field.value.type.struct_def &&
|
||||||
|
field.value.type.struct_def->fixed) {
|
||||||
|
std::string struct_builder =
|
||||||
|
type + ".pack(&builder, obj: &obj." + name + ")";
|
||||||
|
unpack_body.push_back("{{STRUCTNAME}}." + body + struct_builder +
|
||||||
|
builder);
|
||||||
|
} else {
|
||||||
|
unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + name +
|
||||||
|
builder);
|
||||||
|
code_ += "let __" + name + " = " + type +
|
||||||
|
".pack(&builder, obj: &obj." + name + ")";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_STRING: {
|
||||||
|
unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + name +
|
||||||
|
builder);
|
||||||
|
BuildingOptionalObjects(name, "String", "builder.create(string: s)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_UTYPE: break;
|
||||||
|
default:
|
||||||
|
unpack_body.push_back("{{STRUCTNAME}}." + body + "obj." + name +
|
||||||
|
builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code_ += "let __root = {{STRUCTNAME}}.start{{STRUCTNAME}}(&builder)";
|
||||||
|
for (auto it = unpack_body.begin(); it < unpack_body.end(); it++)
|
||||||
|
code_ += *it;
|
||||||
|
code_ +=
|
||||||
|
"return {{STRUCTNAME}}.end{{STRUCTNAME}}(&builder, start: "
|
||||||
|
"__root)";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateVectorObjectAPITableExtension(const FieldDef &field,
|
||||||
|
const std::string &name,
|
||||||
|
const std::string &type) {
|
||||||
|
auto vectortype = field.value.type.VectorType();
|
||||||
|
switch (vectortype.base_type) {
|
||||||
|
case BASE_TYPE_UNION: {
|
||||||
|
code_ += "var __" + name + "__: [Offset<UOffset>] = []";
|
||||||
|
code_ += "for i in obj." + name + " {";
|
||||||
|
Indent();
|
||||||
|
code_ += "guard let off = i?.pack(builder: &builder) else { continue }";
|
||||||
|
code_ += "__" + name + "__.append(off)";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
code_ += "let __" + name + " = builder.createVector(ofOffsets: __" +
|
||||||
|
name + "__)";
|
||||||
|
code_ += "let __" + name + "Type = builder.createVector(obj." + name +
|
||||||
|
".compactMap { $0?.type })";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_UTYPE: break;
|
||||||
|
case BASE_TYPE_STRUCT: {
|
||||||
|
if (field.value.type.struct_def &&
|
||||||
|
!field.value.type.struct_def->fixed) {
|
||||||
|
code_ += "var __" + name + "__: [Offset<UOffset>] = []";
|
||||||
|
code_ += "for var i in obj." + name + " {";
|
||||||
|
Indent();
|
||||||
|
code_ +=
|
||||||
|
"__" + name + "__.append(" + type + ".pack(&builder, obj: &i))";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
code_ += "let __" + name + " = builder.createVector(ofOffsets: __" +
|
||||||
|
name + "__)";
|
||||||
|
} else {
|
||||||
|
code_ += "var __" + name + "__: [UnsafeMutableRawPointer] = []";
|
||||||
|
std::string code;
|
||||||
|
GenerateStructArgs(*field.value.type.struct_def, &code, "", "", "_o",
|
||||||
|
true);
|
||||||
|
code = code.substr(0, code.size() - 2);
|
||||||
|
code_ += "for i in obj." + name + " {";
|
||||||
|
Indent();
|
||||||
|
code_ += "guard let _o = i else { continue }";
|
||||||
|
code_ += "__" + name + "__.append(create" +
|
||||||
|
field.value.type.struct_def->name + "(" + code + "))";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
code_ += "let __" + name + " = builder.createVector(structs: __" +
|
||||||
|
name + "__, type: " + type + ".self)";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_STRING: {
|
||||||
|
code_ += "let __" + name + " = builder.createVector(ofStrings: obj." +
|
||||||
|
name + ".compactMap({ $0 }) )";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
code_ += "let __" + name + " = builder.createVector(obj." + name + ")";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildingOptionalObjects(const std::string &name,
|
||||||
|
const std::string &object_type,
|
||||||
|
const std::string &body_front) {
|
||||||
|
code_ += "let __" + name + ": Offset<" + object_type + ">";
|
||||||
|
code_ += "if let s = obj." + name + " {";
|
||||||
|
Indent();
|
||||||
|
code_ += "__" + name + " = " + body_front;
|
||||||
|
Outdent();
|
||||||
|
code_ += "} else {";
|
||||||
|
Indent();
|
||||||
|
code_ += "__" + name + " = Offset<" + object_type + ">()";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
code_ += "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildObjectAPIConstructor(const std::vector<std::string> &body,
|
||||||
|
const std::string &header = "") {
|
||||||
|
code_.SetValue("HEADER", header);
|
||||||
|
code_ += "init({{HEADER}}) {";
|
||||||
|
Indent();
|
||||||
|
for (auto it = body.begin(); it < body.end(); ++it) code_ += *it;
|
||||||
|
Outdent();
|
||||||
|
code_ += "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildObjectAPIConstructorBody(
|
||||||
|
const FieldDef &field, bool is_fixed,
|
||||||
|
std::vector<std::string> &buffer_constructor,
|
||||||
|
std::vector<std::string> &base_constructor) {
|
||||||
|
auto name = Name(field);
|
||||||
|
auto type = GenType(field.value.type);
|
||||||
|
code_.SetValue("VALUENAME", name);
|
||||||
|
code_.SetValue("VALUETYPE", type);
|
||||||
|
|
||||||
|
switch (field.value.type.base_type) {
|
||||||
|
case BASE_TYPE_STRUCT: {
|
||||||
|
code_.SetValue("VALUETYPE", type + "T");
|
||||||
|
buffer_constructor.push_back("var __" + name + " = _t." + name);
|
||||||
|
auto optional =
|
||||||
|
(field.value.type.struct_def && field.value.type.struct_def->fixed);
|
||||||
|
std::string question_mark = (optional && is_fixed ? "" : "?");
|
||||||
|
code_ += "var {{VALUENAME}}: {{VALUETYPE}}" + question_mark;
|
||||||
|
buffer_constructor.push_back("" + name + " = __" + name +
|
||||||
|
question_mark + ".unpack()");
|
||||||
|
base_constructor.push_back("" + name + " = " + type + "T()");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();
|
||||||
|
case BASE_TYPE_VECTOR: {
|
||||||
|
BuildObjectAPIConstructorBodyVectors(field, name, buffer_constructor,
|
||||||
|
base_constructor, " ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_STRING: {
|
||||||
|
code_ += "var {{VALUENAME}}: String?";
|
||||||
|
buffer_constructor.push_back(name + " = _t." + name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_UTYPE: break;
|
||||||
|
case BASE_TYPE_UNION: {
|
||||||
|
BuildUnionEnumSwitchCase(*field.value.type.enum_def, name,
|
||||||
|
buffer_constructor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
buffer_constructor.push_back(name + " = _t." + name);
|
||||||
|
|
||||||
|
if (IsScalar(field.value.type.base_type) &&
|
||||||
|
!IsBool(field.value.type.base_type) && !IsEnum(field.value.type)) {
|
||||||
|
code_ += "var {{VALUENAME}}: {{VALUETYPE}}";
|
||||||
|
base_constructor.push_back(name + " = " + field.value.constant);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsEnum(field.value.type)) {
|
||||||
|
auto default_value = IsEnum(field.value.type)
|
||||||
|
? GenEnumDefaultValue(field)
|
||||||
|
: field.value.constant;
|
||||||
|
code_ += "var {{VALUENAME}}: {{VALUETYPE}}";
|
||||||
|
base_constructor.push_back(name + " = " + default_value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsBool(field.value.type.base_type)) {
|
||||||
|
code_ += "var {{VALUENAME}}: Bool";
|
||||||
|
std::string default_value =
|
||||||
|
"0" == field.value.constant ? "false" : "true";
|
||||||
|
base_constructor.push_back(name + " = " + default_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildObjectAPIConstructorBodyVectors(
|
||||||
|
const FieldDef &field, const std::string &name,
|
||||||
|
std::vector<std::string> &buffer_constructor,
|
||||||
|
std::vector<std::string> &base_constructor,
|
||||||
|
const std::string &indentation) {
|
||||||
|
auto vectortype = field.value.type.VectorType();
|
||||||
|
|
||||||
|
if (vectortype.base_type != BASE_TYPE_UTYPE) {
|
||||||
|
buffer_constructor.push_back(name + " = []");
|
||||||
|
buffer_constructor.push_back("for index in 0..<_t." + name + "Count {");
|
||||||
|
base_constructor.push_back(name + " = []");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (vectortype.base_type) {
|
||||||
|
case BASE_TYPE_STRUCT: {
|
||||||
|
code_.SetValue("VALUETYPE", GenType(vectortype) + "T");
|
||||||
|
code_ += "var {{VALUENAME}}: [{{VALUETYPE}}?]";
|
||||||
|
buffer_constructor.push_back(indentation + "var __v_ = _t." + name +
|
||||||
|
"(at: index)");
|
||||||
|
buffer_constructor.push_back(indentation + name +
|
||||||
|
".append(__v_?.unpack())");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();
|
||||||
|
case BASE_TYPE_VECTOR: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_UNION: {
|
||||||
|
BuildUnionEnumSwitchCase(*field.value.type.enum_def, name,
|
||||||
|
buffer_constructor, indentation, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_UTYPE: break;
|
||||||
|
default: {
|
||||||
|
code_.SetValue("VALUETYPE", (vectortype.base_type == BASE_TYPE_STRING
|
||||||
|
? "String?"
|
||||||
|
: GenType(vectortype)));
|
||||||
|
code_ += "var {{VALUENAME}}: [{{VALUETYPE}}]";
|
||||||
|
|
||||||
|
if (IsEnum(vectortype) && vectortype.base_type != BASE_TYPE_UNION) {
|
||||||
|
auto default_value = IsEnum(field.value.type)
|
||||||
|
? GenEnumDefaultValue(field)
|
||||||
|
: field.value.constant;
|
||||||
|
buffer_constructor.push_back(indentation + name + ".append(_t." +
|
||||||
|
name + "(at: index)!)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buffer_constructor.push_back(indentation + name + ".append(_t." + name +
|
||||||
|
"(at: index))");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vectortype.base_type != BASE_TYPE_UTYPE)
|
||||||
|
buffer_constructor.push_back("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildUnionEnumSwitchCaseWritter(const EnumDef &ev) {
|
||||||
|
auto field_name = EscapeKeyword(ev.name);
|
||||||
|
code_.SetValue("VALUETYPE", field_name);
|
||||||
|
code_ += "switch type {";
|
||||||
|
for (auto it = ev.Vals().begin(); it < ev.Vals().end(); ++it) {
|
||||||
|
auto field = **it;
|
||||||
|
auto ev_name = Name(field);
|
||||||
|
auto type = GenType(field.union_type);
|
||||||
|
std::transform(ev_name.begin(), ev_name.end(), ev_name.begin(),
|
||||||
|
LowerCase);
|
||||||
|
if (field.union_type.base_type == BASE_TYPE_NONE ||
|
||||||
|
field.union_type.base_type == BASE_TYPE_STRING) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
code_ += "case ." + ev_name + ":";
|
||||||
|
Indent();
|
||||||
|
code_ += "var __obj = value as? " + type + "T";
|
||||||
|
code_ += "return " + type + ".pack(&builder, obj: &__obj)";
|
||||||
|
Outdent();
|
||||||
|
}
|
||||||
|
code_ += "default: return Offset()";
|
||||||
|
code_ += "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildUnionEnumSwitchCase(const EnumDef &ev, const std::string &name,
|
||||||
|
std::vector<std::string> &buffer_constructor,
|
||||||
|
const std::string &indentation = "",
|
||||||
|
const bool is_vector = false) {
|
||||||
|
auto field_name = EscapeKeyword(ev.name);
|
||||||
|
code_.SetValue("VALUETYPE", field_name);
|
||||||
|
code_ += "var {{VALUENAME}}: \\";
|
||||||
|
code_ += is_vector ? "[{{VALUETYPE}}Union?]" : "{{VALUETYPE}}Union?";
|
||||||
|
|
||||||
|
auto vector_reader = is_vector ? "(at: index" : "";
|
||||||
|
buffer_constructor.push_back(indentation + "switch _t." + name + "Type" +
|
||||||
|
vector_reader + (is_vector ? ")" : "") + " {");
|
||||||
|
|
||||||
|
for (auto it = ev.Vals().begin(); it < ev.Vals().end(); ++it) {
|
||||||
|
auto field = **it;
|
||||||
|
auto ev_name = Name(field);
|
||||||
|
std::transform(ev_name.begin(), ev_name.end(), ev_name.begin(),
|
||||||
|
LowerCase);
|
||||||
|
if (field.union_type.base_type == BASE_TYPE_NONE ||
|
||||||
|
field.union_type.base_type == BASE_TYPE_STRING) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
buffer_constructor.push_back(indentation + "case ." + ev_name + ":");
|
||||||
|
buffer_constructor.push_back(
|
||||||
|
indentation + " var _v = _t." + name + (is_vector ? "" : "(") +
|
||||||
|
vector_reader + (is_vector ? ", " : "") +
|
||||||
|
"type: " + GenType(field.union_type) + ".self)");
|
||||||
|
auto constructor =
|
||||||
|
field_name + "Union(_v?.unpack(), type: ." + ev_name + ")";
|
||||||
|
buffer_constructor.push_back(
|
||||||
|
indentation + " " + name +
|
||||||
|
(is_vector ? ".append(" + constructor + ")" : " = " + constructor));
|
||||||
|
}
|
||||||
|
buffer_constructor.push_back(indentation + "default: break");
|
||||||
|
buffer_constructor.push_back(indentation + "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddMinOrMaxEnumValue(const std::string &str, const std::string &type) {
|
void AddMinOrMaxEnumValue(const std::string &str, const std::string &type) {
|
||||||
@@ -682,67 +1132,72 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
std::transform(current_value.begin(), current_value.end(),
|
std::transform(current_value.begin(), current_value.end(),
|
||||||
current_value.begin(), LowerCase);
|
current_value.begin(), LowerCase);
|
||||||
code_.SetValue(type, current_value);
|
code_.SetValue(type, current_value);
|
||||||
code_ += "\tpublic static var " + type + ": {{ENUM_NAME}} { return .{{" +
|
code_ += "public static var " + type + ": {{ENUM_NAME}} { return .{{" +
|
||||||
type + "}} }";
|
type + "}} }";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenLookup(const FieldDef &key_field) {
|
void GenLookup(const FieldDef &key_field) {
|
||||||
code_.SetValue("OFFSET", NumToString(key_field.value.offset));
|
code_.SetValue("OFFSET", NumToString(key_field.value.offset));
|
||||||
auto offset_reader =
|
std::string offset_reader =
|
||||||
"Table.offset(Int32(fbb.capacity) - tableOffset, vOffset: {{OFFSET}}, "
|
"Table.offset(Int32(fbb.capacity) - tableOffset, vOffset: {{OFFSET}}, "
|
||||||
"fbb: fbb)";
|
"fbb: fbb)";
|
||||||
std::string spacing = "\t\t";
|
|
||||||
std::string double_spacing = spacing + "\t";
|
|
||||||
|
|
||||||
code_.SetValue("TYPE", GenType(key_field.value.type));
|
code_.SetValue("TYPE", GenType(key_field.value.type));
|
||||||
code_ +=
|
code_ +=
|
||||||
"\tfileprivate static func lookupByKey(vector: Int32, key: {{TYPE}}, "
|
"fileprivate static func lookupByKey(vector: Int32, key: {{TYPE}}, "
|
||||||
"fbb: "
|
"fbb: "
|
||||||
"ByteBuffer) -> {{VALUENAME}}? {";
|
"ByteBuffer) -> {{VALUENAME}}? {";
|
||||||
|
Indent();
|
||||||
if (key_field.value.type.base_type == BASE_TYPE_STRING)
|
if (key_field.value.type.base_type == BASE_TYPE_STRING)
|
||||||
code_ += spacing + "let key = key.utf8.map { $0 }";
|
code_ += "let key = key.utf8.map { $0 }";
|
||||||
code_ += spacing +
|
code_ += "var span = fbb.read(def: Int32.self, position: Int(vector - 4))";
|
||||||
"var span = fbb.read(def: Int32.self, position: Int(vector - 4))";
|
code_ += "var start: Int32 = 0";
|
||||||
code_ += spacing + "var start: Int32 = 0";
|
code_ += "while span != 0 {";
|
||||||
code_ += spacing + "while span != 0 {";
|
Indent();
|
||||||
code_ += double_spacing + "var middle = span / 2";
|
code_ += "var middle = span / 2";
|
||||||
code_ +=
|
code_ +=
|
||||||
double_spacing +
|
|
||||||
"let tableOffset = Table.indirect(vector + 4 * (start + middle), fbb)";
|
"let tableOffset = Table.indirect(vector + 4 * (start + middle), fbb)";
|
||||||
if (key_field.value.type.base_type == BASE_TYPE_STRING) {
|
if (key_field.value.type.base_type == BASE_TYPE_STRING) {
|
||||||
code_ += double_spacing + "let comp = Table.compare(" + offset_reader +
|
code_ += "let comp = Table.compare(" + offset_reader + ", key, fbb: fbb)";
|
||||||
", key, fbb: fbb)";
|
|
||||||
} else {
|
} else {
|
||||||
code_ += double_spacing +
|
code_ += "let comp = fbb.read(def: {{TYPE}}.self, position: Int(" +
|
||||||
"let comp = fbb.read(def: {{TYPE}}.self, position: Int(" +
|
|
||||||
offset_reader + "))";
|
offset_reader + "))";
|
||||||
}
|
}
|
||||||
|
|
||||||
code_ += double_spacing + "if comp > 0 {";
|
code_ += "if comp > 0 {";
|
||||||
code_ += double_spacing + "\tspan = middle";
|
Indent();
|
||||||
code_ += double_spacing + "} else if comp < 0 {";
|
code_ += "span = middle";
|
||||||
code_ += double_spacing + "\tmiddle += 1";
|
Outdent();
|
||||||
code_ += double_spacing + "\tstart += middle";
|
code_ += "} else if comp < 0 {";
|
||||||
code_ += double_spacing + "\tspan -= middle";
|
Indent();
|
||||||
code_ += double_spacing + "} else {";
|
code_ += "middle += 1";
|
||||||
code_ += double_spacing + "\treturn {{VALUENAME}}(fbb, o: tableOffset)";
|
code_ += "start += middle";
|
||||||
code_ += double_spacing + "}";
|
code_ += "span -= middle";
|
||||||
code_ += spacing + "}";
|
Outdent();
|
||||||
code_ += spacing + "return nil";
|
code_ += "} else {";
|
||||||
code_ += "\t}";
|
Indent();
|
||||||
|
code_ += "return {{VALUENAME}}(fbb, o: tableOffset)";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
|
code_ += "return nil";
|
||||||
|
Outdent();
|
||||||
|
code_ += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenComment(const std::vector<std::string> &dc, const char *prefix = "") {
|
void GenComment(const std::vector<std::string> &dc) {
|
||||||
std::string text;
|
if (dc.begin() == dc.end()) {
|
||||||
::flatbuffers::GenComment(dc, &text, nullptr, prefix);
|
// Don't output empty comment blocks with 0 lines of comment content.
|
||||||
code_ += text + "\\";
|
return;
|
||||||
|
}
|
||||||
|
for (auto it = dc.begin(); it != dc.end(); ++it) { code_ += "/// " + *it; }
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenOffset() { return "let o = {{ACCESS}}.offset({{OFFSET}}); "; }
|
std::string GenOffset() { return "let o = {{ACCESS}}.offset({{OFFSET}}); "; }
|
||||||
|
|
||||||
std::string GenReaderMainBody(const std::string &optional = "") {
|
std::string GenReaderMainBody(const std::string &optional = "") {
|
||||||
return "\tpublic var {{VALUENAME}}: {{VALUETYPE}}" + optional + " { ";
|
return "public var {{VALUENAME}}: {{VALUETYPE}}" + optional + " { ";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenReader(const std::string &type,
|
std::string GenReader(const std::string &type,
|
||||||
@@ -756,13 +1211,13 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
std::string GenMutate(const std::string &offset,
|
std::string GenMutate(const std::string &offset,
|
||||||
const std::string &get_offset, bool isRaw = false) {
|
const std::string &get_offset, bool isRaw = false) {
|
||||||
return "\tpublic func mutate({{VALUENAME}}: {{VALUETYPE}}) -> Bool {" +
|
return "public func mutate({{VALUENAME}}: {{VALUETYPE}}) -> Bool {" +
|
||||||
get_offset + " return {{ACCESS}}.mutate({{VALUENAME}}" +
|
get_offset + " return {{ACCESS}}.mutate({{VALUENAME}}" +
|
||||||
(isRaw ? ".rawValue" : "") + ", index: " + offset + ") }";
|
(isRaw ? ".rawValue" : "") + ", index: " + offset + ") }";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenMutateArray() {
|
std::string GenMutateArray() {
|
||||||
return "\tpublic func mutate({{VALUENAME}}: {{VALUETYPE}}, at index: "
|
return "public func mutate({{VALUENAME}}: {{VALUETYPE}}, at index: "
|
||||||
"Int32) -> Bool { " +
|
"Int32) -> Bool { " +
|
||||||
GenOffset() +
|
GenOffset() +
|
||||||
"return {{ACCESS}}.directMutate({{VALUENAME}}, index: "
|
"return {{ACCESS}}.directMutate({{VALUENAME}}, index: "
|
||||||
@@ -790,7 +1245,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string ValidateFunc() {
|
std::string ValidateFunc() {
|
||||||
return "\tstatic func validateVersion() { FlatBuffersVersion_1_12_0() }";
|
return "static func validateVersion() { FlatBuffersVersion_1_12_0() }";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenType(const Type &type) const {
|
std::string GenType(const Type &type) const {
|
||||||
@@ -814,6 +1269,10 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
return GenTypeBasic(type, true);
|
return GenTypeBasic(type, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Indent() { code_.IncrementIdentLevel(); }
|
||||||
|
|
||||||
|
void Outdent() { code_.DecrementIdentLevel(); }
|
||||||
|
|
||||||
std::string GenTypeBasic(const Type &type, bool can_override) const {
|
std::string GenTypeBasic(const Type &type, bool can_override) const {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const char * const swift_type[] = {
|
static const char * const swift_type[] = {
|
||||||
@@ -863,7 +1322,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
// Close cur_name_space in reverse order to reach the common prefix.
|
// Close cur_name_space in reverse order to reach the common prefix.
|
||||||
// In the previous example, D then C are closed.
|
// In the previous example, D then C are closed.
|
||||||
for (size_t j = old_size; j > common_prefix_size; --j) {
|
for (size_t j = old_size; j > common_prefix_size; --j) {
|
||||||
if (namespace_depth != 0) {
|
if (namespace_depth >= 0) {
|
||||||
code_ += "}";
|
code_ += "}";
|
||||||
namespace_depth -= 1;
|
namespace_depth -= 1;
|
||||||
}
|
}
|
||||||
@@ -881,7 +1340,10 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
namespace_depth += 1;
|
namespace_depth += 1;
|
||||||
namespaces_.insert(name);
|
namespaces_.insert(name);
|
||||||
} else {
|
} else {
|
||||||
code_ += "}";
|
if (namespace_depth != 0) {
|
||||||
|
code_ += "}";
|
||||||
|
namespace_depth = 0;
|
||||||
|
}
|
||||||
is_extension = true;
|
is_extension = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,16 @@ public struct ByteBuffer {
|
|||||||
push(value: s, len: MemoryLayout.size(ofValue: s))
|
push(value: s, len: MemoryLayout.size(ofValue: s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Adds an array of type Bool to the buffer memory
|
||||||
|
/// - Parameter elements: An array of Bool
|
||||||
|
@usableFromInline mutating func push(elements: [Bool]) {
|
||||||
|
let size = elements.count * MemoryLayout<Bool>.size
|
||||||
|
ensureSpace(size: UInt32(size))
|
||||||
|
elements.lazy.reversed().forEach { (s) in
|
||||||
|
push(value: s ? 1 : 0, len: MemoryLayout.size(ofValue: s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A custom type of structs that are padded according to the flatbuffer padding,
|
/// A custom type of structs that are padded according to the flatbuffer padding,
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
@@ -174,8 +184,6 @@ public struct ByteBuffer {
|
|||||||
/// - len: Size of string
|
/// - len: Size of string
|
||||||
@usableFromInline mutating internal func push(bytes: UnsafeBufferPointer<String.UTF8View.Element>, len: Int) -> Bool {
|
@usableFromInline mutating internal func push(bytes: UnsafeBufferPointer<String.UTF8View.Element>, len: Int) -> Bool {
|
||||||
memcpy(_storage.memory.advanced(by: writerIndex - len), UnsafeRawPointer(bytes.baseAddress!), len)
|
memcpy(_storage.memory.advanced(by: writerIndex - len), UnsafeRawPointer(bytes.baseAddress!), len)
|
||||||
// _memory.advanced(by: writerIndex - len).copyMemory(from:
|
|
||||||
// UnsafeRawPointer(bytes.baseAddress!), byteCount: len)
|
|
||||||
_writerSize += len
|
_writerSize += len
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public struct FlatBufferBuilder {
|
|||||||
/// Returns A sized Buffer from the readable bytes
|
/// Returns A sized Buffer from the readable bytes
|
||||||
public var sizedBuffer: ByteBuffer {
|
public var sizedBuffer: ByteBuffer {
|
||||||
assert(finished, "Data shouldn't be called before finish()")
|
assert(finished, "Data shouldn't be called before finish()")
|
||||||
return ByteBuffer(memory: _bb.memory.advanced(by: _bb.reader), count: _bb.reader)
|
return ByteBuffer(memory: _bb.memory.advanced(by: _bb.reader), count: Int(_bb.size))
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Init
|
// MARK: - Init
|
||||||
@@ -276,6 +276,24 @@ public struct FlatBufferBuilder {
|
|||||||
return push(element: Int32(len))
|
return push(element: Int32(len))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a vector of type Bool in the buffer
|
||||||
|
/// - Parameter elements: elements to be written into the buffer
|
||||||
|
/// - returns: Offset of the vector
|
||||||
|
mutating public func createVector(_ elements: [Bool]) -> Offset<UOffset> {
|
||||||
|
return createVector(elements, size: elements.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a vector of type Bool in the buffer
|
||||||
|
/// - Parameter elements: Elements to be written into the buffer
|
||||||
|
/// - Parameter size: Count of elements
|
||||||
|
/// - returns: Offset of the vector
|
||||||
|
mutating public func createVector(_ elements: [Bool], size: Int) -> Offset<UOffset> {
|
||||||
|
let size = size
|
||||||
|
startVector(size, elementSize: MemoryLayout<Bool>.size)
|
||||||
|
_bb.push(elements: elements)
|
||||||
|
return Offset(offset: endVector(len: size))
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a vector of type Scalar in the buffer
|
/// Creates a vector of type Scalar in the buffer
|
||||||
/// - Parameter elements: elements to be written into the buffer
|
/// - Parameter elements: elements to be written into the buffer
|
||||||
/// - returns: Offset of the vector
|
/// - returns: Offset of the vector
|
||||||
|
|||||||
@@ -6,6 +6,14 @@ public protocol FlatBufferObject {
|
|||||||
init(_ bb: ByteBuffer, o: Int32)
|
init(_ bb: ByteBuffer, o: Int32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public protocol NativeTable {}
|
||||||
|
|
||||||
|
public protocol ObjectAPI {
|
||||||
|
associatedtype T
|
||||||
|
static func pack(_ builder: inout FlatBufferBuilder, obj: inout T) -> Offset<UOffset>
|
||||||
|
mutating func unpack() -> T
|
||||||
|
}
|
||||||
|
|
||||||
/// Readable is structures all the Flatbuffers structs
|
/// Readable is structures all the Flatbuffers structs
|
||||||
///
|
///
|
||||||
/// Readable is a procotol that each Flatbuffer struct should confirm to since
|
/// Readable is a procotol that each Flatbuffer struct should confirm to since
|
||||||
|
|||||||
@@ -4,77 +4,77 @@ import FlatBuffers
|
|||||||
|
|
||||||
public struct HelloReply: FlatBufferObject {
|
public struct HelloReply: FlatBufferObject {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
|
private var _accessor: Table
|
||||||
|
|
||||||
private var _accessor: Table
|
public static func getRootAsHelloReply(bb: ByteBuffer) -> HelloReply { return HelloReply(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
|
||||||
public static func getRootAsHelloReply(bb: ByteBuffer) -> HelloReply { return HelloReply(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
|
|
||||||
|
|
||||||
private init(_ t: Table) { _accessor = t }
|
private init(_ t: Table) { _accessor = t }
|
||||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||||
|
|
||||||
public var message: String? { let o = _accessor.offset(4); return o == 0 ? nil : _accessor.string(at: o) }
|
public var message: String? { let o = _accessor.offset(4); return o == 0 ? nil : _accessor.string(at: o) }
|
||||||
public var messageSegmentArray: [UInt8]? { return _accessor.getVector(at: 4) }
|
public var messageSegmentArray: [UInt8]? { return _accessor.getVector(at: 4) }
|
||||||
public static func startHelloReply(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
public static func startHelloReply(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
||||||
public static func add(message: Offset<String>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: message, at: 0) }
|
public static func add(message: Offset<String>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: message, at: 0) }
|
||||||
public static func endHelloReply(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
|
public static func endHelloReply(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
|
||||||
public static func createHelloReply(_ fbb: inout FlatBufferBuilder,
|
public static func createHelloReply(_ fbb: inout FlatBufferBuilder,
|
||||||
offsetOfMessage message: Offset<String> = Offset()) -> Offset<UOffset> {
|
offsetOfMessage message: Offset<String> = Offset()) -> Offset<UOffset> {
|
||||||
let __start = HelloReply.startHelloReply(&fbb)
|
let __start = HelloReply.startHelloReply(&fbb)
|
||||||
HelloReply.add(message: message, &fbb)
|
HelloReply.add(message: message, &fbb)
|
||||||
return HelloReply.endHelloReply(&fbb, start: __start)
|
return HelloReply.endHelloReply(&fbb, start: __start)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct HelloRequest: FlatBufferObject {
|
public struct HelloRequest: FlatBufferObject {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
|
private var _accessor: Table
|
||||||
|
|
||||||
private var _accessor: Table
|
public static func getRootAsHelloRequest(bb: ByteBuffer) -> HelloRequest { return HelloRequest(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
|
||||||
public static func getRootAsHelloRequest(bb: ByteBuffer) -> HelloRequest { return HelloRequest(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
|
|
||||||
|
|
||||||
private init(_ t: Table) { _accessor = t }
|
private init(_ t: Table) { _accessor = t }
|
||||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||||
|
|
||||||
public var name: String? { let o = _accessor.offset(4); return o == 0 ? nil : _accessor.string(at: o) }
|
public var name: String? { let o = _accessor.offset(4); return o == 0 ? nil : _accessor.string(at: o) }
|
||||||
public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: 4) }
|
public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: 4) }
|
||||||
public static func startHelloRequest(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
public static func startHelloRequest(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
||||||
public static func add(name: Offset<String>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: 0) }
|
public static func add(name: Offset<String>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: 0) }
|
||||||
public static func endHelloRequest(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
|
public static func endHelloRequest(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
|
||||||
public static func createHelloRequest(_ fbb: inout FlatBufferBuilder,
|
public static func createHelloRequest(_ fbb: inout FlatBufferBuilder,
|
||||||
offsetOfName name: Offset<String> = Offset()) -> Offset<UOffset> {
|
offsetOfName name: Offset<String> = Offset()) -> Offset<UOffset> {
|
||||||
let __start = HelloRequest.startHelloRequest(&fbb)
|
let __start = HelloRequest.startHelloRequest(&fbb)
|
||||||
HelloRequest.add(name: name, &fbb)
|
HelloRequest.add(name: name, &fbb)
|
||||||
return HelloRequest.endHelloRequest(&fbb, start: __start)
|
return HelloRequest.endHelloRequest(&fbb, start: __start)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ManyHellosRequest: FlatBufferObject {
|
public struct ManyHellosRequest: FlatBufferObject {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
|
private var _accessor: Table
|
||||||
|
|
||||||
private var _accessor: Table
|
public static func getRootAsManyHellosRequest(bb: ByteBuffer) -> ManyHellosRequest { return ManyHellosRequest(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
|
||||||
public static func getRootAsManyHellosRequest(bb: ByteBuffer) -> ManyHellosRequest { return ManyHellosRequest(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
|
|
||||||
|
|
||||||
private init(_ t: Table) { _accessor = t }
|
private init(_ t: Table) { _accessor = t }
|
||||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||||
|
|
||||||
public var name: String? { let o = _accessor.offset(4); return o == 0 ? nil : _accessor.string(at: o) }
|
public var name: String? { let o = _accessor.offset(4); return o == 0 ? nil : _accessor.string(at: o) }
|
||||||
public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: 4) }
|
public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: 4) }
|
||||||
public var numGreetings: Int32 { let o = _accessor.offset(6); return o == 0 ? 0 : _accessor.readBuffer(of: Int32.self, at: o) }
|
public var numGreetings: Int32 { let o = _accessor.offset(6); return o == 0 ? 0 : _accessor.readBuffer(of: Int32.self, at: o) }
|
||||||
public static func startManyHellosRequest(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 2) }
|
public static func startManyHellosRequest(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 2) }
|
||||||
public static func add(name: Offset<String>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: 0) }
|
public static func add(name: Offset<String>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: 0) }
|
||||||
public static func add(numGreetings: Int32, _ fbb: inout FlatBufferBuilder) { fbb.add(element: numGreetings, def: 0, at: 1) }
|
public static func add(numGreetings: Int32, _ fbb: inout FlatBufferBuilder) { fbb.add(element: numGreetings, def: 0, at: 1) }
|
||||||
public static func endManyHellosRequest(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
|
public static func endManyHellosRequest(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
|
||||||
public static func createManyHellosRequest(_ fbb: inout FlatBufferBuilder,
|
public static func createManyHellosRequest(_ fbb: inout FlatBufferBuilder,
|
||||||
offsetOfName name: Offset<String> = Offset(),
|
offsetOfName name: Offset<String> = Offset(),
|
||||||
numGreetings: Int32 = 0) -> Offset<UOffset> {
|
numGreetings: Int32 = 0) -> Offset<UOffset> {
|
||||||
let __start = ManyHellosRequest.startManyHellosRequest(&fbb)
|
let __start = ManyHellosRequest.startManyHellosRequest(&fbb)
|
||||||
ManyHellosRequest.add(name: name, &fbb)
|
ManyHellosRequest.add(name: name, &fbb)
|
||||||
ManyHellosRequest.add(numGreetings: numGreetings, &fbb)
|
ManyHellosRequest.add(numGreetings: numGreetings, &fbb)
|
||||||
return ManyHellosRequest.endManyHellosRequest(&fbb, start: __start)
|
return ManyHellosRequest.endManyHellosRequest(&fbb, start: __start)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ let package = Package(
|
|||||||
.package(path: "../../swift/")
|
.package(path: "../../swift/")
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
|
.target(name: "SwiftFlatBuffers"),
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: "FlatBuffers.Test.SwiftTests",
|
name: "FlatBuffers.Test.SwiftTests",
|
||||||
dependencies: ["FlatBuffers"]),
|
dependencies: ["FlatBuffers"]),
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
import Foundation
|
||||||
|
print("Flatbuffers")
|
||||||
@@ -2,9 +2,9 @@ swift_dir=`pwd`
|
|||||||
cd ..
|
cd ..
|
||||||
test_dir=`pwd`
|
test_dir=`pwd`
|
||||||
|
|
||||||
${test_dir}/../flatc --swift --gen-mutable -I ${test_dir}/include_test ${test_dir}/monster_test.fbs ${test_dir}/union_vector/union_vector.fbs
|
${test_dir}/../flatc --swift --gen-mutable --gen-object-api -I ${test_dir}/include_test ${test_dir}/monster_test.fbs ${test_dir}/union_vector/union_vector.fbs
|
||||||
cd ${test_dir}
|
cd ${test_dir}
|
||||||
mv *_generated.swift ${swift_dir}/Tests/FlatBuffers.Test.SwiftTests
|
mv *_generated.swift ${swift_dir}/Tests/FlatBuffers.Test.SwiftTests
|
||||||
cd ${swift_dir}
|
cd ${swift_dir}
|
||||||
swift build --build-tests
|
swift build --build-tests
|
||||||
swift test
|
swift test
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
let _data = ByteBuffer(data: data)
|
let _data = ByteBuffer(data: data)
|
||||||
readMonster(fb: _data)
|
readMonster(fb: _data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testReadFromOtherLangagues() {
|
func testReadFromOtherLangagues() {
|
||||||
let path = FileManager.default.currentDirectoryPath
|
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")
|
||||||
@@ -29,21 +29,33 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
mutateMonster(fb: bytes.buffer)
|
mutateMonster(fb: bytes.buffer)
|
||||||
readMonster(fb: bytes.buffer)
|
readMonster(fb: bytes.buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateMonsterResizedBuffer() {
|
func testCreateMonsterResizedBuffer() {
|
||||||
let bytes = createMonster(withPrefix: false)
|
let bytes = createMonster(withPrefix: false)
|
||||||
XCTAssertEqual(bytes.sizedByteArray, [48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 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])
|
XCTAssertEqual(bytes.sizedByteArray, [48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 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])
|
||||||
readMonster(fb: ByteBuffer(data: bytes.data))
|
readMonster(fb: bytes.sizedBuffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateMonsterPrefixed() {
|
func testCreateMonsterPrefixed() {
|
||||||
let bytes = createMonster(withPrefix: true)
|
let bytes = createMonster(withPrefix: true)
|
||||||
XCTAssertEqual(bytes.sizedByteArray, [44, 1, 0, 0, 44, 0, 0, 0, 77, 79, 78, 83, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 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])
|
XCTAssertEqual(bytes.sizedByteArray, [44, 1, 0, 0, 44, 0, 0, 0, 77, 79, 78, 83, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 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])
|
||||||
|
|
||||||
let newBuf = FlatBuffersUtils.removeSizePrefix(bb: bytes.buffer)
|
let newBuf = FlatBuffersUtils.removeSizePrefix(bb: bytes.buffer)
|
||||||
readMonster(fb: newBuf)
|
readMonster(fb: newBuf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readMonster(fb: ByteBuffer) {
|
||||||
|
var monster = Monster1.getRootAsMonster(bb: fb)
|
||||||
|
readFlatbufferMonster(monster: &monster)
|
||||||
|
var unpacked: MyGame.Example.MonsterT? = monster.unpack()
|
||||||
|
readObjectApi(monster: unpacked!)
|
||||||
|
var builder = FlatBufferBuilder()
|
||||||
|
let root = Monster1.pack(&builder, obj: &unpacked)
|
||||||
|
builder.finish(offset: root)
|
||||||
|
var newMonster = Monster1.getRootAsMonster(bb: builder.sizedBuffer)
|
||||||
|
readFlatbufferMonster(monster: &newMonster)
|
||||||
|
}
|
||||||
|
|
||||||
func createMonster(withPrefix prefix: Bool) -> FlatBufferBuilder {
|
func createMonster(withPrefix prefix: Bool) -> FlatBufferBuilder {
|
||||||
var fbb = FlatBufferBuilder(initialSize: 1)
|
var fbb = FlatBufferBuilder(initialSize: 1)
|
||||||
let names = [fbb.create(string: "Frodo"), fbb.create(string: "Barney"), fbb.create(string: "Wilma")]
|
let names = [fbb.create(string: "Frodo"), fbb.create(string: "Barney"), fbb.create(string: "Wilma")]
|
||||||
@@ -57,15 +69,15 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
let start3 = Monster1.startMonster(&fbb)
|
let start3 = Monster1.startMonster(&fbb)
|
||||||
Monster1.add(name: names[2], &fbb)
|
Monster1.add(name: names[2], &fbb)
|
||||||
offsets.append(Monster1.endMonster(&fbb, start: start3))
|
offsets.append(Monster1.endMonster(&fbb, start: start3))
|
||||||
|
|
||||||
let sortedArray = Monster1.sortVectorOfMonster(offsets: offsets, &fbb)
|
let sortedArray = Monster1.sortVectorOfMonster(offsets: offsets, &fbb)
|
||||||
|
|
||||||
let str = fbb.create(string: "MyMonster")
|
let str = fbb.create(string: "MyMonster")
|
||||||
let test1 = fbb.create(string: "test1")
|
let test1 = fbb.create(string: "test1")
|
||||||
let test2 = fbb.create(string: "test2")
|
let test2 = fbb.create(string: "test2")
|
||||||
let _inv: [Byte] = [0, 1, 2, 3, 4]
|
let _inv: [Byte] = [0, 1, 2, 3, 4]
|
||||||
let inv = fbb.createVector(_inv)
|
let inv = fbb.createVector(_inv)
|
||||||
|
|
||||||
let fred = fbb.create(string: "Fred")
|
let fred = fbb.create(string: "Fred")
|
||||||
let mon1Start = Monster1.startMonster(&fbb)
|
let mon1Start = Monster1.startMonster(&fbb)
|
||||||
Monster1.add(name: fred, &fbb)
|
Monster1.add(name: fred, &fbb)
|
||||||
@@ -73,9 +85,9 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
let test4 = fbb.createVector(structs: [MyGame.Example.createTest(a: 30, b: 40),
|
let test4 = fbb.createVector(structs: [MyGame.Example.createTest(a: 30, b: 40),
|
||||||
MyGame.Example.createTest(a: 10, b: 20)],
|
MyGame.Example.createTest(a: 10, b: 20)],
|
||||||
type: Test1.self)
|
type: Test1.self)
|
||||||
|
|
||||||
let stringTestVector = fbb.createVector(ofOffsets: [test1, test2])
|
let stringTestVector = fbb.createVector(ofOffsets: [test1, test2])
|
||||||
|
|
||||||
let mStart = Monster1.startMonster(&fbb)
|
let mStart = Monster1.startMonster(&fbb)
|
||||||
let posOffset = fbb.create(struct: MyGame.Example.createVec3(x: 1, y: 2, z: 3, test1: 3, test2: .green, test3a: 5, test3b: 6), type: Vec3.self)
|
let posOffset = fbb.create(struct: MyGame.Example.createVec3(x: 1, y: 2, z: 3, test1: 3, test2: .green, test3a: 5, test3b: 6), type: Vec3.self)
|
||||||
Monster1.add(pos: posOffset, &fbb)
|
Monster1.add(pos: posOffset, &fbb)
|
||||||
@@ -92,37 +104,37 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
Monster1.finish(&fbb, end: end, prefix: prefix)
|
Monster1.finish(&fbb, end: end, prefix: prefix)
|
||||||
return fbb
|
return fbb
|
||||||
}
|
}
|
||||||
|
|
||||||
func mutateMonster(fb: ByteBuffer) {
|
func mutateMonster(fb: ByteBuffer) {
|
||||||
let monster = Monster1.getRootAsMonster(bb: fb)
|
let monster = Monster1.getRootAsMonster(bb: fb)
|
||||||
XCTAssertFalse(monster.mutate(mana: 10))
|
XCTAssertFalse(monster.mutate(mana: 10))
|
||||||
XCTAssertEqual(monster.testarrayoftables(at: 0)?.name, "Barney")
|
XCTAssertEqual(monster.testarrayoftables(at: 0)?.name, "Barney")
|
||||||
XCTAssertEqual(monster.testarrayoftables(at: 1)?.name, "Frodo")
|
XCTAssertEqual(monster.testarrayoftables(at: 1)?.name, "Frodo")
|
||||||
XCTAssertEqual(monster.testarrayoftables(at: 2)?.name, "Wilma")
|
XCTAssertEqual(monster.testarrayoftables(at: 2)?.name, "Wilma")
|
||||||
|
|
||||||
// Example of searching for a table by the key
|
// Example of searching for a table by the key
|
||||||
XCTAssertNotNil(monster.testarrayoftablesBy(key: "Frodo"))
|
XCTAssertNotNil(monster.testarrayoftablesBy(key: "Frodo"))
|
||||||
XCTAssertNotNil(monster.testarrayoftablesBy(key: "Barney"))
|
XCTAssertNotNil(monster.testarrayoftablesBy(key: "Barney"))
|
||||||
XCTAssertNotNil(monster.testarrayoftablesBy(key: "Wilma"))
|
XCTAssertNotNil(monster.testarrayoftablesBy(key: "Wilma"))
|
||||||
|
|
||||||
XCTAssertEqual(monster.testType, .monster)
|
XCTAssertEqual(monster.testType, .monster)
|
||||||
|
|
||||||
XCTAssertEqual(monster.mutate(inventory: 1, at: 0), true)
|
XCTAssertEqual(monster.mutate(inventory: 1, at: 0), true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 2, at: 1), true)
|
XCTAssertEqual(monster.mutate(inventory: 2, at: 1), true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 3, at: 2), true)
|
XCTAssertEqual(monster.mutate(inventory: 3, at: 2), true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 4, at: 3), true)
|
XCTAssertEqual(monster.mutate(inventory: 4, at: 3), true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 5, at: 4), true)
|
XCTAssertEqual(monster.mutate(inventory: 5, at: 4), true)
|
||||||
|
|
||||||
for i in 0..<monster.inventoryCount {
|
for i in 0..<monster.inventoryCount {
|
||||||
XCTAssertEqual(monster.inventory(at: i), Byte(i + 1))
|
XCTAssertEqual(monster.inventory(at: i), Byte(i + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(monster.mutate(inventory: 0, at: 0), true)
|
XCTAssertEqual(monster.mutate(inventory: 0, at: 0), true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 1, at: 1), true)
|
XCTAssertEqual(monster.mutate(inventory: 1, at: 1), true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 2, at: 2), true)
|
XCTAssertEqual(monster.mutate(inventory: 2, at: 2), true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 3, at: 3), true)
|
XCTAssertEqual(monster.mutate(inventory: 3, at: 3), true)
|
||||||
XCTAssertEqual(monster.mutate(inventory: 4, at: 4), true)
|
XCTAssertEqual(monster.mutate(inventory: 4, at: 4), true)
|
||||||
|
|
||||||
let vec = monster.pos
|
let vec = monster.pos
|
||||||
XCTAssertEqual(vec?.x, 1)
|
XCTAssertEqual(vec?.x, 1)
|
||||||
XCTAssertTrue(vec?.mutate(x: 55.0) ?? false)
|
XCTAssertTrue(vec?.mutate(x: 55.0) ?? false)
|
||||||
@@ -133,9 +145,8 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
XCTAssertEqual(vec?.x, 1)
|
XCTAssertEqual(vec?.x, 1)
|
||||||
XCTAssertTrue(vec?.mutate(test1: 3) ?? false)
|
XCTAssertTrue(vec?.mutate(test1: 3) ?? false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readMonster(fb: ByteBuffer) {
|
func readFlatbufferMonster(monster: inout MyGame.Example.Monster) {
|
||||||
let monster = Monster1.getRootAsMonster(bb: fb)
|
|
||||||
XCTAssertEqual(monster.hp, 80)
|
XCTAssertEqual(monster.hp, 80)
|
||||||
XCTAssertEqual(monster.mana, 150)
|
XCTAssertEqual(monster.mana, 150)
|
||||||
XCTAssertEqual(monster.name, "MyMonster")
|
XCTAssertEqual(monster.name, "MyMonster")
|
||||||
@@ -177,14 +188,56 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
|||||||
XCTAssertEqual(monster.testarrayofstring(at: 0), "test1")
|
XCTAssertEqual(monster.testarrayofstring(at: 0), "test1")
|
||||||
XCTAssertEqual(monster.testarrayofstring(at: 1), "test2")
|
XCTAssertEqual(monster.testarrayofstring(at: 1), "test2")
|
||||||
XCTAssertEqual(monster.testbool, true)
|
XCTAssertEqual(monster.testbool, true)
|
||||||
|
|
||||||
let array = monster.nameSegmentArray
|
let array = monster.nameSegmentArray
|
||||||
XCTAssertEqual(String(bytes: array ?? [], encoding: .utf8), "MyMonster")
|
XCTAssertEqual(String(bytes: array ?? [], encoding: .utf8), "MyMonster")
|
||||||
|
|
||||||
if 0 == monster.testarrayofboolsCount {
|
if 0 == monster.testarrayofboolsCount {
|
||||||
XCTAssertEqual(monster.testarrayofbools.isEmpty, true)
|
XCTAssertEqual(monster.testarrayofbools.isEmpty, true)
|
||||||
} else {
|
} else {
|
||||||
XCTAssertEqual(monster.testarrayofbools.isEmpty, false)
|
XCTAssertEqual(monster.testarrayofbools.isEmpty, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readObjectApi(monster: MyGame.Example.MonsterT) {
|
||||||
|
XCTAssertEqual(monster.hp, 80)
|
||||||
|
XCTAssertEqual(monster.mana, 150)
|
||||||
|
XCTAssertEqual(monster.name, "MyMonster")
|
||||||
|
let pos = monster.pos
|
||||||
|
XCTAssertEqual(pos?.x, 1)
|
||||||
|
XCTAssertEqual(pos?.y, 2)
|
||||||
|
XCTAssertEqual(pos?.z, 3)
|
||||||
|
XCTAssertEqual(pos?.test1, 3)
|
||||||
|
XCTAssertEqual(pos?.test2, .green)
|
||||||
|
let test = pos?.test3
|
||||||
|
XCTAssertEqual(test?.a, 5)
|
||||||
|
XCTAssertEqual(test?.b, 6)
|
||||||
|
let monster2 = monster.test?.value as? MyGame.Example.MonsterT
|
||||||
|
XCTAssertEqual(monster2?.name, "Fred")
|
||||||
|
XCTAssertEqual(monster.mana, 150)
|
||||||
|
monster.mana = 10
|
||||||
|
XCTAssertEqual(monster.mana, 10)
|
||||||
|
monster.mana = 150
|
||||||
|
XCTAssertEqual(monster.mana, 150)
|
||||||
|
|
||||||
|
XCTAssertEqual(monster.inventory.count, 5)
|
||||||
|
var sum: Byte = 0
|
||||||
|
for i in monster.inventory {
|
||||||
|
sum += i
|
||||||
|
}
|
||||||
|
XCTAssertEqual(sum, 10)
|
||||||
|
XCTAssertEqual(monster.test4.count, 2)
|
||||||
|
let test0 = monster.test4[0]
|
||||||
|
let test1 = monster.test4[1]
|
||||||
|
var sum0 = 0
|
||||||
|
var sum1 = 0
|
||||||
|
if let a = test0?.a, let b = test0?.b {
|
||||||
|
sum0 = Int(a) + Int(b)
|
||||||
|
}
|
||||||
|
if let a = test1?.a, let b = test1?.b {
|
||||||
|
sum1 = Int(a) + Int(b)
|
||||||
|
}
|
||||||
|
XCTAssertEqual(sum0 + sum1, 100)
|
||||||
|
XCTAssertEqual(monster.testbool, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ final class FlatBuffersUnionTests: XCTestCase {
|
|||||||
let end = Movie.createMovie(&fb, vectorOfCharactersType: types, vectorOfCharacters: characterVector)
|
let end = Movie.createMovie(&fb, vectorOfCharactersType: types, vectorOfCharacters: characterVector)
|
||||||
Movie.finish(&fb, end: end)
|
Movie.finish(&fb, end: end)
|
||||||
|
|
||||||
let movie = Movie.getRootAsMovie(bb: fb.buffer)
|
var movie = Movie.getRootAsMovie(bb: fb.buffer)
|
||||||
XCTAssertEqual(movie.charactersTypeCount, Int32(characterType.count))
|
XCTAssertEqual(movie.charactersTypeCount, Int32(characterType.count))
|
||||||
XCTAssertEqual(movie.charactersCount, Int32(characters.count))
|
XCTAssertEqual(movie.charactersCount, Int32(characters.count))
|
||||||
|
|
||||||
@@ -102,6 +102,19 @@ final class FlatBuffersUnionTests: XCTestCase {
|
|||||||
XCTAssertEqual(movie.characters(at: 0, type: BookReader.self)?.booksRead, 7)
|
XCTAssertEqual(movie.characters(at: 0, type: BookReader.self)?.booksRead, 7)
|
||||||
XCTAssertEqual(movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage, swordDmg)
|
XCTAssertEqual(movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage, swordDmg)
|
||||||
XCTAssertEqual(movie.characters(at: 2, type: BookReader.self)?.booksRead, 2)
|
XCTAssertEqual(movie.characters(at: 2, type: BookReader.self)?.booksRead, 2)
|
||||||
|
|
||||||
|
var objc: MovieT? = movie.unpack()
|
||||||
|
XCTAssertEqual(movie.charactersTypeCount, Int32(objc?.characters.count ?? 0))
|
||||||
|
XCTAssertEqual(movie.characters(at: 0, type: BookReader.self)?.booksRead, (objc?.characters[0]?.value as? BookReaderT)?.booksRead)
|
||||||
|
fb.clear()
|
||||||
|
let newMovie = Movie.pack(&fb, obj: &objc)
|
||||||
|
fb.finish(offset: newMovie)
|
||||||
|
|
||||||
|
let packedMovie = Movie.getRootAsMovie(bb: fb.buffer)
|
||||||
|
|
||||||
|
XCTAssertEqual(packedMovie.characters(at: 0, type: BookReader.self)?.booksRead, movie.characters(at: 0, type: BookReader.self)?.booksRead)
|
||||||
|
XCTAssertEqual(packedMovie.characters(at: 1, type: Attacker.self)?.swordAttackDamage, movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage)
|
||||||
|
XCTAssertEqual(packedMovie.characters(at: 2, type: BookReader.self)?.booksRead, movie.characters(at: 2, type: BookReader.self)?.booksRead)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -3,124 +3,292 @@
|
|||||||
import FlatBuffers
|
import FlatBuffers
|
||||||
|
|
||||||
public enum Character: UInt8, Enum {
|
public enum Character: UInt8, Enum {
|
||||||
public typealias T = UInt8
|
public typealias T = UInt8
|
||||||
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
|
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
|
||||||
public var value: UInt8 { return self.rawValue }
|
public var value: UInt8 { return self.rawValue }
|
||||||
case none = 0
|
case none = 0
|
||||||
case mulan = 1
|
case mulan = 1
|
||||||
case rapunzel = 2
|
case rapunzel = 2
|
||||||
case belle = 3
|
case belle = 3
|
||||||
case bookfan = 4
|
case bookfan = 4
|
||||||
case other = 5
|
case other = 5
|
||||||
case unused = 6
|
case unused = 6
|
||||||
|
|
||||||
|
|
||||||
|
public static var max: Character { return .unused }
|
||||||
public static var max: Character { return .unused }
|
public static var min: Character { return .none }
|
||||||
public static var min: Character { return .none }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CharacterUnion {
|
||||||
|
var type: Character
|
||||||
|
var value: NativeTable?
|
||||||
|
init(_ v: NativeTable?, type: Character) {
|
||||||
|
self.type = type
|
||||||
|
self.value = v
|
||||||
|
}
|
||||||
|
func pack(builder: inout FlatBufferBuilder) -> Offset<UOffset> {
|
||||||
|
switch type {
|
||||||
|
case .mulan:
|
||||||
|
var __obj = value as? AttackerT
|
||||||
|
return Attacker.pack(&builder, obj: &__obj)
|
||||||
|
case .rapunzel:
|
||||||
|
var __obj = value as? RapunzelT
|
||||||
|
return Rapunzel.pack(&builder, obj: &__obj)
|
||||||
|
case .belle:
|
||||||
|
var __obj = value as? BookReaderT
|
||||||
|
return BookReader.pack(&builder, obj: &__obj)
|
||||||
|
case .bookfan:
|
||||||
|
var __obj = value as? BookReaderT
|
||||||
|
return BookReader.pack(&builder, obj: &__obj)
|
||||||
|
default: return Offset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public struct Rapunzel: Readable {
|
public struct Rapunzel: Readable {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
|
private var _accessor: Struct
|
||||||
|
|
||||||
private var _accessor: Struct
|
public static var size = 4
|
||||||
public static var size = 4
|
public static var alignment = 4
|
||||||
public static var alignment = 4
|
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
|
||||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
|
|
||||||
|
|
||||||
public var hairLength: Int32 { return _accessor.readBuffer(of: Int32.self, at: 0) }
|
public var hairLength: Int32 { return _accessor.readBuffer(of: Int32.self, at: 0) }
|
||||||
public func mutate(hairLength: Int32) -> Bool { return _accessor.mutate(hairLength, index: 0) }
|
public func mutate(hairLength: Int32) -> Bool { return _accessor.mutate(hairLength, index: 0) }
|
||||||
|
|
||||||
|
|
||||||
|
public mutating func unpack() -> RapunzelT {
|
||||||
|
return RapunzelT(&self)
|
||||||
|
}
|
||||||
|
public static func pack(_ builder: inout FlatBufferBuilder, obj: inout RapunzelT?) -> Offset<UOffset> {
|
||||||
|
guard let obj = obj else { return Offset<UOffset>() }
|
||||||
|
|
||||||
|
return builder.create(struct: createRapunzel(hairLength: obj.hairLength), type: Rapunzel.self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class RapunzelT: NativeTable {
|
||||||
|
|
||||||
|
var hairLength: Int32
|
||||||
|
|
||||||
|
init(_ _t: inout Rapunzel) {
|
||||||
|
hairLength = _t.hairLength
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
hairLength = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
public struct BookReader: Readable {
|
public struct BookReader: Readable {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
|
private var _accessor: Struct
|
||||||
|
|
||||||
private var _accessor: Struct
|
public static var size = 4
|
||||||
public static var size = 4
|
public static var alignment = 4
|
||||||
public static var alignment = 4
|
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
|
||||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
|
|
||||||
|
|
||||||
public var booksRead: Int32 { return _accessor.readBuffer(of: Int32.self, at: 0) }
|
public var booksRead: Int32 { return _accessor.readBuffer(of: Int32.self, at: 0) }
|
||||||
public func mutate(booksRead: Int32) -> Bool { return _accessor.mutate(booksRead, index: 0) }
|
public func mutate(booksRead: Int32) -> Bool { return _accessor.mutate(booksRead, index: 0) }
|
||||||
|
|
||||||
|
|
||||||
|
public mutating func unpack() -> BookReaderT {
|
||||||
|
return BookReaderT(&self)
|
||||||
|
}
|
||||||
|
public static func pack(_ builder: inout FlatBufferBuilder, obj: inout BookReaderT?) -> Offset<UOffset> {
|
||||||
|
guard let obj = obj else { return Offset<UOffset>() }
|
||||||
|
|
||||||
|
return builder.create(struct: createBookReader(booksRead: obj.booksRead), type: BookReader.self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BookReaderT: NativeTable {
|
||||||
|
|
||||||
|
var booksRead: Int32
|
||||||
|
|
||||||
|
init(_ _t: inout BookReader) {
|
||||||
|
booksRead = _t.booksRead
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
booksRead = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
public func createRapunzel(hairLength: Int32) -> UnsafeMutableRawPointer {
|
public func createRapunzel(hairLength: Int32) -> UnsafeMutableRawPointer {
|
||||||
let memory = UnsafeMutableRawPointer.allocate(byteCount: Rapunzel.size, alignment: Rapunzel.alignment)
|
let memory = UnsafeMutableRawPointer.allocate(byteCount: Rapunzel.size, alignment: Rapunzel.alignment)
|
||||||
memory.initializeMemory(as: UInt8.self, repeating: 0, count: Rapunzel.size)
|
memory.initializeMemory(as: UInt8.self, repeating: 0, count: Rapunzel.size)
|
||||||
memory.storeBytes(of: hairLength, toByteOffset: 0, as: Int32.self)
|
memory.storeBytes(of: hairLength, toByteOffset: 0, as: Int32.self)
|
||||||
return memory
|
return memory
|
||||||
}
|
}
|
||||||
|
|
||||||
public func createBookReader(booksRead: Int32) -> UnsafeMutableRawPointer {
|
public func createBookReader(booksRead: Int32) -> UnsafeMutableRawPointer {
|
||||||
let memory = UnsafeMutableRawPointer.allocate(byteCount: BookReader.size, alignment: BookReader.alignment)
|
let memory = UnsafeMutableRawPointer.allocate(byteCount: BookReader.size, alignment: BookReader.alignment)
|
||||||
memory.initializeMemory(as: UInt8.self, repeating: 0, count: BookReader.size)
|
memory.initializeMemory(as: UInt8.self, repeating: 0, count: BookReader.size)
|
||||||
memory.storeBytes(of: booksRead, toByteOffset: 0, as: Int32.self)
|
memory.storeBytes(of: booksRead, toByteOffset: 0, as: Int32.self)
|
||||||
return memory
|
return memory
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct Attacker: FlatBufferObject {
|
public struct Attacker: FlatBufferObject {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
|
private var _accessor: Table
|
||||||
|
|
||||||
private var _accessor: Table
|
public static func finish(_ fbb: inout FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MOVI", addPrefix: prefix) }
|
||||||
public static func finish(_ fbb: inout FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MOVI", addPrefix: prefix) }
|
public static func getRootAsAttacker(bb: ByteBuffer) -> Attacker { return Attacker(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
|
||||||
public static func getRootAsAttacker(bb: ByteBuffer) -> Attacker { return Attacker(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
|
|
||||||
|
|
||||||
private init(_ t: Table) { _accessor = t }
|
private init(_ t: Table) { _accessor = t }
|
||||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||||
|
|
||||||
public var swordAttackDamage: Int32 { let o = _accessor.offset(4); return o == 0 ? 0 : _accessor.readBuffer(of: Int32.self, at: o) }
|
public var swordAttackDamage: Int32 { let o = _accessor.offset(4); return o == 0 ? 0 : _accessor.readBuffer(of: Int32.self, at: o) }
|
||||||
public func mutate(swordAttackDamage: Int32) -> Bool {let o = _accessor.offset(4); return _accessor.mutate(swordAttackDamage, index: o) }
|
public func mutate(swordAttackDamage: Int32) -> Bool {let o = _accessor.offset(4); return _accessor.mutate(swordAttackDamage, index: o) }
|
||||||
public static func startAttacker(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
public static func startAttacker(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
||||||
public static func add(swordAttackDamage: Int32, _ fbb: inout FlatBufferBuilder) { fbb.add(element: swordAttackDamage, def: 0, at: 0) }
|
public static func add(swordAttackDamage: Int32, _ fbb: inout FlatBufferBuilder) { fbb.add(element: swordAttackDamage, def: 0, at: 0) }
|
||||||
public static func endAttacker(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
|
public static func endAttacker(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
|
||||||
public static func createAttacker(_ fbb: inout FlatBufferBuilder,
|
public static func createAttacker(_ fbb: inout FlatBufferBuilder,
|
||||||
swordAttackDamage: Int32 = 0) -> Offset<UOffset> {
|
swordAttackDamage: Int32 = 0) -> Offset<UOffset> {
|
||||||
let __start = Attacker.startAttacker(&fbb)
|
let __start = Attacker.startAttacker(&fbb)
|
||||||
Attacker.add(swordAttackDamage: swordAttackDamage, &fbb)
|
Attacker.add(swordAttackDamage: swordAttackDamage, &fbb)
|
||||||
return Attacker.endAttacker(&fbb, start: __start)
|
return Attacker.endAttacker(&fbb, start: __start)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public mutating func unpack() -> AttackerT {
|
||||||
|
return AttackerT(&self)
|
||||||
|
}
|
||||||
|
public static func pack(_ builder: inout FlatBufferBuilder, obj: inout AttackerT?) -> Offset<UOffset> {
|
||||||
|
guard let obj = obj else { return Offset<UOffset>() }
|
||||||
|
|
||||||
|
let __root = Attacker.startAttacker(&builder)
|
||||||
|
Attacker.add(swordAttackDamage: obj.swordAttackDamage, &builder)
|
||||||
|
return Attacker.endAttacker(&builder, start: __root)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AttackerT: NativeTable {
|
||||||
|
|
||||||
|
var swordAttackDamage: Int32
|
||||||
|
|
||||||
|
init(_ _t: inout Attacker) {
|
||||||
|
swordAttackDamage = _t.swordAttackDamage
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
swordAttackDamage = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
public struct Movie: FlatBufferObject {
|
public struct Movie: FlatBufferObject {
|
||||||
|
|
||||||
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
static func validateVersion() { FlatBuffersVersion_1_12_0() }
|
||||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||||
|
private var _accessor: Table
|
||||||
|
|
||||||
private var _accessor: Table
|
public static func finish(_ fbb: inout FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MOVI", addPrefix: prefix) }
|
||||||
public static func finish(_ fbb: inout FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MOVI", addPrefix: prefix) }
|
public static func getRootAsMovie(bb: ByteBuffer) -> Movie { return Movie(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
|
||||||
public static func getRootAsMovie(bb: ByteBuffer) -> Movie { return Movie(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
|
|
||||||
|
|
||||||
private init(_ t: Table) { _accessor = t }
|
private init(_ t: Table) { _accessor = t }
|
||||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||||
|
|
||||||
public var mainCharacterType: Character { let o = _accessor.offset(4); return o == 0 ? .none : Character(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .none }
|
public var mainCharacterType: Character { let o = _accessor.offset(4); return o == 0 ? .none : Character(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .none }
|
||||||
public func mainCharacter<T: FlatBufferObject>(type: T.Type) -> T? { let o = _accessor.offset(6); return o == 0 ? nil : _accessor.union(o) }
|
public func mainCharacter<T: FlatBufferObject>(type: T.Type) -> T? { let o = _accessor.offset(6); return o == 0 ? nil : _accessor.union(o) }
|
||||||
public var charactersTypeCount: Int32 { let o = _accessor.offset(8); return o == 0 ? 0 : _accessor.vector(count: o) }
|
public var charactersTypeCount: Int32 { let o = _accessor.offset(8); return o == 0 ? 0 : _accessor.vector(count: o) }
|
||||||
public func charactersType(at index: Int32) -> Character? { let o = _accessor.offset(8); return o == 0 ? Character.none : Character(rawValue: _accessor.directRead(of: UInt8.self, offset: _accessor.vector(at: o) + index * 1)) }
|
public func charactersType(at index: Int32) -> Character? { let o = _accessor.offset(8); return o == 0 ? Character.none : Character(rawValue: _accessor.directRead(of: UInt8.self, offset: _accessor.vector(at: o) + index * 1)) }
|
||||||
public var charactersCount: Int32 { let o = _accessor.offset(10); return o == 0 ? 0 : _accessor.vector(count: o) }
|
public var charactersCount: Int32 { let o = _accessor.offset(10); return o == 0 ? 0 : _accessor.vector(count: o) }
|
||||||
public func characters<T: FlatBufferObject>(at index: Int32, type: T.Type) -> T? { let o = _accessor.offset(10); return o == 0 ? nil : _accessor.directUnion(_accessor.vector(at: o) + index * 4) }
|
public func characters<T: FlatBufferObject>(at index: Int32, type: T.Type) -> T? { let o = _accessor.offset(10); return o == 0 ? nil : _accessor.directUnion(_accessor.vector(at: o) + index * 4) }
|
||||||
public static func startMovie(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 4) }
|
public static func startMovie(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 4) }
|
||||||
public static func add(mainCharacterType: Character, _ fbb: inout FlatBufferBuilder) { fbb.add(element: mainCharacterType.rawValue, def: 0, at: 0) }
|
public static func add(mainCharacterType: Character, _ fbb: inout FlatBufferBuilder) { fbb.add(element: mainCharacterType.rawValue, def: 0, at: 0) }
|
||||||
public static func add(mainCharacter: Offset<UOffset>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: mainCharacter, at: 1) }
|
public static func add(mainCharacter: Offset<UOffset>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: mainCharacter, at: 1) }
|
||||||
public static func addVectorOf(charactersType: Offset<UOffset>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: charactersType, at: 2) }
|
public static func addVectorOf(charactersType: Offset<UOffset>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: charactersType, at: 2) }
|
||||||
public static func addVectorOf(characters: Offset<UOffset>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: characters, at: 3) }
|
public static func addVectorOf(characters: Offset<UOffset>, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: characters, at: 3) }
|
||||||
public static func endMovie(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
|
public static func endMovie(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
|
||||||
public static func createMovie(_ fbb: inout FlatBufferBuilder,
|
public static func createMovie(_ fbb: inout FlatBufferBuilder,
|
||||||
mainCharacterType: Character = .none,
|
mainCharacterType: Character = .none,
|
||||||
offsetOfMainCharacter mainCharacter: Offset<UOffset> = Offset(),
|
offsetOfMainCharacter mainCharacter: Offset<UOffset> = Offset(),
|
||||||
vectorOfCharactersType charactersType: Offset<UOffset> = Offset(),
|
vectorOfCharactersType charactersType: Offset<UOffset> = Offset(),
|
||||||
vectorOfCharacters characters: Offset<UOffset> = Offset()) -> Offset<UOffset> {
|
vectorOfCharacters characters: Offset<UOffset> = Offset()) -> Offset<UOffset> {
|
||||||
let __start = Movie.startMovie(&fbb)
|
let __start = Movie.startMovie(&fbb)
|
||||||
Movie.add(mainCharacterType: mainCharacterType, &fbb)
|
Movie.add(mainCharacterType: mainCharacterType, &fbb)
|
||||||
Movie.add(mainCharacter: mainCharacter, &fbb)
|
Movie.add(mainCharacter: mainCharacter, &fbb)
|
||||||
Movie.addVectorOf(charactersType: charactersType, &fbb)
|
Movie.addVectorOf(charactersType: charactersType, &fbb)
|
||||||
Movie.addVectorOf(characters: characters, &fbb)
|
Movie.addVectorOf(characters: characters, &fbb)
|
||||||
return Movie.endMovie(&fbb, start: __start)
|
return Movie.endMovie(&fbb, start: __start)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public mutating func unpack() -> MovieT {
|
||||||
|
return MovieT(&self)
|
||||||
|
}
|
||||||
|
public static func pack(_ builder: inout FlatBufferBuilder, obj: inout MovieT?) -> Offset<UOffset> {
|
||||||
|
guard let obj = obj else { return Offset<UOffset>() }
|
||||||
|
|
||||||
|
let __mainCharacter = obj.mainCharacter?.pack(builder: &builder) ?? Offset()
|
||||||
|
var __characters__: [Offset<UOffset>] = []
|
||||||
|
for i in obj.characters {
|
||||||
|
guard let off = i?.pack(builder: &builder) else { continue }
|
||||||
|
__characters__.append(off)
|
||||||
|
}
|
||||||
|
let __characters = builder.createVector(ofOffsets: __characters__)
|
||||||
|
let __charactersType = builder.createVector(obj.characters.compactMap { $0?.type })
|
||||||
|
let __root = Movie.startMovie(&builder)
|
||||||
|
if let o = obj.mainCharacter?.type {
|
||||||
|
Movie.add(mainCharacterType: o, &builder)
|
||||||
|
Movie.add(mainCharacter: __mainCharacter, &builder)
|
||||||
|
}
|
||||||
|
|
||||||
|
Movie.addVectorOf(charactersType: __charactersType, &builder)
|
||||||
|
Movie.addVectorOf(characters: __characters, &builder)
|
||||||
|
return Movie.endMovie(&builder, start: __root)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MovieT: NativeTable {
|
||||||
|
|
||||||
|
var mainCharacter: CharacterUnion?
|
||||||
|
var characters: [CharacterUnion?]
|
||||||
|
|
||||||
|
init(_ _t: inout Movie) {
|
||||||
|
switch _t.mainCharacterType {
|
||||||
|
case .mulan:
|
||||||
|
var _v = _t.mainCharacter(type: Attacker.self)
|
||||||
|
mainCharacter = CharacterUnion(_v?.unpack(), type: .mulan)
|
||||||
|
case .rapunzel:
|
||||||
|
var _v = _t.mainCharacter(type: Rapunzel.self)
|
||||||
|
mainCharacter = CharacterUnion(_v?.unpack(), type: .rapunzel)
|
||||||
|
case .belle:
|
||||||
|
var _v = _t.mainCharacter(type: BookReader.self)
|
||||||
|
mainCharacter = CharacterUnion(_v?.unpack(), type: .belle)
|
||||||
|
case .bookfan:
|
||||||
|
var _v = _t.mainCharacter(type: BookReader.self)
|
||||||
|
mainCharacter = CharacterUnion(_v?.unpack(), type: .bookfan)
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
characters = []
|
||||||
|
for index in 0..<_t.charactersCount {
|
||||||
|
switch _t.charactersType(at: index) {
|
||||||
|
case .mulan:
|
||||||
|
var _v = _t.characters(at: index, type: Attacker.self)
|
||||||
|
characters.append(CharacterUnion(_v?.unpack(), type: .mulan))
|
||||||
|
case .rapunzel:
|
||||||
|
var _v = _t.characters(at: index, type: Rapunzel.self)
|
||||||
|
characters.append(CharacterUnion(_v?.unpack(), type: .rapunzel))
|
||||||
|
case .belle:
|
||||||
|
var _v = _t.characters(at: index, type: BookReader.self)
|
||||||
|
characters.append(CharacterUnion(_v?.unpack(), type: .belle))
|
||||||
|
case .bookfan:
|
||||||
|
var _v = _t.characters(at: index, type: BookReader.self)
|
||||||
|
characters.append(CharacterUnion(_v?.unpack(), type: .bookfan))
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
characters = []
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user