mirror of
https://github.com/google/flatbuffers.git
synced 2025-04-08 09:12:14 +08:00
Implements verifier and code gen for swift (#6373)
Updates test cases on linux Adhere to new protocol naming Adds fuzzing Adds documentation Adds support for string unions Updated fuzzer generated code
This commit is contained in:
parent
04b10f5a3a
commit
a5175c513a
1
.gitignore
vendored
1
.gitignore
vendored
@ -141,3 +141,4 @@ yarn-error.log
|
||||
**/vendor
|
||||
**/go.sum
|
||||
flatbuffers.pc
|
||||
**/FlatBuffers.Test.Swift.xcodeproj
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
import FlatBuffers
|
||||
|
||||
public struct models_HelloReply: FlatBufferObject {
|
||||
public struct models_HelloReply: FlatBufferObject, Verifiable {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -34,9 +34,15 @@ public struct models_HelloReply: FlatBufferObject {
|
||||
models_HelloReply.add(message: message, &fbb)
|
||||
return models_HelloReply.endHelloReply(&fbb, start: __start)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.message.p, fieldName: "message", required: false, type: ForwardOffset<String>.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
public struct models_HelloRequest: FlatBufferObject {
|
||||
public struct models_HelloRequest: FlatBufferObject, Verifiable {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -66,5 +72,11 @@ public struct models_HelloRequest: FlatBufferObject {
|
||||
models_HelloRequest.add(name: name, &fbb)
|
||||
return models_HelloRequest.endHelloRequest(&fbb, start: __start)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.name.p, fieldName: "name", required: false, type: ForwardOffset<String>.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,8 @@ class SwiftGenerator : public BaseGenerator {
|
||||
code_.SetValue("ACCESS_TYPE", is_private_access ? "internal" : "public");
|
||||
GenComment(struct_def.doc_comment);
|
||||
code_.SetValue("STRUCTNAME", NameWrappedInNameSpace(struct_def));
|
||||
code_ += "{{ACCESS_TYPE}} struct {{STRUCTNAME}}: NativeStruct\\";
|
||||
code_ +=
|
||||
"{{ACCESS_TYPE}} struct {{STRUCTNAME}}: NativeStruct, Verifiable\\";
|
||||
if (parser_.opts.generate_object_based_api) code_ += ", NativeObject\\";
|
||||
code_ += " {";
|
||||
code_ += "";
|
||||
@ -250,6 +251,15 @@ class SwiftGenerator : public BaseGenerator {
|
||||
GenReaderMainBody() + "{{VALUETYPE}}(rawValue: _{{VALUENAME}})! }";
|
||||
}
|
||||
}
|
||||
code_ += "";
|
||||
code_ +=
|
||||
"public static func verify<T>(_ verifier: inout Verifier, at position: "
|
||||
"Int, of type: T.Type) throws where T: Verifiable {";
|
||||
Indent();
|
||||
code_ +=
|
||||
"try verifier.inBuffer(position: position, of: {{STRUCTNAME}}.self)";
|
||||
Outdent();
|
||||
code_ += "}";
|
||||
Outdent();
|
||||
code_ += "}\n";
|
||||
}
|
||||
@ -375,6 +385,8 @@ class SwiftGenerator : public BaseGenerator {
|
||||
GenTableWriter(struct_def);
|
||||
if (parser_.opts.generate_object_based_api)
|
||||
GenerateObjectAPITableExtension(struct_def);
|
||||
code_ += "";
|
||||
GenerateVerifier(struct_def);
|
||||
Outdent();
|
||||
code_ += "}\n";
|
||||
}
|
||||
@ -410,6 +422,7 @@ class SwiftGenerator : public BaseGenerator {
|
||||
code_.SetValue("MUTABLE", struct_def.fixed ? Mutable() : "");
|
||||
code_ +=
|
||||
"{{ACCESS_TYPE}} struct {{STRUCTNAME}}{{MUTABLE}}: FlatBufferObject\\";
|
||||
if (!struct_def.fixed) code_ += ", Verifiable\\";
|
||||
if (!struct_def.fixed && parser_.opts.generate_object_based_api)
|
||||
code_ += ", ObjectAPIPacker\\";
|
||||
code_ += " {\n";
|
||||
@ -651,8 +664,10 @@ class SwiftGenerator : public BaseGenerator {
|
||||
code_.SetValue("VALUETYPE", type);
|
||||
code_.SetValue("OFFSET", name);
|
||||
code_.SetValue("CONSTANT", field.value.constant);
|
||||
std::string def_Val = field.IsDefault() ? "{{CONSTANT}}" : "nil";
|
||||
std::string optional = field.IsOptional() ? "?" : "";
|
||||
bool opt_scalar =
|
||||
field.IsOptional() && IsScalar(field.value.type.base_type);
|
||||
std::string def_Val = opt_scalar ? "nil" : "{{CONSTANT}}";
|
||||
std::string optional = opt_scalar ? "?" : "";
|
||||
auto const_string = "return o == 0 ? " + def_Val + " : ";
|
||||
GenComment(field.doc_comment);
|
||||
if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type) &&
|
||||
@ -831,6 +846,112 @@ class SwiftGenerator : public BaseGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
void GenerateVerifier(const StructDef &struct_def) {
|
||||
code_ +=
|
||||
"public static func verify<T>(_ verifier: inout Verifier, at position: "
|
||||
"Int, of type: T.Type) throws where T: Verifiable {";
|
||||
Indent();
|
||||
code_ += "var _v = try verifier.visitTable(at: position)";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (field.deprecated) continue;
|
||||
auto offset = NumToString(field.value.offset);
|
||||
auto name = Name(field);
|
||||
|
||||
code_.SetValue("VALUENAME", name);
|
||||
code_.SetValue("VALUETYPE", GenerateVerifierType(field));
|
||||
code_.SetValue("OFFSET", name);
|
||||
code_.SetValue("ISREQUIRED", field.IsRequired() ? "true" : "false");
|
||||
|
||||
if (IsUnion(field.value.type)) {
|
||||
GenerateUnionTypeVerifier(field);
|
||||
continue;
|
||||
}
|
||||
|
||||
code_ +=
|
||||
"try _v.visit(field: {{TABLEOFFSET}}.{{OFFSET}}.p, fieldName: "
|
||||
"\"{{VALUENAME}}\", required: {{ISREQUIRED}}, type: "
|
||||
"{{VALUETYPE}}.self)";
|
||||
}
|
||||
code_ += "_v.finish()";
|
||||
Outdent();
|
||||
code_ += "}";
|
||||
}
|
||||
|
||||
void GenerateUnionTypeVerifier(const FieldDef &field) {
|
||||
auto is_vector = IsVector(field.value.type) || IsArray(field.value.type);
|
||||
if (field.value.type.base_type == BASE_TYPE_UTYPE ||
|
||||
(is_vector &&
|
||||
field.value.type.VectorType().base_type == BASE_TYPE_UTYPE))
|
||||
return;
|
||||
EnumDef &union_def = *field.value.type.enum_def;
|
||||
code_.SetValue("VALUETYPE", NameWrappedInNameSpace(union_def));
|
||||
code_.SetValue("FUNCTION_NAME", is_vector ? "visitUnionVector" : "visit");
|
||||
code_ +=
|
||||
"try _v.{{FUNCTION_NAME}}(unionKey: {{TABLEOFFSET}}.{{OFFSET}}Type.p, "
|
||||
"unionField: {{TABLEOFFSET}}.{{OFFSET}}.p, unionKeyName: "
|
||||
"\"{{VALUENAME}}Type\", fieldName: \"{{VALUENAME}}\", required: "
|
||||
"{{ISREQUIRED}}, completion: { (verifier, key: {{VALUETYPE}}, pos) in";
|
||||
Indent();
|
||||
code_ += "switch key {";
|
||||
for (auto it = union_def.Vals().begin(); it != union_def.Vals().end();
|
||||
++it) {
|
||||
const auto &ev = **it;
|
||||
|
||||
auto name = Name(ev);
|
||||
auto type = GenType(ev.union_type);
|
||||
code_.SetValue("KEY", name);
|
||||
code_.SetValue("VALUETYPE", type);
|
||||
code_ += "case .{{KEY}}:";
|
||||
Indent();
|
||||
if (ev.union_type.base_type == BASE_TYPE_NONE) {
|
||||
code_ += "break // NOTE - SWIFT doesnt support none";
|
||||
} else if (ev.union_type.base_type == BASE_TYPE_STRING) {
|
||||
code_ +=
|
||||
"try ForwardOffset<String>.verify(&verifier, at: pos, of: "
|
||||
"String.self)";
|
||||
} else {
|
||||
code_.SetValue("MAINTYPE", ev.union_type.struct_def->fixed
|
||||
? type
|
||||
: "ForwardOffset<" + type + ">");
|
||||
code_ +=
|
||||
"try {{MAINTYPE}}.verify(&verifier, at: pos, of: "
|
||||
"{{VALUETYPE}}.self)";
|
||||
}
|
||||
Outdent();
|
||||
}
|
||||
code_ += "}";
|
||||
Outdent();
|
||||
code_ += "})";
|
||||
}
|
||||
|
||||
std::string GenerateVerifierType(const FieldDef &field) {
|
||||
auto type = field.value.type;
|
||||
auto is_vector = IsVector(type) || IsArray(type);
|
||||
|
||||
if (is_vector) {
|
||||
auto vector_type = field.value.type.VectorType();
|
||||
return "ForwardOffset<Vector<" +
|
||||
GenerateNestedVerifierTypes(vector_type) + ", " +
|
||||
GenType(vector_type) + ">>";
|
||||
}
|
||||
|
||||
return GenerateNestedVerifierTypes(field.value.type);
|
||||
}
|
||||
|
||||
std::string GenerateNestedVerifierTypes(const Type &type) {
|
||||
auto string_type = GenType(type);
|
||||
|
||||
if (IsScalar(type.base_type)) { return string_type; }
|
||||
|
||||
if (IsString(type)) { return "ForwardOffset<" + string_type + ">"; }
|
||||
|
||||
if (type.struct_def && type.struct_def->fixed) { return string_type; }
|
||||
|
||||
return "ForwardOffset<" + string_type + ">";
|
||||
}
|
||||
|
||||
void GenByKeyFunctions(const FieldDef &key_field) {
|
||||
code_.SetValue("TYPE", GenType(key_field.value.type));
|
||||
code_ +=
|
||||
@ -844,13 +965,24 @@ class SwiftGenerator : public BaseGenerator {
|
||||
void GenEnum(const EnumDef &enum_def) {
|
||||
if (enum_def.generated) return;
|
||||
auto is_private_access = enum_def.attributes.Lookup("private");
|
||||
code_.SetValue("ENUM_TYPE",
|
||||
enum_def.is_union ? "UnionEnum" : "Enum, Verifiable");
|
||||
code_.SetValue("ACCESS_TYPE", is_private_access ? "internal" : "public");
|
||||
code_.SetValue("ENUM_NAME", NameWrappedInNameSpace(enum_def));
|
||||
code_.SetValue("BASE_TYPE", GenTypeBasic(enum_def.underlying_type, false));
|
||||
GenComment(enum_def.doc_comment);
|
||||
code_ += "{{ACCESS_TYPE}} enum {{ENUM_NAME}}: {{BASE_TYPE}}, Enum {";
|
||||
code_ +=
|
||||
"{{ACCESS_TYPE}} enum {{ENUM_NAME}}: {{BASE_TYPE}}, {{ENUM_TYPE}} {";
|
||||
Indent();
|
||||
code_ += "{{ACCESS_TYPE}} typealias T = {{BASE_TYPE}}";
|
||||
if (enum_def.is_union) {
|
||||
code_ += "";
|
||||
code_ += "{{ACCESS_TYPE}} init?(value: T) {";
|
||||
Indent();
|
||||
code_ += "self.init(rawValue: value)";
|
||||
Outdent();
|
||||
code_ += "}\n";
|
||||
}
|
||||
code_ +=
|
||||
"{{ACCESS_TYPE}} static var byteSize: Int { return "
|
||||
"MemoryLayout<{{BASE_TYPE}}>.size "
|
||||
@ -865,7 +997,7 @@ class SwiftGenerator : public BaseGenerator {
|
||||
GenComment(ev.doc_comment);
|
||||
code_ += "case {{KEY}} = {{VALUE}}";
|
||||
}
|
||||
code_ += "\n";
|
||||
code_ += "";
|
||||
AddMinOrMaxEnumValue(Name(*enum_def.MaxValue()), "max");
|
||||
AddMinOrMaxEnumValue(Name(*enum_def.MinValue()), "min");
|
||||
Outdent();
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
# format
|
||||
--indent 2
|
||||
--maxwidth 80
|
||||
|
||||
# options
|
||||
--self remove # redundantSelf
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
/// `ByteBuffer` is the interface that stores the data for a `Flatbuffers` object
|
||||
/// it allows users to write and read data directly from memory thus the use of its
|
||||
/// functions should be used
|
||||
@frozen
|
||||
public struct ByteBuffer {
|
||||
|
||||
@ -32,7 +35,9 @@ public struct ByteBuffer {
|
||||
|
||||
@usableFromInline
|
||||
init(count: Int, alignment: Int) {
|
||||
memory = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: alignment)
|
||||
memory = UnsafeMutableRawPointer.allocate(
|
||||
byteCount: count,
|
||||
alignment: alignment)
|
||||
capacity = count
|
||||
unowned = false
|
||||
}
|
||||
@ -69,7 +74,7 @@ public struct ByteBuffer {
|
||||
/// Reallocates the buffer incase the object to be written doesnt fit in the current buffer
|
||||
/// - Parameter size: Size of the current object
|
||||
@usableFromInline
|
||||
internal func reallocate(_ size: Int, writerSize: Int, alignment: Int) {
|
||||
func reallocate(_ size: Int, writerSize: Int, alignment: Int) {
|
||||
let currentWritingIndex = capacity &- writerSize
|
||||
while capacity <= writerSize &+ size {
|
||||
capacity = capacity << 1
|
||||
@ -78,7 +83,9 @@ public struct ByteBuffer {
|
||||
/// solution take from Apple-NIO
|
||||
capacity = capacity.convertToPowerofTwo
|
||||
|
||||
let newData = UnsafeMutableRawPointer.allocate(byteCount: capacity, alignment: alignment)
|
||||
let newData = UnsafeMutableRawPointer.allocate(
|
||||
byteCount: capacity,
|
||||
alignment: alignment)
|
||||
memset(newData, 0, capacity &- writerSize)
|
||||
memcpy(
|
||||
newData.advanced(by: capacity &- writerSize),
|
||||
@ -94,9 +101,9 @@ public struct ByteBuffer {
|
||||
/// The size of the elements written to the buffer + their paddings
|
||||
private var _writerSize: Int = 0
|
||||
/// Aliginment of the current memory being written to the buffer
|
||||
internal var alignment = 1
|
||||
var alignment = 1
|
||||
/// Current Index which is being used to write to the buffer, it is written from the end to the start of the buffer
|
||||
internal var writerIndex: Int { _storage.capacity &- _writerSize }
|
||||
var writerIndex: Int { _storage.capacity &- _writerSize }
|
||||
|
||||
/// Reader is the position of the current Writer Index (capacity - size)
|
||||
public var reader: Int { writerIndex }
|
||||
@ -166,7 +173,7 @@ public struct ByteBuffer {
|
||||
/// - Parameters:
|
||||
/// - memory: Current memory of the buffer
|
||||
/// - count: count of bytes
|
||||
internal init(memory: UnsafeMutableRawPointer, count: Int) {
|
||||
init(memory: UnsafeMutableRawPointer, count: Int) {
|
||||
_storage = Storage(count: count, alignment: alignment)
|
||||
_storage.copy(from: memory, count: count)
|
||||
_writerSize = _storage.capacity
|
||||
@ -177,7 +184,11 @@ public struct ByteBuffer {
|
||||
/// - memory: Current memory of the buffer
|
||||
/// - count: count of bytes
|
||||
/// - removeBytes: Removes a number of bytes from the current size
|
||||
internal init(memory: UnsafeMutableRawPointer, count: Int, removing removeBytes: Int) {
|
||||
init(
|
||||
memory: UnsafeMutableRawPointer,
|
||||
count: Int,
|
||||
removing removeBytes: Int)
|
||||
{
|
||||
_storage = Storage(count: count, alignment: alignment)
|
||||
_storage.copy(from: memory, count: count)
|
||||
_writerSize = removeBytes
|
||||
@ -247,7 +258,7 @@ public struct ByteBuffer {
|
||||
/// - bytes: Pointer to the view
|
||||
/// - len: Size of string
|
||||
@inline(__always)
|
||||
mutating internal func push(
|
||||
mutating func push(
|
||||
bytes: UnsafeBufferPointer<String.UTF8View.Element>,
|
||||
len: Int) -> Bool
|
||||
{
|
||||
@ -292,20 +303,18 @@ public struct ByteBuffer {
|
||||
/// pops the written VTable if it's already written into the buffer
|
||||
/// - Parameter size: size of the `VTable`
|
||||
@inline(__always)
|
||||
mutating internal func pop(_ size: Int) {
|
||||
mutating func pop(_ size: Int) {
|
||||
assert((_writerSize &- size) > 0, "New size should NOT be a negative number")
|
||||
memset(_storage.memory.advanced(by: writerIndex), 0, _writerSize &- size)
|
||||
_writerSize = size
|
||||
}
|
||||
|
||||
/// Clears the current size of the buffer
|
||||
@inline(__always)
|
||||
mutating public func clearSize() {
|
||||
_writerSize = 0
|
||||
}
|
||||
|
||||
/// Clears the current instance of the buffer, replacing it with new memory
|
||||
@inline(__always)
|
||||
mutating public func clear() {
|
||||
_writerSize = 0
|
||||
alignment = 1
|
||||
@ -317,10 +326,7 @@ public struct ByteBuffer {
|
||||
/// - def: Type of the object
|
||||
/// - position: the index of the object in the buffer
|
||||
public func read<T>(def: T.Type, position: Int) -> T {
|
||||
assert(
|
||||
position + MemoryLayout<T>.size <= _storage.capacity,
|
||||
"Reading out of bounds is illegal")
|
||||
return _storage.memory.advanced(by: position).load(as: T.self)
|
||||
_storage.memory.advanced(by: position).load(as: T.self)
|
||||
}
|
||||
|
||||
/// Reads a slice from the memory assuming a type of T
|
||||
@ -329,14 +335,14 @@ public struct ByteBuffer {
|
||||
/// - count: count of bytes in memory
|
||||
@inline(__always)
|
||||
public func readSlice<T>(
|
||||
index: Int32,
|
||||
count: Int32) -> [T]
|
||||
index: Int,
|
||||
count: Int) -> [T]
|
||||
{
|
||||
let _index = Int(index)
|
||||
let _count = Int(count)
|
||||
assert(_index + _count <= _storage.capacity, "Reading out of bounds is illegal")
|
||||
let start = _storage.memory.advanced(by: _index).assumingMemoryBound(to: T.self)
|
||||
let array = UnsafeBufferPointer(start: start, count: _count)
|
||||
assert(
|
||||
index + count <= _storage.capacity,
|
||||
"Reading out of bounds is illegal")
|
||||
let start = _storage.memory.advanced(by: index).assumingMemoryBound(to: T.self)
|
||||
let array = UnsafeBufferPointer(start: start, count: count)
|
||||
return Array(array)
|
||||
}
|
||||
|
||||
@ -345,17 +351,16 @@ public struct ByteBuffer {
|
||||
/// - index: index of the string in the buffer
|
||||
/// - count: length of the string
|
||||
/// - type: Encoding of the string
|
||||
@inline(__always)
|
||||
public func readString(
|
||||
at index: Int32,
|
||||
count: Int32,
|
||||
at index: Int,
|
||||
count: Int,
|
||||
type: String.Encoding = .utf8) -> String?
|
||||
{
|
||||
let _index = Int(index)
|
||||
let _count = Int(count)
|
||||
assert(_index + _count <= _storage.capacity, "Reading out of bounds is illegal")
|
||||
let start = _storage.memory.advanced(by: _index).assumingMemoryBound(to: UInt8.self)
|
||||
let bufprt = UnsafeBufferPointer(start: start, count: _count)
|
||||
assert(
|
||||
index + count <= _storage.capacity,
|
||||
"Reading out of bounds is illegal")
|
||||
let start = _storage.memory.advanced(by: index).assumingMemoryBound(to: UInt8.self)
|
||||
let bufprt = UnsafeBufferPointer(start: start, count: count)
|
||||
return String(bytes: Array(bufprt), encoding: type)
|
||||
}
|
||||
|
||||
@ -363,12 +368,22 @@ public struct ByteBuffer {
|
||||
/// - Parameter removeBytes: the amount of bytes to remove from the current Size
|
||||
public func duplicate(removing removeBytes: Int = 0) -> ByteBuffer {
|
||||
assert(removeBytes > 0, "Can NOT remove negative bytes")
|
||||
assert(removeBytes < _storage.capacity, "Can NOT remove more bytes than the ones allocated")
|
||||
assert(
|
||||
removeBytes < _storage.capacity,
|
||||
"Can NOT remove more bytes than the ones allocated")
|
||||
return ByteBuffer(
|
||||
memory: _storage.memory,
|
||||
count: _storage.capacity,
|
||||
removing: _writerSize &- removeBytes)
|
||||
}
|
||||
|
||||
/// SkipPrefix Skips the first 4 bytes in case one of the following
|
||||
/// functions are called `getPrefixedSizeCheckedRoot` & `getPrefixedSizeRoot`
|
||||
/// which allows us to skip the first 4 bytes instead of recreating the buffer
|
||||
@usableFromInline
|
||||
mutating func skipPrefix() {
|
||||
_writerSize = _writerSize &- MemoryLayout<Int32>.size
|
||||
}
|
||||
}
|
||||
|
||||
extension ByteBuffer: CustomDebugStringConvertible {
|
||||
|
@ -32,14 +32,16 @@ public typealias VOffset = UInt16
|
||||
/// Maximum size for a buffer
|
||||
public let FlatBufferMaxSize = UInt32.max << ((MemoryLayout<SOffset>.size * 8 - 1) - 1)
|
||||
|
||||
/// Protocol that confirms all the numbers
|
||||
/// Protocol that All Scalars should conform to
|
||||
///
|
||||
/// Scalar is used to confirm all the numbers that can be represented in a FlatBuffer. It's used to write/read from the buffer.
|
||||
/// Scalar is used to conform all the numbers that can be represented in a FlatBuffer. It's used to write/read from the buffer.
|
||||
public protocol Scalar: Equatable {
|
||||
associatedtype NumericValue
|
||||
var convertedEndian: NumericValue { get }
|
||||
}
|
||||
|
||||
extension Scalar where Self: Verifiable {}
|
||||
|
||||
extension Scalar where Self: FixedWidthInteger {
|
||||
/// Converts the value from BigEndian to LittleEndian
|
||||
///
|
||||
@ -49,7 +51,7 @@ extension Scalar where Self: FixedWidthInteger {
|
||||
}
|
||||
}
|
||||
|
||||
extension Double: Scalar {
|
||||
extension Double: Scalar, Verifiable {
|
||||
public typealias NumericValue = UInt64
|
||||
|
||||
public var convertedEndian: UInt64 {
|
||||
@ -57,7 +59,7 @@ extension Double: Scalar {
|
||||
}
|
||||
}
|
||||
|
||||
extension Float32: Scalar {
|
||||
extension Float32: Scalar, Verifiable {
|
||||
public typealias NumericValue = UInt32
|
||||
|
||||
public var convertedEndian: UInt32 {
|
||||
@ -65,7 +67,7 @@ extension Float32: Scalar {
|
||||
}
|
||||
}
|
||||
|
||||
extension Bool: Scalar {
|
||||
extension Bool: Scalar, Verifiable {
|
||||
public var convertedEndian: UInt8 {
|
||||
self == true ? 1 : 0
|
||||
}
|
||||
@ -73,39 +75,39 @@ extension Bool: Scalar {
|
||||
public typealias NumericValue = UInt8
|
||||
}
|
||||
|
||||
extension Int: Scalar {
|
||||
extension Int: Scalar, Verifiable {
|
||||
public typealias NumericValue = Int
|
||||
}
|
||||
|
||||
extension Int8: Scalar {
|
||||
extension Int8: Scalar, Verifiable {
|
||||
public typealias NumericValue = Int8
|
||||
}
|
||||
|
||||
extension Int16: Scalar {
|
||||
extension Int16: Scalar, Verifiable {
|
||||
public typealias NumericValue = Int16
|
||||
}
|
||||
|
||||
extension Int32: Scalar {
|
||||
extension Int32: Scalar, Verifiable {
|
||||
public typealias NumericValue = Int32
|
||||
}
|
||||
|
||||
extension Int64: Scalar {
|
||||
extension Int64: Scalar, Verifiable {
|
||||
public typealias NumericValue = Int64
|
||||
}
|
||||
|
||||
extension UInt8: Scalar {
|
||||
extension UInt8: Scalar, Verifiable {
|
||||
public typealias NumericValue = UInt8
|
||||
}
|
||||
|
||||
extension UInt16: Scalar {
|
||||
extension UInt16: Scalar, Verifiable {
|
||||
public typealias NumericValue = UInt16
|
||||
}
|
||||
|
||||
extension UInt32: Scalar {
|
||||
extension UInt32: Scalar, Verifiable {
|
||||
public typealias NumericValue = UInt32
|
||||
}
|
||||
|
||||
extension UInt64: Scalar {
|
||||
extension UInt64: Scalar, Verifiable {
|
||||
public typealias NumericValue = UInt64
|
||||
}
|
||||
|
||||
|
54
swift/Sources/FlatBuffers/Enum.swift
Normal file
54
swift/Sources/FlatBuffers/Enum.swift
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Enum is a protocol that all flatbuffers enums should conform to
|
||||
/// Since it allows us to get the actual `ByteSize` and `Value`
|
||||
public protocol Enum {
|
||||
/// associatedtype that the type of the enum should conform to
|
||||
associatedtype T: Scalar & Verifiable
|
||||
/// Size of the current associatedtype in the enum
|
||||
static var byteSize: Int { get }
|
||||
/// The current value the enum hosts
|
||||
var value: T { get }
|
||||
}
|
||||
|
||||
extension Enum where Self: Verifiable {
|
||||
|
||||
/// Verifies that the current value is which the bounds of the buffer, and if
|
||||
/// the current `Value` is aligned properly
|
||||
/// - Parameters:
|
||||
/// - verifier: Verifier that hosts the buffer
|
||||
/// - position: Current position within the buffer
|
||||
/// - type: The type of the object to be verified
|
||||
/// - Throws: Errors coming from `inBuffer` function
|
||||
public static func verify<T>(
|
||||
_ verifier: inout Verifier,
|
||||
at position: Int,
|
||||
of type: T.Type) throws where T: Verifiable
|
||||
{
|
||||
try verifier.inBuffer(position: position, of: type.self)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// UnionEnum is a Protocol that allows us to create Union type of enums
|
||||
/// and their value initializers. Since an `init` was required by
|
||||
/// the verifier
|
||||
public protocol UnionEnum: Enum {
|
||||
init?(value: T) throws
|
||||
}
|
@ -16,6 +16,9 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
/// `FlatBufferBuilder` builds a `FlatBuffer` through manipulating its internal state.
|
||||
/// This is done by creating a `ByteBuffer` that hosts the incoming data and
|
||||
/// has a hardcoded growth limit of `2GiB` which is set by the Flatbuffers standards
|
||||
@frozen
|
||||
public struct FlatBufferBuilder {
|
||||
|
||||
@ -74,7 +77,9 @@ public struct FlatBufferBuilder {
|
||||
/// Returns A sized Buffer from the readable bytes
|
||||
public var sizedBuffer: ByteBuffer {
|
||||
assert(finished, "Data shouldn't be called before finish()")
|
||||
return ByteBuffer(memory: _bb.memory.advanced(by: _bb.reader), count: Int(_bb.size))
|
||||
return ByteBuffer(
|
||||
memory: _bb.memory.advanced(by: _bb.reader),
|
||||
count: Int(_bb.size))
|
||||
}
|
||||
|
||||
// MARK: - Init
|
||||
@ -112,7 +117,9 @@ public struct FlatBufferBuilder {
|
||||
for field in fields {
|
||||
let start = _bb.capacity &- Int(table.o)
|
||||
let startTable = start &- Int(_bb.read(def: Int32.self, position: start))
|
||||
let isOkay = _bb.read(def: VOffset.self, position: startTable &+ Int(field)) != 0
|
||||
let isOkay = _bb.read(
|
||||
def: VOffset.self,
|
||||
position: startTable &+ Int(field)) != 0
|
||||
assert(isOkay, "Flatbuffers requires the following field")
|
||||
}
|
||||
}
|
||||
@ -122,9 +129,15 @@ public struct FlatBufferBuilder {
|
||||
/// - offset: Offset of the table
|
||||
/// - fileId: Takes the fileId
|
||||
/// - prefix: if false it wont add the size of the buffer
|
||||
mutating public func finish(offset: Offset, fileId: String, addPrefix prefix: Bool = false) {
|
||||
mutating public func finish(
|
||||
offset: Offset,
|
||||
fileId: String,
|
||||
addPrefix prefix: Bool = false)
|
||||
{
|
||||
let size = MemoryLayout<UOffset>.size
|
||||
preAlign(len: size &+ (prefix ? size : 0) &+ FileIdLength, alignment: _minAlignment)
|
||||
preAlign(
|
||||
len: size &+ (prefix ? size : 0) &+ FileIdLength,
|
||||
alignment: _minAlignment)
|
||||
assert(fileId.count == FileIdLength, "Flatbuffers requires file id to be 4")
|
||||
_bb.push(string: fileId, len: 4)
|
||||
finish(offset: offset, addPrefix: prefix)
|
||||
@ -134,7 +147,10 @@ public struct FlatBufferBuilder {
|
||||
/// - Parameters:
|
||||
/// - offset: Offset of the table
|
||||
/// - prefix: if false it wont add the size of the buffer
|
||||
mutating public func finish(offset: Offset, addPrefix prefix: Bool = false) {
|
||||
mutating public func finish(
|
||||
offset: Offset,
|
||||
addPrefix prefix: Bool = false)
|
||||
{
|
||||
notNested()
|
||||
let size = MemoryLayout<UOffset>.size
|
||||
preAlign(len: size &+ (prefix ? size : 0), alignment: _minAlignment)
|
||||
@ -184,7 +200,10 @@ public struct FlatBufferBuilder {
|
||||
itr = itr &+ _vtableStorage.size
|
||||
guard loaded.offset != 0 else { continue }
|
||||
let _index = (_bb.writerIndex &+ Int(loaded.position))
|
||||
_bb.write(value: VOffset(vTableOffset &- loaded.offset), index: _index, direct: true)
|
||||
_bb.write(
|
||||
value: VOffset(vTableOffset &- loaded.offset),
|
||||
index: _index,
|
||||
direct: true)
|
||||
}
|
||||
|
||||
_vtableStorage.clear()
|
||||
@ -375,7 +394,9 @@ public struct FlatBufferBuilder {
|
||||
/// - Parameter structs: A vector of structs
|
||||
/// - Returns: offset of the vector
|
||||
mutating public func createVector<T: NativeStruct>(ofStructs structs: [T]) -> Offset {
|
||||
startVector(structs.count * MemoryLayout<T>.size, elementSize: MemoryLayout<T>.alignment)
|
||||
startVector(
|
||||
structs.count * MemoryLayout<T>.size,
|
||||
elementSize: MemoryLayout<T>.alignment)
|
||||
for i in structs.reversed() {
|
||||
_ = create(struct: i)
|
||||
}
|
||||
@ -394,7 +415,9 @@ public struct FlatBufferBuilder {
|
||||
struct s: T, position: VOffset) -> Offset
|
||||
{
|
||||
let offset = create(struct: s)
|
||||
_vtableStorage.add(loc: FieldLoc(offset: _bb.size, position: VOffset(position)))
|
||||
_vtableStorage.add(loc: FieldLoc(
|
||||
offset: _bb.size,
|
||||
position: VOffset(position)))
|
||||
return offset
|
||||
}
|
||||
|
||||
@ -529,8 +552,6 @@ extension FlatBufferBuilder: CustomDebugStringConvertible {
|
||||
var numOfFields: Int = 0
|
||||
/// Last written Index
|
||||
var writtenIndex: Int = 0
|
||||
/// the amount of added elements into the buffer
|
||||
var addedElements: Int { capacity - (numOfFields &* size) }
|
||||
|
||||
/// Creates the memory to store the buffer in
|
||||
@usableFromInline
|
||||
@ -555,7 +576,9 @@ extension FlatBufferBuilder: CustomDebugStringConvertible {
|
||||
/// and max offset
|
||||
/// - Parameter loc: Location of encoded element
|
||||
func add(loc: FieldLoc) {
|
||||
memory.baseAddress?.advanced(by: writtenIndex).storeBytes(of: loc, as: FieldLoc.self)
|
||||
memory.baseAddress?.advanced(by: writtenIndex).storeBytes(
|
||||
of: loc,
|
||||
as: FieldLoc.self)
|
||||
writtenIndex = writtenIndex &+ size
|
||||
numOfFields = numOfFields &+ 1
|
||||
maxOffset = max(loc.position, maxOffset)
|
||||
@ -574,7 +597,9 @@ extension FlatBufferBuilder: CustomDebugStringConvertible {
|
||||
func ensure(space: Int) {
|
||||
guard space &+ writtenIndex > capacity else { return }
|
||||
memory.deallocate()
|
||||
memory = UnsafeMutableRawBufferPointer.allocate(byteCount: space, alignment: size)
|
||||
memory = UnsafeMutableRawBufferPointer.allocate(
|
||||
byteCount: space,
|
||||
alignment: size)
|
||||
capacity = space
|
||||
}
|
||||
|
||||
|
@ -31,15 +31,26 @@ public protocol FlatBufferObject: FlatbuffersInitializable {
|
||||
var __buffer: ByteBuffer! { get }
|
||||
}
|
||||
|
||||
/// `ObjectAPIPacker` is a protocol that allows object to pack and unpack from a
|
||||
/// `NativeObject` to a flatbuffers Object and vice versa.
|
||||
public protocol ObjectAPIPacker {
|
||||
/// associatedtype to the object that should be unpacked.
|
||||
associatedtype T
|
||||
|
||||
/// `pack` tries packs the variables of a native Object into the `ByteBuffer` by using
|
||||
/// the FlatBufferBuilder
|
||||
/// - Parameters:
|
||||
/// - builder: FlatBufferBuilder that will host incoming data
|
||||
/// - obj: Object of associatedtype to the current implementer
|
||||
static func pack(_ builder: inout FlatBufferBuilder, obj: inout T?) -> Offset
|
||||
|
||||
/// `pack` packs the variables of a native Object into the `ByteBuffer` by using
|
||||
/// the FlatBufferBuilder
|
||||
/// - Parameters:
|
||||
/// - builder: FlatBufferBuilder that will host incoming data
|
||||
/// - obj: Object of associatedtype to the current implementer
|
||||
static func pack(_ builder: inout FlatBufferBuilder, obj: inout T) -> Offset
|
||||
|
||||
/// `Unpack` unpacks a flatbuffers object into a `NativeObject`
|
||||
mutating func unpack() -> T
|
||||
}
|
||||
|
||||
public protocol Enum {
|
||||
associatedtype T: Scalar
|
||||
static var byteSize: Int { get }
|
||||
var value: T { get }
|
||||
}
|
||||
|
@ -16,7 +16,8 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public final class FlatBuffersUtils {
|
||||
/// FlatBuffersUtils hosts some utility functions that might be useful
|
||||
public enum FlatBuffersUtils {
|
||||
|
||||
/// Gets the size of the prefix
|
||||
/// - Parameter bb: Flatbuffer object
|
||||
@ -24,7 +25,9 @@ public final class FlatBuffersUtils {
|
||||
bb.read(def: Int32.self, position: bb.reader)
|
||||
}
|
||||
|
||||
/// Removes the prefix by duplicating the Flatbuffer
|
||||
/// Removes the prefix by duplicating the Flatbuffer this call is expensive since its
|
||||
/// creates a new buffer use `readPrefixedSizeCheckedRoot` instead
|
||||
/// unless a completely new buffer is required
|
||||
/// - Parameter bb: Flatbuffer object
|
||||
public static func removeSizePrefix(bb: ByteBuffer) -> ByteBuffer {
|
||||
bb.duplicate(removing: MemoryLayout<Int32>.size)
|
||||
|
59
swift/Sources/FlatBuffers/FlatbuffersErrors.swift
Normal file
59
swift/Sources/FlatBuffers/FlatbuffersErrors.swift
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Collection of thrown from the Flatbuffer verifier
|
||||
public enum FlatbuffersErrors: Error, Equatable {
|
||||
|
||||
/// Thrown when buffer is bigger than the allowed 2GiB
|
||||
case exceedsMaxSizeAllowed
|
||||
/// Thrown when there is an missaligned pointer at position
|
||||
/// of type
|
||||
case missAlignedPointer(position: Int, type: String)
|
||||
/// Thrown when trying to read a value that goes out of the
|
||||
/// current buffer bounds
|
||||
case outOfBounds(position: UInt, end: Int)
|
||||
/// Thrown when the signed offset is out of the bounds of the
|
||||
/// current buffer
|
||||
case signedOffsetOutOfBounds(offset: Int, position: Int)
|
||||
/// Thrown when a required field doesnt exist within the buffer
|
||||
case requiredFieldDoesntExist(position: VOffset, name: String)
|
||||
/// Thrown when a string is missing its NULL Terminator `\0`,
|
||||
/// this can be disabled in the `VerifierOptions`
|
||||
case missingNullTerminator(position: Int, str: String?)
|
||||
/// Thrown when the verifier has reached the maximum tables allowed,
|
||||
/// this can be disabled in the `VerifierOptions`
|
||||
case maximumTables
|
||||
/// Thrown when the verifier has reached the maximum depth allowed,
|
||||
/// this can be disabled in the `VerifierOptions`
|
||||
case maximumDepth
|
||||
/// Thrown when the verifier is presented with an unknown union case
|
||||
case unknownUnionCase
|
||||
/// thrown when a value for a union is not found within the buffer
|
||||
case valueNotFound(key: Int?, keyName: String, field: Int?, fieldName: String)
|
||||
/// thrown when the size of the keys vector doesnt match fields vector
|
||||
case unionVectorSize(
|
||||
keyVectorSize: Int,
|
||||
fieldVectorSize: Int,
|
||||
unionKeyName: String,
|
||||
fieldName: String)
|
||||
case apparentSizeTooLarge
|
||||
|
||||
public static func == (lhs: FlatbuffersErrors, rhs: FlatbuffersErrors) -> Bool {
|
||||
lhs.localizedDescription == rhs.localizedDescription
|
||||
}
|
||||
}
|
@ -14,6 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
/// FlatBufferGRPCMessage protocol that should allow us to invoke
|
||||
/// initializers directly from the GRPC generated code
|
||||
public protocol FlatBufferGRPCMessage {
|
||||
|
||||
/// Raw pointer which would be pointing to the beginning of the readable bytes
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
/// NativeObject is a protocol that all of the `Object-API` generated code should be
|
||||
/// conforming to since it allows developers the ease of use to pack and unpack their
|
||||
/// Flatbuffers objects
|
||||
public protocol NativeObject {}
|
||||
|
||||
extension NativeObject {
|
||||
@ -36,7 +39,10 @@ extension NativeObject {
|
||||
/// - Returns: returns the encoded sized ByteBuffer
|
||||
/// - Note: The `serialize(builder:type)` can be considered as a function that allows you to create smaller builder instead of the default `1024`.
|
||||
/// It can be considered less expensive in terms of memory allocation
|
||||
public func serialize<T: ObjectAPIPacker>(builder: inout FlatBufferBuilder, type: T.Type) -> ByteBuffer where T.T == Self {
|
||||
public func serialize<T: ObjectAPIPacker>(
|
||||
builder: inout FlatBufferBuilder,
|
||||
type: T.Type) -> ByteBuffer where T.T == Self
|
||||
{
|
||||
var s = self
|
||||
let root = type.pack(&builder, obj: &s)
|
||||
builder.finish(offset: root)
|
||||
|
68
swift/Sources/FlatBuffers/Root.swift
Normal file
68
swift/Sources/FlatBuffers/Root.swift
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Takes in a prefixed sized buffer, where the prefixed size would be skipped.
|
||||
/// And would verify that the buffer passed is a valid `Flatbuffers` Object.
|
||||
/// - Parameters:
|
||||
/// - byteBuffer: Buffer that needs to be checked and read
|
||||
/// - options: Verifier options
|
||||
/// - Throws: FlatbuffersErrors
|
||||
/// - Returns: Returns a valid, checked Flatbuffers object
|
||||
public func getPrefixedSizeCheckedRoot<T: FlatBufferObject & Verifiable>(
|
||||
byteBuffer: inout ByteBuffer,
|
||||
options: VerifierOptions = .init()) throws -> T
|
||||
{
|
||||
byteBuffer.skipPrefix()
|
||||
return try getCheckedRoot(byteBuffer: &byteBuffer, options: options)
|
||||
}
|
||||
|
||||
/// Takes in a prefixed sized buffer, where the prefixed size would be skipped.
|
||||
/// Returns a `NON-Checked` flatbuffers object
|
||||
/// - Parameter byteBuffer: Buffer that contains data
|
||||
/// - Returns: Returns a Flatbuffers object
|
||||
public func getPrefixedSizeRoot<T: FlatBufferObject>(byteBuffer: inout ByteBuffer) -> T {
|
||||
byteBuffer.skipPrefix()
|
||||
return getRoot(byteBuffer: &byteBuffer)
|
||||
|
||||
}
|
||||
|
||||
/// Verifies that the buffer passed is a valid `Flatbuffers` Object.
|
||||
/// - Parameters:
|
||||
/// - byteBuffer: Buffer that needs to be checked and read
|
||||
/// - options: Verifier options
|
||||
/// - Throws: FlatbuffersErrors
|
||||
/// - Returns: Returns a valid, checked Flatbuffers object
|
||||
public func getCheckedRoot<T: FlatBufferObject & Verifiable>(
|
||||
byteBuffer: inout ByteBuffer,
|
||||
options: VerifierOptions = .init()) throws -> T
|
||||
{
|
||||
var verifier = try Verifier(buffer: &byteBuffer, options: options)
|
||||
try ForwardOffset<T>.verify(&verifier, at: 0, of: T.self)
|
||||
return T.init(
|
||||
byteBuffer,
|
||||
o: Int32(byteBuffer.read(def: UOffset.self, position: byteBuffer.reader)) + Int32(byteBuffer.reader))
|
||||
}
|
||||
|
||||
/// Returns a `NON-Checked` flatbuffers object
|
||||
/// - Parameter byteBuffer: Buffer that contains data
|
||||
/// - Returns: Returns a Flatbuffers object
|
||||
public func getRoot<T: FlatBufferObject>(byteBuffer: inout ByteBuffer) -> T {
|
||||
T.init(
|
||||
byteBuffer,
|
||||
o: Int32(byteBuffer.read(def: UOffset.self, position: byteBuffer.reader)) + Int32(byteBuffer.reader))
|
||||
}
|
@ -16,6 +16,42 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
extension String: Verifiable {
|
||||
|
||||
/// Verifies that the current value is which the bounds of the buffer, and if
|
||||
/// the current `Value` is aligned properly
|
||||
/// - Parameters:
|
||||
/// - verifier: Verifier that hosts the buffer
|
||||
/// - position: Current position within the buffer
|
||||
/// - type: The type of the object to be verified
|
||||
/// - Throws: Errors coming from `inBuffer`, `missingNullTerminator` and `outOfBounds`
|
||||
public static func verify<T>(
|
||||
_ verifier: inout Verifier,
|
||||
at position: Int,
|
||||
of type: T.Type) throws where T: Verifiable
|
||||
{
|
||||
|
||||
let range = try String.verifyRange(&verifier, at: position, of: UInt8.self)
|
||||
/// Safe &+ since we already check for overflow in verify range
|
||||
let stringLen = range.start &+ range.count
|
||||
|
||||
if stringLen >= verifier.capacity {
|
||||
throw FlatbuffersErrors.outOfBounds(
|
||||
position: UInt(clamping: stringLen.magnitude),
|
||||
end: verifier.capacity)
|
||||
}
|
||||
|
||||
let isNullTerminated = verifier._buffer.read(
|
||||
def: UInt8.self,
|
||||
position: stringLen) == 0
|
||||
|
||||
if !verifier._options._ignoreMissingNullTerminators && !isNullTerminated {
|
||||
let str = verifier._buffer.readString(at: range.start, count: range.count)
|
||||
throw FlatbuffersErrors.missingNullTerminator(position: position, str: str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension String: FlatbuffersInitializable {
|
||||
|
||||
/// Initailizes a string from a Flatbuffers ByteBuffer
|
||||
@ -23,10 +59,11 @@ extension String: FlatbuffersInitializable {
|
||||
/// - bb: ByteBuffer containing the readable string
|
||||
/// - o: Current position
|
||||
public init(_ bb: ByteBuffer, o: Int32) {
|
||||
let count = bb.read(def: Int32.self, position: Int(o))
|
||||
let v = Int(o)
|
||||
let count = bb.read(def: Int32.self, position: v)
|
||||
self = bb.readString(
|
||||
at: Int32(MemoryLayout<Int32>.size) + o,
|
||||
count: count) ?? ""
|
||||
at: MemoryLayout<Int32>.size + v,
|
||||
count: Int(count)) ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,7 +90,10 @@ extension String: NativeObject {
|
||||
fatalError("serialize should never be called from string directly")
|
||||
}
|
||||
|
||||
public func serialize<T: ObjectAPIPacker>(builder: inout FlatBufferBuilder, type: T.Type) -> ByteBuffer where T.T == Self {
|
||||
public func serialize<T: ObjectAPIPacker>(
|
||||
builder: inout FlatBufferBuilder,
|
||||
type: T.Type) -> ByteBuffer where T.T == Self
|
||||
{
|
||||
fatalError("serialize should never be called from string directly")
|
||||
}
|
||||
}
|
||||
|
@ -16,16 +16,30 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Struct is a representation of a mutable `Flatbuffers` struct
|
||||
/// since native structs are value types and cant be mutated
|
||||
@frozen
|
||||
public struct Struct {
|
||||
|
||||
/// Hosting Bytebuffer
|
||||
public private(set) var bb: ByteBuffer
|
||||
/// Current position of the struct
|
||||
public private(set) var postion: Int32
|
||||
|
||||
/// Initializer for a mutable flatbuffers struct
|
||||
/// - Parameters:
|
||||
/// - bb: Current hosting Bytebuffer
|
||||
/// - position: Current position for the struct in the ByteBuffer
|
||||
public init(bb: ByteBuffer, position: Int32 = 0) {
|
||||
self.bb = bb
|
||||
postion = position
|
||||
}
|
||||
|
||||
/// Reads data from the buffer directly at offset O
|
||||
/// - Parameters:
|
||||
/// - type: Type of data to be read
|
||||
/// - o: Current offset of the data
|
||||
/// - Returns: Data of Type T that conforms to type Scalar
|
||||
public func readBuffer<T: Scalar>(of type: T.Type, at o: Int32) -> T {
|
||||
let r = bb.read(def: T.self, position: Int(o + postion))
|
||||
return r
|
||||
|
@ -16,11 +16,22 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
/// `Table` is a Flatbuffers object that can read,
|
||||
/// mutate scalar fields within a valid flatbuffers buffer
|
||||
@frozen
|
||||
public struct Table {
|
||||
|
||||
/// Hosting Bytebuffer
|
||||
public private(set) var bb: ByteBuffer
|
||||
/// Current position of the table within the buffer
|
||||
public private(set) var postion: Int32
|
||||
|
||||
/// Initializer for the table interface to allow generated code to read
|
||||
/// data from memory
|
||||
/// - Parameters:
|
||||
/// - bb: ByteBuffer that stores data
|
||||
/// - position: Current table position
|
||||
/// - Note: This will `CRASH` if read on a big endian machine
|
||||
public init(bb: ByteBuffer, position: Int32 = 0) {
|
||||
guard isLitteEndian else {
|
||||
fatalError("Reading/Writing a buffer in big endian machine is not supported on swift")
|
||||
@ -29,6 +40,10 @@ public struct Table {
|
||||
postion = position
|
||||
}
|
||||
|
||||
/// Gets the offset of the current field within the buffer by reading
|
||||
/// the vtable
|
||||
/// - Parameter o: current offset
|
||||
/// - Returns: offset of field within buffer
|
||||
public func offset(_ o: Int32) -> Int32 {
|
||||
let vtable = postion - bb.read(def: Int32.self, position: Int(postion))
|
||||
return o < bb.read(def: VOffset.self, position: Int(vtable)) ? Int32(bb.read(
|
||||
@ -36,7 +51,13 @@ public struct Table {
|
||||
position: Int(vtable + o))) : 0
|
||||
}
|
||||
|
||||
public func indirect(_ o: Int32) -> Int32 { o + bb.read(def: Int32.self, position: Int(o)) }
|
||||
/// Gets the indirect offset of the current stored object
|
||||
/// (applicable only for object arrays)
|
||||
/// - Parameter o: current offset
|
||||
/// - Returns: offset of field within buffer
|
||||
public func indirect(_ o: Int32) -> Int32 {
|
||||
o + bb.read(def: Int32.self, position: Int(o))
|
||||
}
|
||||
|
||||
/// String reads from the buffer with respect to position of the current table.
|
||||
/// - Parameter offset: Offset of the string
|
||||
@ -45,14 +66,15 @@ public struct Table {
|
||||
}
|
||||
|
||||
/// Direct string reads from the buffer disregarding the position of the table.
|
||||
/// It would be preferable to use string unless the current position of the table is not needed
|
||||
/// It would be preferable to use string unless the current position of the table
|
||||
/// is not needed
|
||||
/// - Parameter offset: Offset of the string
|
||||
public func directString(at offset: Int32) -> String? {
|
||||
var offset = offset
|
||||
offset += bb.read(def: Int32.self, position: Int(offset))
|
||||
let count = bb.read(def: Int32.self, position: Int(offset))
|
||||
let position = offset + Int32(MemoryLayout<Int32>.size)
|
||||
return bb.readString(at: position, count: count)
|
||||
let position = Int(offset) + MemoryLayout<Int32>.size
|
||||
return bb.readString(at: position, count: Int(count))
|
||||
}
|
||||
|
||||
/// Reads from the buffer with respect to the position in the table.
|
||||
@ -81,19 +103,30 @@ public struct Table {
|
||||
return r
|
||||
}
|
||||
|
||||
/// Returns that current `Union` object at a specific offset
|
||||
/// by adding offset to the current position of table
|
||||
/// - Parameter o: offset
|
||||
/// - Returns: A flatbuffers object
|
||||
public func union<T: FlatbuffersInitializable>(_ o: Int32) -> T {
|
||||
let o = o + postion
|
||||
return directUnion(o)
|
||||
}
|
||||
|
||||
/// Returns a direct `Union` object at a specific offset
|
||||
/// - Parameter o: offset
|
||||
/// - Returns: A flatbuffers object
|
||||
public func directUnion<T: FlatbuffersInitializable>(_ o: Int32) -> T {
|
||||
T.init(bb, o: o + bb.read(def: Int32.self, position: Int(o)))
|
||||
}
|
||||
|
||||
/// Returns a vector of type T at a specific offset
|
||||
/// This should only be used by `Scalars`
|
||||
/// - Parameter off: Readable offset
|
||||
/// - Returns: Returns a vector of type [T]
|
||||
public func getVector<T>(at off: Int32) -> [T]? {
|
||||
let o = offset(off)
|
||||
guard o != 0 else { return nil }
|
||||
return bb.readSlice(index: vector(at: o), count: vector(count: o))
|
||||
return bb.readSlice(index: Int(vector(at: o)), count: Int(vector(count: o)))
|
||||
}
|
||||
|
||||
/// Vector count gets the count of Elements within the array
|
||||
@ -115,17 +148,36 @@ public struct Table {
|
||||
return o + bb.read(def: Int32.self, position: Int(o)) + 4
|
||||
}
|
||||
|
||||
static public func indirect(_ o: Int32, _ fbb: ByteBuffer) -> Int32 { o + fbb.read(
|
||||
def: Int32.self,
|
||||
position: Int(o)) }
|
||||
/// Reading an indirect offset of a table.
|
||||
/// - Parameters:
|
||||
/// - o: position within the buffer
|
||||
/// - fbb: ByteBuffer
|
||||
/// - Returns: table offset
|
||||
static public func indirect(_ o: Int32, _ fbb: ByteBuffer) -> Int32 {
|
||||
o + fbb.read(def: Int32.self, position: Int(o))
|
||||
}
|
||||
|
||||
/// Gets a vtable value according to an table Offset and a field offset
|
||||
/// - Parameters:
|
||||
/// - o: offset relative to entire buffer
|
||||
/// - vOffset: Field offset within a vtable
|
||||
/// - fbb: ByteBuffer
|
||||
/// - Returns: an position of a field
|
||||
static public func offset(_ o: Int32, vOffset: Int32, fbb: ByteBuffer) -> Int32 {
|
||||
let vTable = Int32(fbb.capacity) - o
|
||||
return vTable + Int32(fbb.read(
|
||||
def: Int16.self,
|
||||
position: Int(vTable + vOffset - fbb.read(def: Int32.self, position: Int(vTable)))))
|
||||
position: Int(vTable + vOffset - fbb.read(
|
||||
def: Int32.self,
|
||||
position: Int(vTable)))))
|
||||
}
|
||||
|
||||
/// Compares two objects at offset A and offset B within a ByteBuffer
|
||||
/// - Parameters:
|
||||
/// - off1: first offset to compare
|
||||
/// - off2: second offset to compare
|
||||
/// - fbb: Bytebuffer
|
||||
/// - Returns: returns the difference between
|
||||
static public func compare(_ off1: Int32, _ off2: Int32, fbb: ByteBuffer) -> Int32 {
|
||||
let memorySize = Int32(MemoryLayout<Int32>.size)
|
||||
let _off1 = off1 + fbb.read(def: Int32.self, position: Int(off1))
|
||||
@ -145,6 +197,12 @@ public struct Table {
|
||||
return len1 - len2
|
||||
}
|
||||
|
||||
/// Compares two objects at offset A and array of `Bytes` within a ByteBuffer
|
||||
/// - Parameters:
|
||||
/// - off1: Offset to compare to
|
||||
/// - key: bytes array to compare to
|
||||
/// - fbb: Bytebuffer
|
||||
/// - Returns: returns the difference between
|
||||
static public func compare(_ off1: Int32, _ key: [Byte], fbb: ByteBuffer) -> Int32 {
|
||||
let memorySize = Int32(MemoryLayout<Int32>.size)
|
||||
let _off1 = off1 + fbb.read(def: Int32.self, position: Int(off1))
|
||||
|
202
swift/Sources/FlatBuffers/TableVerifier.swift
Normal file
202
swift/Sources/FlatBuffers/TableVerifier.swift
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
/// `TableVerifier` verifies a table object is within a provided memory.
|
||||
/// It checks if all the objects for a specific generated table, are within
|
||||
/// the bounds of the buffer, aligned.
|
||||
public struct TableVerifier {
|
||||
|
||||
/// position of current table in `ByteBuffer`
|
||||
fileprivate var _position: Int
|
||||
|
||||
/// Current VTable position
|
||||
fileprivate var _vtable: Int
|
||||
|
||||
/// Length of current VTable
|
||||
fileprivate var _vtableLength: Int
|
||||
|
||||
/// `Verifier` object created in the base verifable call.
|
||||
fileprivate var _verifier: Verifier
|
||||
|
||||
/// Creates a `TableVerifier` verifier that allows the Flatbuffer object
|
||||
/// to verify the buffer before accessing any of the data.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - position: Current table Position
|
||||
/// - vtable: Current `VTable` position
|
||||
/// - vtableLength: Current `VTable` length
|
||||
/// - verifier: `Verifier` Object that caches the data of the verifiable object
|
||||
internal init(
|
||||
position: Int,
|
||||
vtable: Int,
|
||||
vtableLength: Int,
|
||||
verifier: inout Verifier)
|
||||
{
|
||||
_position = position
|
||||
_vtable = vtable
|
||||
_vtableLength = vtableLength
|
||||
_verifier = verifier
|
||||
}
|
||||
|
||||
/// Dereference the current object position from the `VTable`
|
||||
/// - Parameter field: Current VTable refrence to position.
|
||||
/// - Throws: A `FlatbuffersErrors` incase the voffset is not aligned/outOfBounds/apparentSizeTooLarge
|
||||
/// - Returns: An optional position for current field
|
||||
internal mutating func dereference(_ field: VOffset) throws -> Int? {
|
||||
if field >= _vtableLength {
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Reading the offset for the field needs to be read.
|
||||
let offset: VOffset = try _verifier.getValue(
|
||||
at: Int(clamping: _vtable &+ Int(field))
|
||||
)
|
||||
|
||||
if offset > 0 {
|
||||
return Int(clamping: _position &+ Int(offset))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Visits all the fields within the table to validate the integrity
|
||||
/// of the data
|
||||
/// - Parameters:
|
||||
/// - field: voffset of the current field to be read
|
||||
/// - fieldName: fieldname to report data Errors.
|
||||
/// - required: If the field has to be available in the buffer
|
||||
/// - type: Type of field to be read
|
||||
/// - Throws: A `FlatbuffersErrors` where the field is corrupt
|
||||
public mutating func visit<T>(
|
||||
field: VOffset,
|
||||
fieldName: String,
|
||||
required: Bool,
|
||||
type: T.Type) throws where T: Verifiable
|
||||
{
|
||||
let derefValue = try dereference(field)
|
||||
|
||||
if let value = derefValue {
|
||||
try T.verify(&_verifier, at: value, of: T.self)
|
||||
return
|
||||
}
|
||||
if required {
|
||||
throw FlatbuffersErrors.requiredFieldDoesntExist(
|
||||
position: field,
|
||||
name: fieldName)
|
||||
}
|
||||
}
|
||||
|
||||
/// Visits all the fields for a union object within the table to
|
||||
/// validate the integrity of the data
|
||||
/// - Parameters:
|
||||
/// - key: Current Key Voffset
|
||||
/// - field: Current field Voffset
|
||||
/// - unionKeyName: Union key name
|
||||
/// - fieldName: Field key name
|
||||
/// - required: indicates if an object is required to be present
|
||||
/// - completion: Completion is a handler that WILL be called in the generated
|
||||
/// - Throws: A `FlatbuffersErrors` where the field is corrupt
|
||||
public mutating func visit<T>(
|
||||
unionKey key: VOffset,
|
||||
unionField field: VOffset,
|
||||
unionKeyName: String,
|
||||
fieldName: String,
|
||||
required: Bool,
|
||||
completion: @escaping (inout Verifier, T, Int) throws -> Void) throws where T: UnionEnum
|
||||
{
|
||||
let keyPos = try dereference(key)
|
||||
let valPos = try dereference(field)
|
||||
|
||||
if keyPos == nil && valPos == nil {
|
||||
if required {
|
||||
throw FlatbuffersErrors.requiredFieldDoesntExist(
|
||||
position: key,
|
||||
name: unionKeyName)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if let _key = keyPos,
|
||||
let _val = valPos
|
||||
{
|
||||
/// verifiying that the key is within the buffer
|
||||
try T.T.verify(&_verifier, at: _key, of: T.T.self)
|
||||
guard let _enum = try T.init(value: _verifier._buffer.read(
|
||||
def: T.T.self,
|
||||
position: _key)) else
|
||||
{
|
||||
throw FlatbuffersErrors.unknownUnionCase
|
||||
}
|
||||
/// we are assuming that Unions will always be of type Uint8
|
||||
try completion(
|
||||
&_verifier,
|
||||
_enum,
|
||||
_val)
|
||||
return
|
||||
}
|
||||
throw FlatbuffersErrors.valueNotFound(
|
||||
key: keyPos,
|
||||
keyName: unionKeyName,
|
||||
field: valPos,
|
||||
fieldName: fieldName)
|
||||
}
|
||||
|
||||
/// Visits and validates all the objects within a union vector
|
||||
/// - Parameters:
|
||||
/// - key: Current Key Voffset
|
||||
/// - field: Current field Voffset
|
||||
/// - unionKeyName: Union key name
|
||||
/// - fieldName: Field key name
|
||||
/// - required: indicates if an object is required to be present
|
||||
/// - completion: Completion is a handler that WILL be called in the generated
|
||||
/// - Throws: A `FlatbuffersErrors` where the field is corrupt
|
||||
public mutating func visitUnionVector<T>(
|
||||
unionKey key: VOffset,
|
||||
unionField field: VOffset,
|
||||
unionKeyName: String,
|
||||
fieldName: String,
|
||||
required: Bool,
|
||||
completion: @escaping (inout Verifier, T, Int) throws -> Void) throws where T: UnionEnum
|
||||
{
|
||||
let keyVectorPosition = try dereference(key)
|
||||
let offsetVectorPosition = try dereference(field)
|
||||
|
||||
if let keyPos = keyVectorPosition,
|
||||
let valPos = offsetVectorPosition
|
||||
{
|
||||
try UnionVector<T>.verify(
|
||||
&_verifier,
|
||||
keyPosition: keyPos,
|
||||
fieldPosition: valPos,
|
||||
unionKeyName: unionKeyName,
|
||||
fieldName: fieldName,
|
||||
completion: completion)
|
||||
return
|
||||
}
|
||||
if required {
|
||||
throw FlatbuffersErrors.requiredFieldDoesntExist(
|
||||
position: field,
|
||||
name: fieldName)
|
||||
}
|
||||
}
|
||||
|
||||
/// Finishs the current Table verifier, and subtracts the current
|
||||
/// table from the incremented depth.
|
||||
public mutating func finish() {
|
||||
_verifier.finish()
|
||||
}
|
||||
}
|
52
swift/Sources/FlatBuffers/VeriferOptions.swift
Normal file
52
swift/Sources/FlatBuffers/VeriferOptions.swift
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
/// `VerifierOptions` is a set of options to verify a flatbuffer
|
||||
public struct VerifierOptions {
|
||||
|
||||
/// Maximum `Apparent` size if the buffer can be expanded into a DAG tree
|
||||
internal var _maxApparentSize: UOffset
|
||||
|
||||
/// Maximum table count allowed in a buffer
|
||||
internal var _maxTableCount: UOffset
|
||||
|
||||
/// Maximum depth allowed in a buffer
|
||||
internal var _maxDepth: UOffset
|
||||
|
||||
/// Ignoring missing null terminals in strings
|
||||
internal var _ignoreMissingNullTerminators: Bool
|
||||
|
||||
/// initializes the set of options for the verifier
|
||||
/// - Parameters:
|
||||
/// - maxDepth: Maximum depth allowed in a buffer
|
||||
/// - maxTableCount: Maximum table count allowed in a buffer
|
||||
/// - maxApparentSize: Maximum `Apparent` size if the buffer can be expanded into a DAG tree
|
||||
/// - ignoreMissingNullTerminators: Ignoring missing null terminals in strings *Currently not supported in swift*
|
||||
public init(
|
||||
maxDepth: UOffset = 64,
|
||||
maxTableCount: UOffset = 1000000,
|
||||
maxApparentSize: UOffset = 1 << 31,
|
||||
ignoreMissingNullTerminators: Bool = false)
|
||||
{
|
||||
_maxDepth = maxDepth
|
||||
_maxTableCount = maxTableCount
|
||||
_maxApparentSize = maxApparentSize
|
||||
_ignoreMissingNullTerminators = ignoreMissingNullTerminators
|
||||
}
|
||||
|
||||
}
|
211
swift/Sources/FlatBuffers/Verifiable.swift
Normal file
211
swift/Sources/FlatBuffers/Verifiable.swift
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Verifiable is a protocol all swift flatbuffers object should conform to,
|
||||
/// since swift is similar to `cpp` and `rust` where the data is read directly
|
||||
/// from `unsafeMemory` thus the need to verify if the buffer received is a valid one
|
||||
public protocol Verifiable {
|
||||
|
||||
/// Verifies that the current value is which the bounds of the buffer, and if
|
||||
/// the current `Value` is aligned properly
|
||||
/// - Parameters:
|
||||
/// - verifier: Verifier that hosts the buffer
|
||||
/// - position: Current position within the buffer
|
||||
/// - type: The type of the object to be verified
|
||||
/// - Throws: Errors coming from `inBuffer` function
|
||||
static func verify<T>(
|
||||
_ verifier: inout Verifier,
|
||||
at position: Int,
|
||||
of type: T.Type) throws where T: Verifiable
|
||||
}
|
||||
|
||||
extension Verifiable {
|
||||
|
||||
/// Verifies if the current range to be read is within the bounds of the buffer,
|
||||
/// and if the range is properly aligned
|
||||
/// - Parameters:
|
||||
/// - verifier: Verifier that hosts the buffer
|
||||
/// - position: Current position within the buffer
|
||||
/// - type: The type of the object to be verified
|
||||
/// - Throws: Erros thrown from `isAligned` & `rangeInBuffer`
|
||||
/// - Returns: a tuple of the start position and the count of objects within the range
|
||||
@discardableResult
|
||||
public static func verifyRange<T>(
|
||||
_ verifier: inout Verifier,
|
||||
at position: Int, of type: T.Type) throws -> (start: Int, count: Int)
|
||||
{
|
||||
let len: UOffset = try verifier.getValue(at: position)
|
||||
let intLen = Int(len)
|
||||
let start = Int(clamping: (position &+ MemoryLayout<Int32>.size).magnitude)
|
||||
try verifier.isAligned(position: start, type: type.self)
|
||||
try verifier.rangeInBuffer(position: start, size: intLen)
|
||||
return (start, intLen)
|
||||
}
|
||||
}
|
||||
|
||||
extension Verifiable where Self: Scalar {
|
||||
|
||||
/// Verifies that the current value is which the bounds of the buffer, and if
|
||||
/// the current `Value` is aligned properly
|
||||
/// - Parameters:
|
||||
/// - verifier: Verifier that hosts the buffer
|
||||
/// - position: Current position within the buffer
|
||||
/// - type: The type of the object to be verified
|
||||
/// - Throws: Errors coming from `inBuffer` function
|
||||
public static func verify<T>(
|
||||
_ verifier: inout Verifier,
|
||||
at position: Int,
|
||||
of type: T.Type) throws where T: Verifiable
|
||||
{
|
||||
try verifier.inBuffer(position: position, of: type.self)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - ForwardOffset
|
||||
|
||||
/// ForwardOffset is a container to wrap around the Generic type to be verified
|
||||
/// from the flatbuffers object.
|
||||
public enum ForwardOffset<U>: Verifiable where U: Verifiable {
|
||||
|
||||
/// Verifies that the current value is which the bounds of the buffer, and if
|
||||
/// the current `Value` is aligned properly
|
||||
/// - Parameters:
|
||||
/// - verifier: Verifier that hosts the buffer
|
||||
/// - position: Current position within the buffer
|
||||
/// - type: The type of the object to be verified
|
||||
/// - Throws: Errors coming from `inBuffer` function
|
||||
public static func verify<T>(
|
||||
_ verifier: inout Verifier,
|
||||
at position: Int,
|
||||
of type: T.Type) throws where T: Verifiable
|
||||
{
|
||||
let offset: UOffset = try verifier.getValue(at: position)
|
||||
let nextOffset = Int(clamping: (Int(offset) &+ position).magnitude)
|
||||
try U.verify(&verifier, at: nextOffset, of: U.self)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Vector
|
||||
|
||||
/// Vector is a container to wrap around the Generic type to be verified
|
||||
/// from the flatbuffers object.
|
||||
public enum Vector<U, S>: Verifiable where U: Verifiable, S: Verifiable {
|
||||
|
||||
/// Verifies that the current value is which the bounds of the buffer, and if
|
||||
/// the current `Value` is aligned properly
|
||||
/// - Parameters:
|
||||
/// - verifier: Verifier that hosts the buffer
|
||||
/// - position: Current position within the buffer
|
||||
/// - type: The type of the object to be verified
|
||||
/// - Throws: Errors coming from `inBuffer` function
|
||||
public static func verify<T>(
|
||||
_ verifier: inout Verifier,
|
||||
at position: Int,
|
||||
of type: T.Type) throws where T: Verifiable
|
||||
{
|
||||
/// checks if the next verification type S is equal to U of type forwardOffset
|
||||
/// This had to be done since I couldnt find a solution for duplicate call functions
|
||||
/// A fix will be appreciated
|
||||
if U.self is ForwardOffset<S>.Type {
|
||||
let range = try verifyRange(&verifier, at: position, of: UOffset.self)
|
||||
for index in stride(
|
||||
from: range.start,
|
||||
to: Int(clamping: range.start &+ range.count),
|
||||
by: MemoryLayout<UOffset>.size)
|
||||
{
|
||||
try U.verify(&verifier, at: index, of: U.self)
|
||||
}
|
||||
} else {
|
||||
try S.verifyRange(&verifier, at: position, of: S.self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UnionVector
|
||||
|
||||
/// UnionVector is a container to wrap around the Generic type to be verified
|
||||
/// from the flatbuffers object.
|
||||
public enum UnionVector<S> where S: UnionEnum {
|
||||
|
||||
/// Completion handler for the function Verify, that passes the verifier
|
||||
/// enum type and position of union field
|
||||
public typealias Completion = (inout Verifier, S, Int) throws -> Void
|
||||
|
||||
/// Verifies if the current range to be read is within the bounds of the buffer,
|
||||
/// and if the range is properly aligned. It also verifies if the union type is a
|
||||
/// *valid/supported* union type.
|
||||
/// - Parameters:
|
||||
/// - verifier: Verifier that hosts the buffer
|
||||
/// - keyPosition: Current union key position within the buffer
|
||||
/// - fieldPosition: Current union field position within the buffer
|
||||
/// - unionKeyName: Name of key to written if error is presented
|
||||
/// - fieldName: Name of field to written if error is presented
|
||||
/// - completion: Completion is a handler that WILL be called in the generated
|
||||
/// code to verify the actual objects
|
||||
/// - Throws: FlatbuffersErrors
|
||||
public static func verify(
|
||||
_ verifier: inout Verifier,
|
||||
keyPosition: Int,
|
||||
fieldPosition: Int,
|
||||
unionKeyName: String,
|
||||
fieldName: String,
|
||||
completion: @escaping Completion) throws
|
||||
{
|
||||
/// Get offset for union key vectors and offset vectors
|
||||
let keyOffset: UOffset = try verifier.getValue(at: keyPosition)
|
||||
let fieldOffset: UOffset = try verifier.getValue(at: fieldPosition)
|
||||
|
||||
/// Check if values are within the buffer, returns the start position of vectors, and vector counts
|
||||
/// Using &+ is safe since we already verified that the value is within the buffer, where the max is
|
||||
/// going to be 2Gib and swift supports Int64 by default
|
||||
let keysRange = try S.T.verifyRange(
|
||||
&verifier,
|
||||
at: Int(keyOffset) &+ keyPosition,
|
||||
of: S.T.self)
|
||||
let offsetsRange = try UOffset.verifyRange(
|
||||
&verifier,
|
||||
at: Int(fieldOffset) &+ fieldPosition,
|
||||
of: UOffset.self)
|
||||
|
||||
guard keysRange.count == offsetsRange.count else {
|
||||
throw FlatbuffersErrors.unionVectorSize(
|
||||
keyVectorSize: keysRange.count,
|
||||
fieldVectorSize: offsetsRange.count,
|
||||
unionKeyName: unionKeyName,
|
||||
fieldName: fieldName)
|
||||
}
|
||||
|
||||
var count = 0
|
||||
/// Iterate over the vector of keys and offsets.
|
||||
while count < keysRange.count {
|
||||
|
||||
/// index of readable enum value in array
|
||||
let keysIndex = MemoryLayout<S.T>.size * count
|
||||
guard let _enum = try S.init(value: verifier._buffer.read(
|
||||
def: S.T.self,
|
||||
position: keysRange.start + keysIndex)) else
|
||||
{
|
||||
throw FlatbuffersErrors.unknownUnionCase
|
||||
}
|
||||
/// index of readable offset value in array
|
||||
let fieldIndex = MemoryLayout<UOffset>.size * count
|
||||
try completion(&verifier, _enum, offsetsRange.start + fieldIndex)
|
||||
count += 1
|
||||
}
|
||||
}
|
||||
}
|
199
swift/Sources/FlatBuffers/Verifier.swift
Normal file
199
swift/Sources/FlatBuffers/Verifier.swift
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Verifier that check if the buffer passed into it is a valid,
|
||||
/// safe, aligned Flatbuffers object since swift read from `unsafeMemory`
|
||||
public struct Verifier {
|
||||
|
||||
/// Flag to check for alignment if true
|
||||
fileprivate let _checkAlignment: Bool
|
||||
/// Capacity of the current buffer
|
||||
fileprivate var _capacity: Int
|
||||
/// Current ApparentSize
|
||||
fileprivate var _apparentSize: UOffset = 0
|
||||
/// Amount of tables present within a buffer
|
||||
fileprivate var _tableCount = 0
|
||||
|
||||
/// Capacity of the buffer
|
||||
internal var capacity: Int { _capacity }
|
||||
/// Current reached depth within the buffer
|
||||
internal var _depth = 0
|
||||
/// Current verifiable ByteBuffer
|
||||
internal var _buffer: ByteBuffer
|
||||
/// Options for verification
|
||||
internal let _options: VerifierOptions
|
||||
|
||||
/// Initializer for the verifier
|
||||
/// - Parameters:
|
||||
/// - buffer: Bytebuffer that is required to be verified
|
||||
/// - options: `VerifierOptions` that set the rule for some of the verification done
|
||||
/// - checkAlignment: If alignment check is required to be preformed
|
||||
/// - Throws: `exceedsMaxSizeAllowed` if capacity of the buffer is more than 2GiB
|
||||
public init(
|
||||
buffer: inout ByteBuffer,
|
||||
options: VerifierOptions = .init(),
|
||||
checkAlignment: Bool = true) throws
|
||||
{
|
||||
guard buffer.capacity < FlatBufferMaxSize else {
|
||||
throw FlatbuffersErrors.exceedsMaxSizeAllowed
|
||||
}
|
||||
|
||||
_buffer = buffer
|
||||
_capacity = buffer.capacity
|
||||
_checkAlignment = checkAlignment
|
||||
_options = options
|
||||
}
|
||||
|
||||
/// Resets the verifier to initial state
|
||||
public mutating func reset() {
|
||||
_depth = 0
|
||||
_tableCount = 0
|
||||
}
|
||||
|
||||
/// Checks if the value of type `T` is aligned properly in the buffer
|
||||
/// - Parameters:
|
||||
/// - position: Current position
|
||||
/// - type: Type of value to check
|
||||
/// - Throws: `missAlignedPointer` if the pointer is not aligned properly
|
||||
public mutating func isAligned<T>(position: Int, type: T.Type) throws {
|
||||
|
||||
/// If check alignment is false this mutating function doesnt continue
|
||||
if !_checkAlignment { return }
|
||||
|
||||
/// advance pointer to position X
|
||||
let ptr = _buffer._storage.memory.advanced(by: position)
|
||||
/// Check if the pointer is aligned
|
||||
if Int(bitPattern: ptr) & (MemoryLayout<T>.alignment &- 1) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
throw FlatbuffersErrors.missAlignedPointer(
|
||||
position: position,
|
||||
type: String(describing: T.self))
|
||||
}
|
||||
|
||||
/// Checks if the value of Size "X" is within the range of the buffer
|
||||
/// - Parameters:
|
||||
/// - position: Current postion to be read
|
||||
/// - size: `Byte` Size of readable object within the buffer
|
||||
/// - Throws: `outOfBounds` if the value is out of the bounds of the buffer
|
||||
/// and `apparentSizeTooLarge` if the apparent size is bigger than the one specified
|
||||
/// in `VerifierOptions`
|
||||
public mutating func rangeInBuffer(position: Int, size: Int) throws {
|
||||
let end = UInt(clamping: (position &+ size).magnitude)
|
||||
if end > _buffer.capacity {
|
||||
throw FlatbuffersErrors.outOfBounds(position: end, end: capacity)
|
||||
}
|
||||
_apparentSize = _apparentSize &+ UInt32(size)
|
||||
if _apparentSize > _options._maxApparentSize {
|
||||
throw FlatbuffersErrors.apparentSizeTooLarge
|
||||
}
|
||||
}
|
||||
|
||||
/// Validates if a value of type `T` is aligned and within the bounds of
|
||||
/// the buffer
|
||||
/// - Parameters:
|
||||
/// - position: Current readable position
|
||||
/// - type: Type of value to check
|
||||
/// - Throws: FlatbuffersErrors
|
||||
public mutating func inBuffer<T>(position: Int, of type: T.Type) throws {
|
||||
try isAligned(position: position, type: type)
|
||||
try rangeInBuffer(position: position, size: MemoryLayout<T>.size)
|
||||
}
|
||||
|
||||
/// Visits a table at the current position and validates if the table meets
|
||||
/// the rules specified in the `VerifierOptions`
|
||||
/// - Parameter position: Current position to be read
|
||||
/// - Throws: FlatbuffersErrors
|
||||
/// - Returns: A `TableVerifier` at the current readable table
|
||||
public mutating func visitTable(at position: Int) throws -> TableVerifier {
|
||||
let vtablePosition = try derefOffset(position: position)
|
||||
let vtableLength: VOffset = try getValue(at: vtablePosition)
|
||||
|
||||
let length = Int(vtableLength)
|
||||
try isAligned(
|
||||
position: Int(clamping: (vtablePosition + length).magnitude),
|
||||
type: VOffset.self)
|
||||
try rangeInBuffer(position: vtablePosition, size: length)
|
||||
|
||||
_tableCount += 1
|
||||
|
||||
if _tableCount > _options._maxTableCount {
|
||||
throw FlatbuffersErrors.maximumTables
|
||||
}
|
||||
|
||||
_depth += 1
|
||||
|
||||
if _depth > _options._maxDepth {
|
||||
throw FlatbuffersErrors.maximumDepth
|
||||
}
|
||||
|
||||
return TableVerifier(
|
||||
position: position,
|
||||
vtable: vtablePosition,
|
||||
vtableLength: length,
|
||||
verifier: &self)
|
||||
}
|
||||
|
||||
/// Validates if a value of type `T` is within the buffer and returns it
|
||||
/// - Parameter position: Current position to be read
|
||||
/// - Throws: `inBuffer` errors
|
||||
/// - Returns: a value of type `T` usually a `VTable` or a table offset
|
||||
internal mutating func getValue<T>(at position: Int) throws -> T {
|
||||
try inBuffer(position: position, of: T.self)
|
||||
return _buffer.read(def: T.self, position: position)
|
||||
}
|
||||
|
||||
/// derefrences an offset within a vtable to get the position of the field
|
||||
/// in the bytebuffer
|
||||
/// - Parameter position: Current readable position
|
||||
/// - Throws: `inBuffer` errors & `signedOffsetOutOfBounds`
|
||||
/// - Returns: Current readable position for a field
|
||||
@inline(__always)
|
||||
internal mutating func derefOffset(position: Int) throws -> Int {
|
||||
try inBuffer(position: position, of: Int32.self)
|
||||
|
||||
let offset = _buffer.read(def: Int32.self, position: position)
|
||||
// switching to int32 since swift's default Int is int64
|
||||
// this should be safe since we already checked if its within
|
||||
// the buffer
|
||||
let _int32Position = UInt32(position)
|
||||
|
||||
let reportedOverflow: (partialValue: UInt32, overflow: Bool)
|
||||
if offset > 0 {
|
||||
reportedOverflow = _int32Position.subtractingReportingOverflow(offset.magnitude)
|
||||
} else {
|
||||
reportedOverflow = _int32Position.addingReportingOverflow(offset.magnitude)
|
||||
}
|
||||
|
||||
/// since `subtractingReportingOverflow` & `addingReportingOverflow` returns true,
|
||||
/// if there is overflow we return failure
|
||||
if reportedOverflow.overflow || reportedOverflow.partialValue > _buffer.capacity {
|
||||
throw FlatbuffersErrors.signedOffsetOutOfBounds(
|
||||
offset: Int(offset),
|
||||
position: position)
|
||||
}
|
||||
|
||||
return Int(reportedOverflow.partialValue)
|
||||
}
|
||||
|
||||
/// finishes the current iteration of verification on an object
|
||||
internal mutating func finish() {
|
||||
_depth -= 1
|
||||
}
|
||||
}
|
@ -40,7 +40,7 @@ func run(name: String, runs: Int, action: () -> Void) -> Benchmark {
|
||||
func createDocument(Benchmarks: [Benchmark]) -> String {
|
||||
let separator = "-------------------------------------"
|
||||
var document = "\(separator)\n"
|
||||
document += "\(String(format: "|\t%@\t\t|\t\t%@\t\t|", "Name", "Scores"))\n"
|
||||
document += "\(String(format: "|\t%@\t\t |\t\t%@\t\t|", "Name", "Scores"))\n"
|
||||
document += "\(separator)\n"
|
||||
for i in Benchmarks {
|
||||
document += "\(i.description) \n"
|
||||
@ -89,7 +89,9 @@ func benchmarkThreeMillionStructs() {
|
||||
|
||||
var offsets: [Offset] = []
|
||||
for _ in 0..<structCount {
|
||||
fb.startVector(5 * MemoryLayout<AA>.size, elementSize: MemoryLayout<AA>.alignment)
|
||||
fb.startVector(
|
||||
5 * MemoryLayout<AA>.size,
|
||||
elementSize: MemoryLayout<AA>.alignment)
|
||||
for _ in 0..<5 {
|
||||
_ = fb.create(struct: AA(a: 2.4, b: 2.4))
|
||||
}
|
||||
@ -119,12 +121,18 @@ struct AA: NativeStruct {
|
||||
func benchmark(numberOfRuns runs: Int) {
|
||||
var benchmarks: [Benchmark] = []
|
||||
let str = (0...99).map { _ -> String in "x" }.joined()
|
||||
benchmarks.append(run(name: "500_000", runs: runs, action: benchmarkFiveHundredAdds))
|
||||
benchmarks.append(run(
|
||||
name: "500_000",
|
||||
runs: runs,
|
||||
action: benchmarkFiveHundredAdds))
|
||||
benchmarks.append(run(name: "10 str", runs: runs, action: create10Strings))
|
||||
let hundredStr = run(name: "100 str", runs: runs) {
|
||||
create100Strings(str: str)
|
||||
}
|
||||
benchmarks.append(run(name: "3M strc", runs: 1, action: benchmarkThreeMillionStructs))
|
||||
benchmarks.append(run(
|
||||
name: "3M strc",
|
||||
runs: 1,
|
||||
action: benchmarkThreeMillionStructs))
|
||||
benchmarks.append(hundredStr)
|
||||
print(createDocument(Benchmarks: benchmarks))
|
||||
}
|
||||
|
@ -28,7 +28,9 @@ let package = Package(
|
||||
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0"),
|
||||
],
|
||||
targets: [
|
||||
.target(name: "SwiftFlatBuffers"),
|
||||
.target(
|
||||
name: "SwiftFlatBuffers",
|
||||
dependencies: ["FlatBuffers"]),
|
||||
.testTarget(
|
||||
name: "FlatBuffers.Test.SwiftTests",
|
||||
dependencies: ["FlatBuffers", "GRPC"]),
|
||||
|
@ -0,0 +1,32 @@
|
||||
enum Color:ubyte (bit_flags) {
|
||||
Red = 0, // color Red = (1u << 0)
|
||||
/// \brief color Green
|
||||
/// Green is bit_flag with value (1u << 1)
|
||||
Green,
|
||||
/// \brief color Blue (1u << 3)
|
||||
Blue = 3,
|
||||
}
|
||||
|
||||
struct Test { a:short; b:byte; }
|
||||
|
||||
struct Vec3 (force_align: 8) {
|
||||
x:float;
|
||||
y:float;
|
||||
z:float;
|
||||
test1:double;
|
||||
test2:Color;
|
||||
test3:Test;
|
||||
}
|
||||
|
||||
/// an example documentation comment: "monster object"
|
||||
table Monster {
|
||||
pos:Vec3 (id: 0);
|
||||
hp:short = 100 (id: 2);
|
||||
mana:short = 150 (id: 1);
|
||||
name:string (id: 3, key);
|
||||
color:Color = Blue (id: 6);
|
||||
inventory:[ubyte] (id: 5);
|
||||
testarrayoftables:[Monster] (id: 4);
|
||||
}
|
||||
|
||||
root_type Monster;
|
@ -0,0 +1,224 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
// swiftlint:disable all
|
||||
// swiftformat:disable all
|
||||
|
||||
import FlatBuffers
|
||||
|
||||
public enum Color: UInt8, Enum, Verifiable {
|
||||
public typealias T = UInt8
|
||||
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
|
||||
public var value: UInt8 { return self.rawValue }
|
||||
case red = 1
|
||||
/// \brief color Green
|
||||
/// Green is bit_flag with value (1u << 1)
|
||||
case green = 2
|
||||
/// \brief color Blue (1u << 3)
|
||||
case blue = 8
|
||||
|
||||
public static var max: Color { return .blue }
|
||||
public static var min: Color { return .red }
|
||||
}
|
||||
|
||||
public struct Test: NativeStruct, Verifiable {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
|
||||
private var _a: Int16
|
||||
private var _b: Int8
|
||||
private let padding0__: UInt8 = 0
|
||||
|
||||
public init(a: Int16, b: Int8) {
|
||||
_a = a
|
||||
_b = b
|
||||
}
|
||||
|
||||
public init() {
|
||||
_a = 0
|
||||
_b = 0
|
||||
}
|
||||
|
||||
public var a: Int16 { _a }
|
||||
public var b: Int8 { _b }
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
try verifier.inBuffer(position: position, of: Test.self)
|
||||
}
|
||||
}
|
||||
|
||||
public struct Test_Mutable: FlatBufferObject {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
private var _accessor: Struct
|
||||
|
||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
|
||||
|
||||
public var a: Int16 { return _accessor.readBuffer(of: Int16.self, at: 0) }
|
||||
public var b: Int8 { return _accessor.readBuffer(of: Int8.self, at: 2) }
|
||||
}
|
||||
|
||||
public struct Vec3: NativeStruct, Verifiable {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
|
||||
private var _x: Float32
|
||||
private var _y: Float32
|
||||
private var _z: Float32
|
||||
private let padding0__: UInt32 = 0
|
||||
private var _test1: Double
|
||||
private var _test2: UInt8
|
||||
private let padding1__: UInt8 = 0
|
||||
private var _test3: Test
|
||||
private let padding2__: UInt16 = 0
|
||||
|
||||
public init(x: Float32, y: Float32, z: Float32, test1: Double, test2: Color, test3: Test) {
|
||||
_x = x
|
||||
_y = y
|
||||
_z = z
|
||||
_test1 = test1
|
||||
_test2 = test2.value
|
||||
_test3 = test3
|
||||
}
|
||||
|
||||
public init() {
|
||||
_x = 0.0
|
||||
_y = 0.0
|
||||
_z = 0.0
|
||||
_test1 = 0.0
|
||||
_test2 = 0
|
||||
_test3 = Test()
|
||||
}
|
||||
|
||||
public var x: Float32 { _x }
|
||||
public var y: Float32 { _y }
|
||||
public var z: Float32 { _z }
|
||||
public var test1: Double { _test1 }
|
||||
public var test2: Color { Color(rawValue: _test2)! }
|
||||
public var test3: Test { _test3 }
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
try verifier.inBuffer(position: position, of: Vec3.self)
|
||||
}
|
||||
}
|
||||
|
||||
public struct Vec3_Mutable: FlatBufferObject {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
private var _accessor: Struct
|
||||
|
||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
|
||||
|
||||
public var x: Float32 { return _accessor.readBuffer(of: Float32.self, at: 0) }
|
||||
public var y: Float32 { return _accessor.readBuffer(of: Float32.self, at: 4) }
|
||||
public var z: Float32 { return _accessor.readBuffer(of: Float32.self, at: 8) }
|
||||
public var test1: Double { return _accessor.readBuffer(of: Double.self, at: 16) }
|
||||
public var test2: Color { return Color(rawValue: _accessor.readBuffer(of: UInt8.self, at: 24)) ?? .red }
|
||||
public var test3: Test_Mutable { return Test_Mutable(_accessor.bb, o: _accessor.postion + 26) }
|
||||
}
|
||||
|
||||
/// an example documentation comment: "monster object"
|
||||
public struct Monster: FlatBufferObject, Verifiable {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
private var _accessor: Table
|
||||
|
||||
public static func getRootAsMonster(bb: ByteBuffer) -> Monster { return Monster(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
|
||||
|
||||
private init(_ t: Table) { _accessor = t }
|
||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||
|
||||
private enum VTOFFSET: VOffset {
|
||||
case pos = 4
|
||||
case mana = 6
|
||||
case hp = 8
|
||||
case name = 10
|
||||
case testarrayoftables = 12
|
||||
case inventory = 14
|
||||
case color = 16
|
||||
var v: Int32 { Int32(self.rawValue) }
|
||||
var p: VOffset { self.rawValue }
|
||||
}
|
||||
|
||||
public var pos: Vec3? { let o = _accessor.offset(VTOFFSET.pos.v); return o == 0 ? nil : _accessor.readBuffer(of: Vec3.self, at: o) }
|
||||
public var mutablePos: Vec3_Mutable? { let o = _accessor.offset(VTOFFSET.pos.v); return o == 0 ? nil : Vec3_Mutable(_accessor.bb, o: o + _accessor.postion) }
|
||||
public var mana: Int16 { let o = _accessor.offset(VTOFFSET.mana.v); return o == 0 ? 150 : _accessor.readBuffer(of: Int16.self, at: o) }
|
||||
public var hp: Int16 { let o = _accessor.offset(VTOFFSET.hp.v); return o == 0 ? 100 : _accessor.readBuffer(of: Int16.self, at: o) }
|
||||
public var name: String! { let o = _accessor.offset(VTOFFSET.name.v); return _accessor.string(at: o) }
|
||||
public var nameSegmentArray: [UInt8]! { return _accessor.getVector(at: VTOFFSET.name.v) }
|
||||
public var testarrayoftablesCount: Int32 { let o = _accessor.offset(VTOFFSET.testarrayoftables.v); return o == 0 ? 0 : _accessor.vector(count: o) }
|
||||
public func testarrayoftables(at index: Int32) -> Monster? { let o = _accessor.offset(VTOFFSET.testarrayoftables.v); return o == 0 ? nil : Monster(_accessor.bb, o: _accessor.indirect(_accessor.vector(at: o) + index * 4)) }
|
||||
public func testarrayoftablesBy(key: String) -> Monster? { let o = _accessor.offset(VTOFFSET.testarrayoftables.v); return o == 0 ? nil : Monster.lookupByKey(vector: _accessor.vector(at: o), key: key, fbb: _accessor.bb) }
|
||||
public var inventoryCount: Int32 { let o = _accessor.offset(VTOFFSET.inventory.v); return o == 0 ? 0 : _accessor.vector(count: o) }
|
||||
public func inventory(at index: Int32) -> UInt8 { let o = _accessor.offset(VTOFFSET.inventory.v); return o == 0 ? 0 : _accessor.directRead(of: UInt8.self, offset: _accessor.vector(at: o) + index * 1) }
|
||||
public var inventory: [UInt8] { return _accessor.getVector(at: VTOFFSET.inventory.v) ?? [] }
|
||||
public var color: Color { let o = _accessor.offset(VTOFFSET.color.v); return o == 0 ? .blue : Color(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .blue }
|
||||
public static func startMonster(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 7) }
|
||||
public static func add(pos: Vec3?, _ fbb: inout FlatBufferBuilder) { guard let pos = pos else { return }; fbb.create(struct: pos, position: VTOFFSET.pos.p) }
|
||||
public static func add(mana: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: mana, def: 150, at: VTOFFSET.mana.p) }
|
||||
public static func add(hp: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: hp, def: 100, at: VTOFFSET.hp.p) }
|
||||
public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VTOFFSET.name.p) }
|
||||
public static func addVectorOf(testarrayoftables: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: testarrayoftables, at: VTOFFSET.testarrayoftables.p) }
|
||||
public static func addVectorOf(inventory: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: inventory, at: VTOFFSET.inventory.p) }
|
||||
public static func add(color: Color, _ fbb: inout FlatBufferBuilder) { fbb.add(element: color.rawValue, def: 8, at: VTOFFSET.color.p) }
|
||||
public static func endMonster(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); fbb.require(table: end, fields: [10]); return end }
|
||||
public static func createMonster(
|
||||
_ fbb: inout FlatBufferBuilder,
|
||||
pos: Vec3? = nil,
|
||||
mana: Int16 = 150,
|
||||
hp: Int16 = 100,
|
||||
nameOffset name: Offset = Offset(),
|
||||
testarrayoftablesVectorOffset testarrayoftables: Offset = Offset(),
|
||||
inventoryVectorOffset inventory: Offset = Offset(),
|
||||
color: Color = .blue
|
||||
) -> Offset {
|
||||
let __start = Monster.startMonster(&fbb)
|
||||
Monster.add(pos: pos, &fbb)
|
||||
Monster.add(mana: mana, &fbb)
|
||||
Monster.add(hp: hp, &fbb)
|
||||
Monster.add(name: name, &fbb)
|
||||
Monster.addVectorOf(testarrayoftables: testarrayoftables, &fbb)
|
||||
Monster.addVectorOf(inventory: inventory, &fbb)
|
||||
Monster.add(color: color, &fbb)
|
||||
return Monster.endMonster(&fbb, start: __start)
|
||||
}
|
||||
public static func sortVectorOfMonster(offsets:[Offset], _ fbb: inout FlatBufferBuilder) -> Offset {
|
||||
var off = offsets
|
||||
off.sort { Table.compare(Table.offset(Int32($1.o), vOffset: 10, fbb: fbb.buffer), Table.offset(Int32($0.o), vOffset: 10, fbb: fbb.buffer), fbb: fbb.buffer) < 0 }
|
||||
return fbb.createVector(ofOffsets: off)
|
||||
}
|
||||
fileprivate static func lookupByKey(vector: Int32, key: String, fbb: ByteBuffer) -> Monster? {
|
||||
let key = key.utf8.map { $0 }
|
||||
var span = fbb.read(def: Int32.self, position: Int(vector - 4))
|
||||
var start: Int32 = 0
|
||||
while span != 0 {
|
||||
var middle = span / 2
|
||||
let tableOffset = Table.indirect(vector + 4 * (start + middle), fbb)
|
||||
let comp = Table.compare(Table.offset(Int32(fbb.capacity) - tableOffset, vOffset: 10, fbb: fbb), key, fbb: fbb)
|
||||
if comp > 0 {
|
||||
span = middle
|
||||
} else if comp < 0 {
|
||||
middle += 1
|
||||
start += middle
|
||||
span -= middle
|
||||
} else {
|
||||
return Monster(fbb, o: tableOffset)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.pos.p, fieldName: "pos", required: false, type: Vec3.self)
|
||||
try _v.visit(field: VTOFFSET.mana.p, fieldName: "mana", required: false, type: Int16.self)
|
||||
try _v.visit(field: VTOFFSET.hp.p, fieldName: "hp", required: false, type: Int16.self)
|
||||
try _v.visit(field: VTOFFSET.name.p, fieldName: "name", required: true, type: ForwardOffset<String>.self)
|
||||
try _v.visit(field: VTOFFSET.testarrayoftables.p, fieldName: "testarrayoftables", required: false, type: ForwardOffset<Vector<ForwardOffset<Monster>, Monster>>.self)
|
||||
try _v.visit(field: VTOFFSET.inventory.p, fieldName: "inventory", required: false, type: ForwardOffset<Vector<UInt8, UInt8>>.self)
|
||||
try _v.visit(field: VTOFFSET.color.p, fieldName: "color", required: false, type: Color.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
@ -14,5 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
print("Flatbuffers")
|
||||
import FlatBuffers
|
||||
|
||||
@_cdecl("LLVMFuzzerTestOneInput")
|
||||
public func FuzzFlatbuffers(_ start: UnsafeRawPointer, _ count: Int) -> CInt {
|
||||
let bytes = UnsafeRawBufferPointer(start: start, count: count)
|
||||
do {
|
||||
var buffer = ByteBuffer(contiguousBytes: bytes, count: count)
|
||||
let _: Monster = try getCheckedRoot(byteBuffer: &buffer)
|
||||
} catch {
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
@ -9,5 +9,17 @@ fbc --swift --gen-mutable --grpc --gen-object-api -I ${test_dir}/include_test ${
|
||||
fbc --swift ${test_dir}/optional_scalars.fbs
|
||||
fbc --swift --gen-object-api ${test_dir}/more_defaults.fbs
|
||||
cd ${swift_dir}
|
||||
|
||||
cd ${swift_dir}/Sources/SwiftFlatBuffers
|
||||
# create better fuzzing test file
|
||||
fbc --swift fuzzer.fbs
|
||||
cd ${swift_dir}
|
||||
|
||||
swift build --build-tests
|
||||
swift test
|
||||
|
||||
if [ $(uname -s) != Darwin ]; then
|
||||
echo fuzzing
|
||||
swift build -c debug -Xswiftc -sanitize=fuzzer,address -Xswiftc -parse-as-library
|
||||
swift build -c release -Xswiftc -sanitize=fuzzer,address -Xswiftc -parse-as-library
|
||||
fi
|
||||
|
@ -26,9 +26,11 @@ typealias Stat = MyGame_Example_Stat
|
||||
class FlatBuffersMonsterWriterTests: XCTestCase {
|
||||
|
||||
func testData() {
|
||||
// swiftformat:disable all
|
||||
let data = Data([48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 68, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 120, 0, 0, 0, 0, 0, 80, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 64, 2, 0, 5, 0, 6, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 30, 0, 40, 0, 10, 0, 20, 0, 152, 255, 255, 255, 4, 0, 0, 0, 4, 0, 0, 0, 70, 114, 101, 100, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 50, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 49, 0, 0, 0, 9, 0, 0, 0, 77, 121, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 4, 0, 0, 0, 240, 255, 255, 255, 32, 0, 0, 0, 248, 255, 255, 255, 36, 0, 0, 0, 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 12, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 87, 105, 108, 109, 97, 0, 0, 0, 6, 0, 0, 0, 66, 97, 114, 110, 101, 121, 0, 0, 5, 0, 0, 0, 70, 114, 111, 100, 111, 0, 0, 0])
|
||||
// swiftformat:enable all
|
||||
let _data = ByteBuffer(data: data)
|
||||
readMonster(fb: _data)
|
||||
readVerifiedMonster(fb: _data)
|
||||
}
|
||||
|
||||
func testReadFromOtherLanguages() {
|
||||
@ -36,29 +38,36 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
||||
let url = URL(fileURLWithPath: path, isDirectory: true).appendingPathComponent("monsterdata_test").appendingPathExtension("mon")
|
||||
guard let data = try? Data(contentsOf: url) else { return }
|
||||
let _data = ByteBuffer(data: data)
|
||||
readMonster(fb: _data)
|
||||
readVerifiedMonster(fb: _data)
|
||||
}
|
||||
|
||||
func testCreateMonster() {
|
||||
let bytes = createMonster(withPrefix: false)
|
||||
// swiftformat:disable all
|
||||
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: bytes.buffer)
|
||||
// swiftformat:enable all
|
||||
let monster = MyGame_Example_Monster.getRootAsMonster(bb: bytes.buffer)
|
||||
readMonster(monster: monster)
|
||||
mutateMonster(fb: bytes.buffer)
|
||||
readMonster(fb: bytes.buffer)
|
||||
readMonster(monster: monster)
|
||||
}
|
||||
|
||||
func testCreateMonsterResizedBuffer() {
|
||||
let bytes = createMonster(withPrefix: false)
|
||||
// swiftformat:disable all
|
||||
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: bytes.sizedBuffer)
|
||||
// swiftformat:enable all
|
||||
readVerifiedMonster(fb: bytes.sizedBuffer)
|
||||
}
|
||||
|
||||
func testCreateMonsterPrefixed() {
|
||||
let bytes = createMonster(withPrefix: true)
|
||||
// swiftformat:disable all
|
||||
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])
|
||||
// swiftformat:enable all
|
||||
|
||||
let newBuf = FlatBuffersUtils.removeSizePrefix(bb: bytes.buffer)
|
||||
readMonster(fb: newBuf)
|
||||
var buffer = bytes.buffer
|
||||
readMonster(monster: getPrefixedSizeRoot(byteBuffer: &buffer))
|
||||
}
|
||||
|
||||
func testCreateMonsterUsingCreateMonsterMethodWithNilPos() {
|
||||
@ -77,7 +86,15 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
||||
var fbb = FlatBufferBuilder(initialSize: 1)
|
||||
let name = fbb.create(string: "Barney")
|
||||
let mStart = Monster.startMonster(&fbb)
|
||||
Monster.add(pos: MyGame_Example_Vec3(x: 10, y: 0, z: 0, test1: 0, test2: .blue, test3: .init()), &fbb)
|
||||
Monster.add(
|
||||
pos: MyGame_Example_Vec3(
|
||||
x: 10,
|
||||
y: 0,
|
||||
z: 0,
|
||||
test1: 0,
|
||||
test2: .blue,
|
||||
test3: .init()),
|
||||
&fbb)
|
||||
Monster.add(name: name, &fbb)
|
||||
let root = Monster.endMonster(&fbb, start: mStart)
|
||||
fbb.finish(offset: root)
|
||||
@ -88,9 +105,13 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
||||
}
|
||||
|
||||
func testReadMonsterFromUnsafePointerWithoutCopying() {
|
||||
// swiftformat:disable all
|
||||
var array: [UInt8] = [48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 68, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 120, 0, 0, 0, 0, 0, 80, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 64, 2, 0, 5, 0, 6, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 30, 0, 40, 0, 10, 0, 20, 0, 152, 255, 255, 255, 4, 0, 0, 0, 4, 0, 0, 0, 70, 114, 101, 100, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 50, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 49, 0, 0, 0, 9, 0, 0, 0, 77, 121, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 4, 0, 0, 0, 240, 255, 255, 255, 32, 0, 0, 0, 248, 255, 255, 255, 36, 0, 0, 0, 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 12, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 87, 105, 108, 109, 97, 0, 0, 0, 6, 0, 0, 0, 66, 97, 114, 110, 101, 121, 0, 0, 5, 0, 0, 0, 70, 114, 111, 100, 111, 0, 0, 0]
|
||||
// swiftformat:enable all
|
||||
let unpacked = array.withUnsafeMutableBytes { (memory) -> MyGame_Example_MonsterT in
|
||||
let bytes = ByteBuffer(assumingMemoryBound: memory.baseAddress!, capacity: memory.count)
|
||||
let bytes = ByteBuffer(
|
||||
assumingMemoryBound: memory.baseAddress!,
|
||||
capacity: memory.count)
|
||||
var monster = Monster.getRootAsMonster(bb: bytes)
|
||||
readFlatbufferMonster(monster: &monster)
|
||||
let unpacked = monster.unpack()
|
||||
@ -104,7 +125,10 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
||||
var fbb = FlatBufferBuilder(initialSize: 1)
|
||||
let name = fbb.create(string: "Frodo")
|
||||
let bools = fbb.createVector(boolArray)
|
||||
let root = Monster.createMonster(&fbb, nameOffset: name, testarrayofboolsVectorOffset: bools)
|
||||
let root = Monster.createMonster(
|
||||
&fbb,
|
||||
nameOffset: name,
|
||||
testarrayofboolsVectorOffset: bools)
|
||||
fbb.finish(offset: root)
|
||||
let monster = Monster.getRootAsMonster(bb: fbb.sizedBuffer)
|
||||
|
||||
@ -117,8 +141,13 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
func readMonster(fb: ByteBuffer) {
|
||||
var monster = Monster.getRootAsMonster(bb: fb)
|
||||
func readVerifiedMonster(fb: ByteBuffer) {
|
||||
var byteBuffer = fb
|
||||
XCTAssertNoThrow(try readMonster(monster: getCheckedRoot(byteBuffer: &byteBuffer) as MyGame_Example_Monster))
|
||||
}
|
||||
|
||||
func readMonster(monster: Monster) {
|
||||
var monster = monster
|
||||
readFlatbufferMonster(monster: &monster)
|
||||
let unpacked: MyGame_Example_MonsterT? = monster.unpack()
|
||||
readObjectApi(monster: unpacked!)
|
||||
@ -129,7 +158,11 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
||||
|
||||
func createMonster(withPrefix prefix: Bool) -> FlatBufferBuilder {
|
||||
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"),
|
||||
]
|
||||
var offsets: [Offset] = []
|
||||
let start1 = Monster.startMonster(&fbb)
|
||||
Monster.add(name: names[0], &fbb)
|
||||
@ -161,7 +194,15 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
|
||||
|
||||
let stringTestVector = fbb.createVector(ofOffsets: [test1, test2])
|
||||
let mStart = Monster.startMonster(&fbb)
|
||||
Monster.add(pos: MyGame_Example_Vec3(x: 1, y: 2, z: 3, test1: 3, test2: .green, test3: .init(a: 5, b: 6)), &fbb)
|
||||
Monster.add(
|
||||
pos: MyGame_Example_Vec3(
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: 3,
|
||||
test1: 3,
|
||||
test2: .green,
|
||||
test3: .init(a: 5, b: 6)),
|
||||
&fbb)
|
||||
Monster.add(hp: 80, &fbb)
|
||||
Monster.add(name: str, &fbb)
|
||||
Monster.addVectorOf(inventory: inv, &fbb)
|
||||
|
@ -52,22 +52,36 @@ final class FlatBuffersTests: XCTestCase {
|
||||
|
||||
func testCreateFinish() {
|
||||
var b = FlatBufferBuilder(initialSize: 16)
|
||||
let countryOff = Country.createCountry(builder: &b, name: country, log: 200, lan: 100)
|
||||
let countryOff = Country.createCountry(
|
||||
builder: &b,
|
||||
name: country,
|
||||
log: 200,
|
||||
lan: 100)
|
||||
b.finish(offset: countryOff)
|
||||
// swiftformat:disable all
|
||||
let v: [UInt8] = [16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 8, 0, 12, 0, 10, 0, 0, 0, 12, 0, 0, 0, 100, 0, 0, 0, 200, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0]
|
||||
// swiftformat:enable all
|
||||
XCTAssertEqual(b.sizedByteArray, v)
|
||||
}
|
||||
|
||||
func testCreateFinishWithPrefix() {
|
||||
var b = FlatBufferBuilder(initialSize: 16)
|
||||
let countryOff = Country.createCountry(builder: &b, name: country, log: 200, lan: 100)
|
||||
let countryOff = Country.createCountry(
|
||||
builder: &b,
|
||||
name: country,
|
||||
log: 200,
|
||||
lan: 100)
|
||||
b.finish(offset: countryOff, addPrefix: true)
|
||||
// swiftformat:disable all
|
||||
let v: [UInt8] = [44, 0, 0, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 8, 0, 12, 0, 10, 0, 0, 0, 12, 0, 0, 0, 100, 0, 0, 0, 200, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0]
|
||||
// swiftformat:enable all
|
||||
XCTAssertEqual(b.sizedByteArray, v)
|
||||
}
|
||||
|
||||
func testReadCountry() {
|
||||
// swiftformat:disable all
|
||||
let v: [UInt8] = [16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 8, 0, 12, 0, 10, 0, 0, 0, 12, 0, 0, 0, 100, 0, 0, 0, 200, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0]
|
||||
// swiftformat:enable all
|
||||
let buffer = ByteBuffer(bytes: v)
|
||||
let c = Country.getRootAsCountry(buffer)
|
||||
XCTAssertEqual(c.lan, 100)
|
||||
@ -115,14 +129,20 @@ class Country {
|
||||
__t = t
|
||||
}
|
||||
|
||||
var lan: Int32 { let o = __t.offset(6); return o == 0 ? 0 : __t.readBuffer(of: Int32.self, at: o) }
|
||||
var log: Int32 { let o = __t.offset(8); return o == 0 ? 0 : __t.readBuffer(of: Int32.self, at: o) }
|
||||
var lan: Int32 { let o = __t.offset(6); return o == 0 ? 0 : __t.readBuffer(
|
||||
of: Int32.self,
|
||||
at: o) }
|
||||
var log: Int32 { let o = __t.offset(8); return o == 0 ? 0 : __t.readBuffer(
|
||||
of: Int32.self,
|
||||
at: o) }
|
||||
var nameVector: [UInt8]? { __t.getVector(at: 4) }
|
||||
var name: String? { let o = __t.offset(4); return o == 0 ? nil : __t.string(at: o) }
|
||||
|
||||
@inlinable
|
||||
static func getRootAsCountry(_ bb: ByteBuffer) -> Country {
|
||||
Country(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: 0))))
|
||||
Country(Table(
|
||||
bb: bb,
|
||||
position: Int32(bb.read(def: UOffset.self, position: 0))))
|
||||
}
|
||||
|
||||
@inlinable
|
||||
@ -132,7 +152,11 @@ class Country {
|
||||
log: Int32,
|
||||
lan: Int32) -> Offset
|
||||
{
|
||||
createCountry(builder: &builder, offset: builder.create(string: name), log: log, lan: lan)
|
||||
createCountry(
|
||||
builder: &builder,
|
||||
offset: builder.create(string: name),
|
||||
log: log,
|
||||
lan: lan)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
|
@ -34,7 +34,9 @@ final class FlatBuffersUnionTests: XCTestCase {
|
||||
equippedOffset: weapon.o)
|
||||
b.finish(offset: root)
|
||||
let buffer = b.sizedByteArray
|
||||
// swiftformat:disable all
|
||||
XCTAssertEqual(buffer, [16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 7, 0, 12, 0, 10, 0, 0, 0, 0, 0, 0, 1, 8, 0, 0, 0, 20, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 8, 0, 12, 0, 8, 0, 6, 0, 8, 0, 0, 0, 0, 0, 5, 0, 4, 0, 0, 0, 3, 0, 0, 0, 65, 120, 101, 0])
|
||||
// swiftformat:enable all
|
||||
let monster = LocalMonster.getRootAsMonster(bb: ByteBuffer(bytes: buffer))
|
||||
XCTAssertEqual(monster.weapon(at: 0)?.dmg, dmg)
|
||||
XCTAssertEqual(monster.weapon(at: 0)?.name, str)
|
||||
@ -71,7 +73,9 @@ final class FlatBuffersUnionTests: XCTestCase {
|
||||
equippedOffset: weaponTwo,
|
||||
path: path)
|
||||
builder.finish(offset: orc)
|
||||
// swiftformat:disable all
|
||||
XCTAssertEqual(builder.sizedByteArray, [32, 0, 0, 0, 0, 0, 26, 0, 48, 0, 36, 0, 0, 0, 34, 0, 28, 0, 0, 0, 24, 0, 23, 0, 16, 0, 15, 0, 8, 0, 4, 0, 26, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 76, 0, 0, 0, 0, 0, 44, 1, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 2, 0, 0, 0, 0, 0, 128, 64, 0, 0, 160, 64, 0, 0, 192, 64, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 2, 0, 0, 0, 52, 0, 0, 0, 28, 0, 0, 0, 10, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 3, 0, 0, 0, 79, 114, 99, 0, 244, 255, 255, 255, 0, 0, 5, 0, 24, 0, 0, 0, 8, 0, 12, 0, 8, 0, 6, 0, 8, 0, 0, 0, 0, 0, 3, 0, 12, 0, 0, 0, 3, 0, 0, 0, 65, 120, 101, 0, 5, 0, 0, 0, 83, 119, 111, 114, 100, 0, 0, 0])
|
||||
// swiftformat:enable all
|
||||
}
|
||||
|
||||
func testEnumVector() {
|
||||
@ -83,7 +87,9 @@ final class FlatBuffersUnionTests: XCTestCase {
|
||||
ColorsNameSpace.Monster.add(colors: off, &builder)
|
||||
let end = ColorsNameSpace.Monster.endMonster(&builder, start: start)
|
||||
builder.finish(offset: end)
|
||||
// swiftformat:disable all
|
||||
XCTAssertEqual(builder.sizedByteArray, [12, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0])
|
||||
// swiftformat:enable all
|
||||
let monster = ColorsNameSpace.Monster.getRootAsMonster(bb: builder.buffer)
|
||||
XCTAssertEqual(monster.colorsCount, 2)
|
||||
XCTAssertEqual(monster.colors(at: 0), .blue)
|
||||
@ -121,22 +127,36 @@ final class FlatBuffersUnionTests: XCTestCase {
|
||||
XCTAssertEqual(movie.charactersType(at: i), characterType[Int(i)])
|
||||
}
|
||||
|
||||
XCTAssertEqual(movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead, 7)
|
||||
XCTAssertEqual(movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage, swordDmg)
|
||||
XCTAssertEqual(movie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead, 2)
|
||||
XCTAssertEqual(
|
||||
movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead,
|
||||
7)
|
||||
XCTAssertEqual(
|
||||
movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage,
|
||||
swordDmg)
|
||||
XCTAssertEqual(
|
||||
movie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead,
|
||||
2)
|
||||
|
||||
var objc: MovieT? = movie.unpack()
|
||||
XCTAssertEqual(movie.charactersTypeCount, Int32(objc?.characters.count ?? 0))
|
||||
XCTAssertEqual(movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead, (objc?.characters[0]?.value as? BookReader)?.booksRead)
|
||||
XCTAssertEqual(
|
||||
movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead,
|
||||
(objc?.characters[0]?.value as? BookReader)?.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_Mutable.self)?.booksRead, movie.characters(at: 0, type: BookReader_Mutable.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_Mutable.self)?.booksRead, movie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead)
|
||||
XCTAssertEqual(
|
||||
packedMovie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead,
|
||||
movie.characters(at: 0, type: BookReader_Mutable.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_Mutable.self)?.booksRead,
|
||||
movie.characters(at: 2, type: BookReader_Mutable.self)?.booksRead)
|
||||
}
|
||||
|
||||
func testStringUnion() {
|
||||
@ -162,7 +182,9 @@ final class FlatBuffersUnionTests: XCTestCase {
|
||||
|
||||
var movie = Movie.getRootAsMovie(bb: fb.sizedBuffer)
|
||||
XCTAssertEqual(movie.mainCharacter(type: String.self), string)
|
||||
XCTAssertEqual(movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead, 7)
|
||||
XCTAssertEqual(
|
||||
movie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead,
|
||||
7)
|
||||
XCTAssertEqual(movie.characters(at: 1, type: String.self), string)
|
||||
|
||||
var objc: MovieT? = movie.unpack()
|
||||
@ -175,7 +197,9 @@ final class FlatBuffersUnionTests: XCTestCase {
|
||||
|
||||
let packedMovie = Movie.getRootAsMovie(bb: fb.buffer)
|
||||
XCTAssertEqual(packedMovie.mainCharacter(type: String.self), string)
|
||||
XCTAssertEqual(packedMovie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead, 7)
|
||||
XCTAssertEqual(
|
||||
packedMovie.characters(at: 0, type: BookReader_Mutable.self)?.booksRead,
|
||||
7)
|
||||
XCTAssertEqual(packedMovie.characters(at: 1, type: String.self), string)
|
||||
}
|
||||
}
|
||||
@ -239,7 +263,10 @@ struct FinalMonster {
|
||||
builder.add(offset: inventory, at: 14)
|
||||
builder.add(element: color.rawValue, def: Color3.green.rawValue, at: 16)
|
||||
builder.add(offset: weapons, at: 18)
|
||||
builder.add(element: equipment.rawValue, def: Equipment.none.rawValue, at: 20)
|
||||
builder.add(
|
||||
element: equipment.rawValue,
|
||||
def: Equipment.none.rawValue,
|
||||
at: 20)
|
||||
builder.add(offset: equippedOffset, at: 22)
|
||||
builder.add(offset: path, at: 24)
|
||||
return Offset(offset: builder.endTable(at: start))
|
||||
@ -262,7 +289,9 @@ struct LocalMonster {
|
||||
}
|
||||
|
||||
static func getRootAsMonster(bb: ByteBuffer) -> LocalMonster {
|
||||
LocalMonster(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: 0))))
|
||||
LocalMonster(Table(
|
||||
bb: bb,
|
||||
position: Int32(bb.read(def: UOffset.self, position: 0))))
|
||||
}
|
||||
|
||||
@inlinable
|
||||
@ -290,11 +319,15 @@ struct Weapon: FlatBufferObject {
|
||||
init(_ t: Table) { __t = t }
|
||||
init(_ fb: ByteBuffer, o: Int32) { __t = Table(bb: fb, position: o)}
|
||||
|
||||
var dmg: Int16 { let o = __t.offset(6); return o == 0 ? 0 : __t.readBuffer(of: Int16.self, at: o) }
|
||||
var dmg: Int16 { let o = __t.offset(6); return o == 0 ? 0 : __t.readBuffer(
|
||||
of: Int16.self,
|
||||
at: o) }
|
||||
var nameVector: [UInt8]? { __t.getVector(at: 4) }
|
||||
var name: String? { let o = __t.offset(4); return o == 0 ? nil : __t.string(at: o) }
|
||||
|
||||
static func assign(_ i: Int32, _ bb: ByteBuffer) -> Weapon { Weapon(Table(bb: bb, position: i)) }
|
||||
static func assign(_ i: Int32, _ bb: ByteBuffer) -> Weapon { Weapon(Table(
|
||||
bb: bb,
|
||||
position: i)) }
|
||||
|
||||
@inlinable
|
||||
static func createWeapon(
|
||||
|
@ -30,7 +30,9 @@ final class FlatBuffersVectors: XCTestCase {
|
||||
let vector = [n, d]
|
||||
let vectorOffset = b.createVector(ofOffsets: vector)
|
||||
b.finish(offset: vectorOffset)
|
||||
// swiftformat:disable all
|
||||
XCTAssertEqual(b.sizedByteArray, [4, 0, 0, 0, 2, 0, 0, 0, 48, 0, 0, 0, 16, 0, 0, 0, 0, 0, 10, 0, 18, 0, 4, 0, 8, 0, 12, 0, 10, 0, 0, 0, 40, 0, 0, 0, 100, 0, 0, 0, 200, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 8, 0, 12, 0, 10, 0, 0, 0, 24, 0, 0, 0, 188, 2, 0, 0, 120, 3, 0, 0, 7, 0, 0, 0, 68, 101, 110, 109, 97, 114, 107, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0])
|
||||
// swiftformat:enable all
|
||||
}
|
||||
|
||||
func testCreateIntArray() {
|
||||
@ -38,7 +40,9 @@ final class FlatBuffersVectors: XCTestCase {
|
||||
var b = FlatBufferBuilder(initialSize: 20)
|
||||
let o = b.createVector(numbers, size: numbers.count)
|
||||
b.finish(offset: o)
|
||||
// swiftformat:disable all
|
||||
XCTAssertEqual(b.sizedByteArray, [4, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0])
|
||||
// swiftformat:enable all
|
||||
}
|
||||
|
||||
func testCreateEmptyIntArray() {
|
||||
@ -54,7 +58,9 @@ final class FlatBuffersVectors: XCTestCase {
|
||||
var b = FlatBufferBuilder(initialSize: 20)
|
||||
let o = b.createVector(ofStrings: strs)
|
||||
b.finish(offset: o)
|
||||
// swiftformat:disable all
|
||||
XCTAssertEqual(b.sizedByteArray, [4, 0, 0, 0, 2, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0, 7, 0, 0, 0, 68, 101, 110, 109, 97, 114, 107, 0])
|
||||
// swiftformat:enable all
|
||||
}
|
||||
func testCreateSharedStringVector() {
|
||||
let norway = "Norway"
|
||||
@ -67,7 +73,9 @@ final class FlatBuffersVectors: XCTestCase {
|
||||
let v = [noStr, deStr, _noStr, _deStr]
|
||||
let end = b.createVector(ofOffsets: v)
|
||||
b.finish(offset: end)
|
||||
// swiftformat:disable all
|
||||
XCTAssertEqual(b.sizedByteArray, [4, 0, 0, 0, 4, 0, 0, 0, 28, 0, 0, 0, 12, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 68, 101, 110, 109, 97, 114, 107, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0])
|
||||
// swiftformat:enable all
|
||||
}
|
||||
|
||||
func testReadInt32Array() {
|
||||
@ -101,7 +109,9 @@ struct Numbers {
|
||||
|
||||
@inlinable
|
||||
static func getRootAsNumbers(_ bb: ByteBuffer) -> Numbers {
|
||||
Numbers(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: 0))))
|
||||
Numbers(Table(
|
||||
bb: bb,
|
||||
position: Int32(bb.read(def: UOffset.self, position: 0))))
|
||||
}
|
||||
|
||||
var vArrayInt: [Int]? { __t.getVector(at: 4) }
|
||||
|
@ -23,17 +23,39 @@ final class FlatBuffersDoubleTests: XCTestCase {
|
||||
|
||||
func testCreateFinish() {
|
||||
var b = FlatBufferBuilder(initialSize: 16)
|
||||
let countryOff = CountryDouble.createCountry(builder: &b, name: country, log: 200, lan: 100)
|
||||
let countryOff = CountryDouble.createCountry(
|
||||
builder: &b,
|
||||
name: country,
|
||||
log: 200,
|
||||
lan: 100)
|
||||
b.finish(offset: countryOff)
|
||||
let v: [UInt8] = [16, 0, 0, 0, 0, 0, 10, 0, 28, 0, 4, 0, 8, 0, 16, 0, 10, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 64, 0, 0, 0, 0, 0, 0, 105, 64, 0, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0]
|
||||
// swiftformat:disable all
|
||||
let v: [UInt8] = [
|
||||
16, 0, 0, 0, 0, 0, 10, 0, 28, 0, 4, 0, 8, 0, 16, 0, 10,
|
||||
0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 64, 0, 0, 0,
|
||||
0, 0, 0, 105, 64, 0, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119,
|
||||
97, 121, 0, 0
|
||||
]
|
||||
// swiftformat:enable all
|
||||
XCTAssertEqual(b.sizedByteArray, v)
|
||||
}
|
||||
|
||||
func testCreateFinishWithPrefix() {
|
||||
var b = FlatBufferBuilder(initialSize: 16)
|
||||
let countryOff = CountryDouble.createCountry(builder: &b, name: country, log: 200, lan: 100)
|
||||
let countryOff = CountryDouble.createCountry(
|
||||
builder: &b,
|
||||
name: country,
|
||||
log: 200,
|
||||
lan: 100)
|
||||
b.finish(offset: countryOff, addPrefix: true)
|
||||
let v: [UInt8] = [60, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 28, 0, 4, 0, 8, 0, 16, 0, 10, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 64, 0, 0, 0, 0, 0, 0, 105, 64, 0, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0]
|
||||
// swiftformat:disable all
|
||||
let v: [UInt8] = [
|
||||
60, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 28
|
||||
, 0, 4, 0, 8, 0, 16, 0, 10, 0, 0, 0, 24, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 89, 64, 0, 0, 0, 0, 0, 0, 105, 64, 0, 0, 0,
|
||||
0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0
|
||||
]
|
||||
// swiftformat:enable all
|
||||
XCTAssertEqual(b.sizedByteArray, v)
|
||||
}
|
||||
}
|
||||
@ -57,7 +79,11 @@ class CountryDouble {
|
||||
log: Double,
|
||||
lan: Double) -> Offset
|
||||
{
|
||||
createCountry(builder: &builder, offset: builder.create(string: name), log: log, lan: lan)
|
||||
createCountry(
|
||||
builder: &builder,
|
||||
offset: builder.create(string: name),
|
||||
log: log,
|
||||
lan: lan)
|
||||
}
|
||||
|
||||
static func createCountry(
|
||||
|
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import XCTest
|
||||
@testable import FlatBuffers
|
||||
|
||||
final class FlatbuffersVerifierTests: XCTestCase {
|
||||
|
||||
lazy var validStorage: ByteBuffer.Storage = ByteBuffer.Storage(
|
||||
count: Int(FlatBufferMaxSize) - 1,
|
||||
alignment: 1)
|
||||
lazy var errorStorage: ByteBuffer.Storage = ByteBuffer.Storage(
|
||||
count: Int(FlatBufferMaxSize) + 1,
|
||||
alignment: 1)
|
||||
|
||||
var buffer: ByteBuffer!
|
||||
|
||||
var validFlatbuffersObject: ByteBuffer!
|
||||
var invalidFlatbuffersObject: ByteBuffer!
|
||||
|
||||
override func setUp() {
|
||||
// swiftformat:disable all
|
||||
buffer = ByteBuffer(initialSize: 32)
|
||||
add(buffer: &buffer, v: 4, p: 16)
|
||||
add(buffer: &buffer, v: 4, p: 20)
|
||||
|
||||
validFlatbuffersObject = ByteBuffer(bytes: [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])
|
||||
|
||||
invalidFlatbuffersObject = ByteBuffer(bytes: [0, 48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 68, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 120, 0, 0, 0, 0, 0, 80, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 64, 2, 0, 5, 0, 6, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 30, 0, 40, 0, 10, 0, 20, 0, 152, 255, 255, 255, 4, 0, 0, 0, 4, 0, 0, 0, 70, 114, 101, 100, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 50, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 49, 0, 0, 0, 9, 0, 0, 0, 77, 121, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 4, 0, 0, 0, 240, 255, 255, 255, 32, 0, 0, 0, 248, 255, 255, 255, 36, 0, 0, 0, 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 12, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 87, 105, 108, 109, 97, 0, 0, 0, 6, 0, 0, 0, 66, 97, 114, 110, 101, 121, 0, 0, 5, 0, 0, 0, 70, 114, 111, 100, 111, 0, 0, 0])
|
||||
|
||||
// swiftformat:enable all
|
||||
}
|
||||
|
||||
func testVeriferInitPassing() {
|
||||
var buffer = ByteBuffer(initialSize: 0)
|
||||
buffer._storage = validStorage
|
||||
XCTAssertNoThrow(try Verifier(buffer: &buffer))
|
||||
}
|
||||
|
||||
func testVeriferInitFailing() {
|
||||
var buffer = ByteBuffer(initialSize: 0)
|
||||
buffer._storage = errorStorage
|
||||
XCTAssertThrowsError(try Verifier(buffer: &buffer))
|
||||
}
|
||||
|
||||
func testVerifierCheckAlignment() {
|
||||
var verifier = try! Verifier(buffer: &buffer)
|
||||
do {
|
||||
try verifier.isAligned(position: 20, type: Int.self)
|
||||
} catch {
|
||||
XCTAssertEqual(
|
||||
error as? FlatbuffersErrors,
|
||||
.missAlignedPointer(position: 20, type: "Int"))
|
||||
}
|
||||
XCTAssertNoThrow(try verifier.isAligned(position: 16, type: Int.self))
|
||||
|
||||
var newVerifer = try! Verifier(buffer: &buffer, checkAlignment: false)
|
||||
XCTAssertNoThrow(try newVerifer.isAligned(position: 16, type: Int.self))
|
||||
}
|
||||
|
||||
func testRangeInBuffer() {
|
||||
var verifier = try! Verifier(buffer: &buffer)
|
||||
let size = MemoryLayout<Int64>.size
|
||||
XCTAssertNoThrow(try verifier.rangeInBuffer(position: 24, size: size))
|
||||
XCTAssertThrowsError(try verifier.rangeInBuffer(position: 26, size: size))
|
||||
XCTAssertThrowsError(try verifier.rangeInBuffer(position: 26, size: size))
|
||||
XCTAssertThrowsError(try verifier.rangeInBuffer(position: 30, size: size))
|
||||
XCTAssertThrowsError(try verifier.rangeInBuffer(position: 32, size: size))
|
||||
XCTAssertThrowsError(try verifier.rangeInBuffer(position: 34, size: size))
|
||||
|
||||
verifier = try! Verifier(
|
||||
buffer: &buffer,
|
||||
options: .init(maxDepth: 0, maxTableCount: 0, maxApparentSize: 4))
|
||||
do {
|
||||
try verifier.rangeInBuffer(position: 24, size: size)
|
||||
} catch {
|
||||
XCTAssertEqual(
|
||||
error as! FlatbuffersErrors,
|
||||
.apparentSizeTooLarge)
|
||||
}
|
||||
}
|
||||
|
||||
func testPositionInBuffer() {
|
||||
var verifier = try! Verifier(buffer: &buffer)
|
||||
XCTAssertNoThrow(try verifier.inBuffer(position: 0, of: Int64.self))
|
||||
XCTAssertNoThrow(try verifier.inBuffer(position: 24, of: Int64.self))
|
||||
XCTAssertThrowsError(try verifier.inBuffer(position: -9, of: Int64.self))
|
||||
XCTAssertThrowsError(try verifier.inBuffer(position: 25, of: Int64.self))
|
||||
XCTAssertThrowsError(try verifier.inBuffer(position: 26, of: Int32.self))
|
||||
XCTAssertThrowsError(try verifier.inBuffer(position: 26, of: Int64.self))
|
||||
XCTAssertThrowsError(try verifier.inBuffer(position: 30, of: Int64.self))
|
||||
XCTAssertThrowsError(try verifier.inBuffer(position: 32, of: Int64.self))
|
||||
XCTAssertThrowsError(try verifier.inBuffer(position: 34, of: Int64.self))
|
||||
}
|
||||
|
||||
func testVisitTable() {
|
||||
var verifier = try! Verifier(buffer: &validFlatbuffersObject)
|
||||
XCTAssertNoThrow(try verifier.visitTable(at: 48))
|
||||
verifier.reset()
|
||||
}
|
||||
|
||||
func testTableVerifier() {
|
||||
var verifier = try! Verifier(buffer: &validFlatbuffersObject)
|
||||
|
||||
var tableVerifer = try! verifier.visitTable(at: 48)
|
||||
XCTAssertNoThrow(try tableVerifer.visit(
|
||||
field: 4,
|
||||
fieldName: "Vec",
|
||||
required: false,
|
||||
type: Vec3.self))
|
||||
XCTAssertNoThrow(try tableVerifer.visit(
|
||||
field: 8,
|
||||
fieldName: "hp",
|
||||
required: false,
|
||||
type: Int16.self))
|
||||
|
||||
XCTAssertNoThrow(try tableVerifer.visit(
|
||||
field: 10,
|
||||
fieldName: "name",
|
||||
required: true,
|
||||
type: ForwardOffset<String>.self))
|
||||
|
||||
XCTAssertNoThrow(try tableVerifer.visit(
|
||||
field: 14,
|
||||
fieldName: "inventory",
|
||||
required: false,
|
||||
type: ForwardOffset<Vector<UInt8, UInt8>>.self))
|
||||
|
||||
XCTAssertNoThrow(try tableVerifer.visit(
|
||||
field: 22,
|
||||
fieldName: "test4",
|
||||
required: false,
|
||||
type: ForwardOffset<Vector<MyGame_Example_Test, MyGame_Example_Test>>.self))
|
||||
|
||||
XCTAssertNoThrow(try tableVerifer.visit(
|
||||
field: 24,
|
||||
fieldName: "Vector of strings",
|
||||
required: false,
|
||||
type: ForwardOffset<Vector<ForwardOffset<String>, String>>.self))
|
||||
|
||||
do {
|
||||
try tableVerifer.visit(
|
||||
field: 13,
|
||||
fieldName: "notvalid",
|
||||
required: false,
|
||||
type: Int16.self)
|
||||
} catch {
|
||||
XCTAssertEqual(
|
||||
error as! FlatbuffersErrors,
|
||||
.missAlignedPointer(position: 25, type: "UInt16"))
|
||||
}
|
||||
|
||||
do {
|
||||
try tableVerifer.visit(
|
||||
unionKey: 18,
|
||||
unionField: 20,
|
||||
unionKeyName: "testType",
|
||||
fieldName: "test",
|
||||
required: false,
|
||||
completion: { (verifier, key: MyGame_Example_Any_, pos) in
|
||||
switch key {
|
||||
case .none_:
|
||||
break
|
||||
case .monster:
|
||||
try ForwardOffset<MyGame_Example_Monster>.verify(
|
||||
&verifier,
|
||||
at: pos,
|
||||
of: MyGame_Example_Monster.self)
|
||||
|
||||
case .testsimpletablewithenum:
|
||||
break
|
||||
case .mygameExample2Monster:
|
||||
break
|
||||
}
|
||||
})
|
||||
} catch {
|
||||
XCTAssertEqual(
|
||||
error as! FlatbuffersErrors,
|
||||
.missAlignedPointer(position: 25, type: "UInt16"))
|
||||
}
|
||||
}
|
||||
|
||||
func testVerifyUnionVectors() {
|
||||
// swiftformat:disable all
|
||||
var byteBuffer = ByteBuffer(bytes: [20, 0, 0, 0, 77, 79, 86, 73, 12, 0, 12, 0, 0, 0, 0, 0, 8, 0, 4, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 24, 0, 0, 0, 32, 0, 0, 0, 12, 0, 0, 0, 3, 0, 0, 0, 3, 1, 4, 0, 2, 0, 0, 0, 7, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 8, 0, 0, 0])
|
||||
// swiftformat:enable all
|
||||
XCTAssertNoThrow(try getCheckedRoot(byteBuffer: &byteBuffer) as Movie)
|
||||
}
|
||||
|
||||
func testFullVerifier() {
|
||||
XCTAssertNoThrow(try getCheckedRoot(byteBuffer: &validFlatbuffersObject) as MyGame_Example_Monster)
|
||||
}
|
||||
|
||||
func testInvalidBuffer() {
|
||||
XCTAssertThrowsError(try getCheckedRoot(byteBuffer: &invalidFlatbuffersObject) as MyGame_Example_Monster)
|
||||
}
|
||||
|
||||
func testValidUnionBuffer() {
|
||||
let string = "Awesome \\\\t\t\nstring!"
|
||||
var fb = FlatBufferBuilder()
|
||||
let stringOffset = fb.create(string: string)
|
||||
let characterType: [Character] = [.bookfan, .other]
|
||||
|
||||
let characters = [
|
||||
fb.create(struct: BookReader(booksRead: 7)),
|
||||
stringOffset,
|
||||
]
|
||||
let types = fb.createVector(characterType)
|
||||
let characterVector = fb.createVector(ofOffsets: characters)
|
||||
|
||||
let end = Movie.createMovie(
|
||||
&fb,
|
||||
mainCharacterType: .other,
|
||||
mainCharacterOffset: Offset(offset: stringOffset.o),
|
||||
charactersTypeVectorOffset: types,
|
||||
charactersVectorOffset: characterVector)
|
||||
Movie.finish(&fb, end: end)
|
||||
var buf = fb.sizedBuffer
|
||||
XCTAssertNoThrow(try getCheckedRoot(byteBuffer: &buf) as Movie)
|
||||
}
|
||||
|
||||
func add(buffer: inout ByteBuffer, v: Int32, p: Int) {
|
||||
buffer.write(value: v, index: p)
|
||||
}
|
||||
}
|
@ -36,11 +36,17 @@ extension FlatBuffersMonsterWriterTests {
|
||||
("testCreateMonster", testCreateMonster),
|
||||
("testCreateMonsterPrefixed", testCreateMonsterPrefixed),
|
||||
("testCreateMonsterResizedBuffer", testCreateMonsterResizedBuffer),
|
||||
("testCreateMonsterUsingCreateMonsterMethodWithNilPos", testCreateMonsterUsingCreateMonsterMethodWithNilPos),
|
||||
("testCreateMonsterUsingCreateMonsterMethodWithPosX", testCreateMonsterUsingCreateMonsterMethodWithPosX),
|
||||
(
|
||||
"testCreateMonsterUsingCreateMonsterMethodWithNilPos",
|
||||
testCreateMonsterUsingCreateMonsterMethodWithNilPos),
|
||||
(
|
||||
"testCreateMonsterUsingCreateMonsterMethodWithPosX",
|
||||
testCreateMonsterUsingCreateMonsterMethodWithPosX),
|
||||
("testData", testData),
|
||||
("testReadFromOtherLanguages", testReadFromOtherLanguages),
|
||||
("testReadMonsterFromUnsafePointerWithoutCopying", testReadMonsterFromUnsafePointerWithoutCopying),
|
||||
(
|
||||
"testReadMonsterFromUnsafePointerWithoutCopying",
|
||||
testReadMonsterFromUnsafePointerWithoutCopying),
|
||||
]
|
||||
}
|
||||
|
||||
@ -108,6 +114,25 @@ extension FlatBuffersVectors {
|
||||
]
|
||||
}
|
||||
|
||||
extension FlatbuffersVerifierTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__FlatbuffersVerifierTests = [
|
||||
("testFullVerifier", testFullVerifier),
|
||||
("testInvalidBuffer", testInvalidBuffer),
|
||||
("testPositionInBuffer", testPositionInBuffer),
|
||||
("testRangeInBuffer", testRangeInBuffer),
|
||||
("testTableVerifier", testTableVerifier),
|
||||
("testValidUnionBuffer", testValidUnionBuffer),
|
||||
("testVeriferInitFailing", testVeriferInitFailing),
|
||||
("testVeriferInitPassing", testVeriferInitPassing),
|
||||
("testVerifierCheckAlignment", testVerifierCheckAlignment),
|
||||
("testVerifyUnionVectors", testVerifyUnionVectors),
|
||||
("testVisitTable", testVisitTable),
|
||||
]
|
||||
}
|
||||
|
||||
public func __allTests() -> [XCTestCaseEntry] {
|
||||
[
|
||||
testCase(FlatBuffersDoubleTests.__allTests__FlatBuffersDoubleTests),
|
||||
@ -117,6 +142,7 @@ public func __allTests() -> [XCTestCaseEntry] {
|
||||
testCase(FlatBuffersTests.__allTests__FlatBuffersTests),
|
||||
testCase(FlatBuffersUnionTests.__allTests__FlatBuffersUnionTests),
|
||||
testCase(FlatBuffersVectors.__allTests__FlatBuffersVectors),
|
||||
testCase(FlatbuffersVerifierTests.__allTests__FlatbuffersVerifierTests),
|
||||
]
|
||||
}
|
||||
#endif
|
||||
|
@ -5,7 +5,7 @@
|
||||
import FlatBuffers
|
||||
|
||||
/// Composite components of Monster color.
|
||||
public enum MyGame_Example_Color: UInt8, Enum {
|
||||
public enum MyGame_Example_Color: UInt8, Enum, Verifiable {
|
||||
public typealias T = UInt8
|
||||
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
|
||||
public var value: UInt8 { return self.rawValue }
|
||||
@ -15,13 +15,12 @@ public enum MyGame_Example_Color: UInt8, Enum {
|
||||
case green = 2
|
||||
/// \brief color Blue (1u << 3)
|
||||
case blue = 8
|
||||
|
||||
|
||||
public static var max: MyGame_Example_Color { return .blue }
|
||||
public static var min: MyGame_Example_Color { return .red }
|
||||
}
|
||||
|
||||
public enum MyGame_Example_Race: Int8, Enum {
|
||||
public enum MyGame_Example_Race: Int8, Enum, Verifiable {
|
||||
public typealias T = Int8
|
||||
public static var byteSize: Int { return MemoryLayout<Int8>.size }
|
||||
public var value: Int8 { return self.rawValue }
|
||||
@ -29,21 +28,24 @@ public enum MyGame_Example_Race: Int8, Enum {
|
||||
case human = 0
|
||||
case dwarf = 1
|
||||
case elf = 2
|
||||
|
||||
|
||||
public static var max: MyGame_Example_Race { return .elf }
|
||||
public static var min: MyGame_Example_Race { return .none_ }
|
||||
}
|
||||
|
||||
public enum MyGame_Example_Any_: UInt8, Enum {
|
||||
public enum MyGame_Example_Any_: UInt8, UnionEnum {
|
||||
public typealias T = UInt8
|
||||
|
||||
public init?(value: T) {
|
||||
self.init(rawValue: value)
|
||||
}
|
||||
|
||||
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
|
||||
public var value: UInt8 { return self.rawValue }
|
||||
case none_ = 0
|
||||
case monster = 1
|
||||
case testsimpletablewithenum = 2
|
||||
case mygameExample2Monster = 3
|
||||
|
||||
|
||||
public static var max: MyGame_Example_Any_ { return .mygameExample2Monster }
|
||||
public static var min: MyGame_Example_Any_ { return .none_ }
|
||||
@ -71,15 +73,19 @@ public struct MyGame_Example_Any_Union {
|
||||
}
|
||||
}
|
||||
}
|
||||
public enum MyGame_Example_AnyUniqueAliases: UInt8, Enum {
|
||||
public enum MyGame_Example_AnyUniqueAliases: UInt8, UnionEnum {
|
||||
public typealias T = UInt8
|
||||
|
||||
public init?(value: T) {
|
||||
self.init(rawValue: value)
|
||||
}
|
||||
|
||||
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
|
||||
public var value: UInt8 { return self.rawValue }
|
||||
case none_ = 0
|
||||
case m = 1
|
||||
case ts = 2
|
||||
case m2 = 3
|
||||
|
||||
|
||||
public static var max: MyGame_Example_AnyUniqueAliases { return .m2 }
|
||||
public static var min: MyGame_Example_AnyUniqueAliases { return .none_ }
|
||||
@ -107,15 +113,19 @@ public struct MyGame_Example_AnyUniqueAliasesUnion {
|
||||
}
|
||||
}
|
||||
}
|
||||
public enum MyGame_Example_AnyAmbiguousAliases: UInt8, Enum {
|
||||
public enum MyGame_Example_AnyAmbiguousAliases: UInt8, UnionEnum {
|
||||
public typealias T = UInt8
|
||||
|
||||
public init?(value: T) {
|
||||
self.init(rawValue: value)
|
||||
}
|
||||
|
||||
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
|
||||
public var value: UInt8 { return self.rawValue }
|
||||
case none_ = 0
|
||||
case m1 = 1
|
||||
case m2 = 2
|
||||
case m3 = 3
|
||||
|
||||
|
||||
public static var max: MyGame_Example_AnyAmbiguousAliases { return .m3 }
|
||||
public static var min: MyGame_Example_AnyAmbiguousAliases { return .none_ }
|
||||
@ -143,7 +153,7 @@ public struct MyGame_Example_AnyAmbiguousAliasesUnion {
|
||||
}
|
||||
}
|
||||
}
|
||||
public struct MyGame_Example_Test: NativeStruct, NativeObject {
|
||||
public struct MyGame_Example_Test: NativeStruct, Verifiable, NativeObject {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
|
||||
@ -168,6 +178,10 @@ public struct MyGame_Example_Test: NativeStruct, NativeObject {
|
||||
|
||||
public var a: Int16 { _a }
|
||||
public var b: Int8 { _b }
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
try verifier.inBuffer(position: position, of: MyGame_Example_Test.self)
|
||||
}
|
||||
}
|
||||
|
||||
public struct MyGame_Example_Test_Mutable: FlatBufferObject {
|
||||
@ -197,7 +211,7 @@ public struct MyGame_Example_Test_Mutable: FlatBufferObject {
|
||||
}
|
||||
}
|
||||
|
||||
public struct MyGame_Example_Vec3: NativeStruct, NativeObject {
|
||||
public struct MyGame_Example_Vec3: NativeStruct, Verifiable, NativeObject {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
|
||||
@ -245,6 +259,10 @@ public struct MyGame_Example_Vec3: NativeStruct, NativeObject {
|
||||
public var test1: Double { _test1 }
|
||||
public var test2: MyGame_Example_Color { MyGame_Example_Color(rawValue: _test2)! }
|
||||
public var test3: MyGame_Example_Test { _test3 }
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
try verifier.inBuffer(position: position, of: MyGame_Example_Vec3.self)
|
||||
}
|
||||
}
|
||||
|
||||
public struct MyGame_Example_Vec3_Mutable: FlatBufferObject {
|
||||
@ -281,7 +299,7 @@ public struct MyGame_Example_Vec3_Mutable: FlatBufferObject {
|
||||
}
|
||||
}
|
||||
|
||||
public struct MyGame_Example_Ability: NativeStruct, NativeObject {
|
||||
public struct MyGame_Example_Ability: NativeStruct, Verifiable, NativeObject {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
|
||||
@ -305,6 +323,10 @@ public struct MyGame_Example_Ability: NativeStruct, NativeObject {
|
||||
|
||||
public var id: UInt32 { _id }
|
||||
public var distance: UInt32 { _distance }
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
try verifier.inBuffer(position: position, of: MyGame_Example_Ability.self)
|
||||
}
|
||||
}
|
||||
|
||||
public struct MyGame_Example_Ability_Mutable: FlatBufferObject {
|
||||
@ -334,7 +356,7 @@ public struct MyGame_Example_Ability_Mutable: FlatBufferObject {
|
||||
}
|
||||
}
|
||||
|
||||
public struct MyGame_Example_StructOfStructs: NativeStruct, NativeObject {
|
||||
public struct MyGame_Example_StructOfStructs: NativeStruct, Verifiable, NativeObject {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
|
||||
@ -366,6 +388,10 @@ public struct MyGame_Example_StructOfStructs: NativeStruct, NativeObject {
|
||||
public var a: MyGame_Example_Ability { _a }
|
||||
public var b: MyGame_Example_Test { _b }
|
||||
public var c: MyGame_Example_Ability { _c }
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
try verifier.inBuffer(position: position, of: MyGame_Example_StructOfStructs.self)
|
||||
}
|
||||
}
|
||||
|
||||
public struct MyGame_Example_StructOfStructs_Mutable: FlatBufferObject {
|
||||
@ -394,7 +420,7 @@ public struct MyGame_Example_StructOfStructs_Mutable: FlatBufferObject {
|
||||
}
|
||||
}
|
||||
|
||||
public struct MyGame_InParentNamespace: FlatBufferObject, ObjectAPIPacker {
|
||||
public struct MyGame_InParentNamespace: FlatBufferObject, Verifiable, ObjectAPIPacker {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -422,6 +448,11 @@ public struct MyGame_InParentNamespace: FlatBufferObject, ObjectAPIPacker {
|
||||
let __root = MyGame_InParentNamespace.startInParentNamespace(&builder)
|
||||
return MyGame_InParentNamespace.endInParentNamespace(&builder, start: __root)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
public class MyGame_InParentNamespaceT: NativeObject {
|
||||
@ -436,7 +467,7 @@ public class MyGame_InParentNamespaceT: NativeObject {
|
||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_InParentNamespace.self) }
|
||||
|
||||
}
|
||||
public struct MyGame_Example2_Monster: FlatBufferObject, ObjectAPIPacker {
|
||||
public struct MyGame_Example2_Monster: FlatBufferObject, Verifiable, ObjectAPIPacker {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -464,6 +495,11 @@ public struct MyGame_Example2_Monster: FlatBufferObject, ObjectAPIPacker {
|
||||
let __root = MyGame_Example2_Monster.startMonster(&builder)
|
||||
return MyGame_Example2_Monster.endMonster(&builder, start: __root)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
public class MyGame_Example2_MonsterT: NativeObject {
|
||||
@ -478,7 +514,7 @@ public class MyGame_Example2_MonsterT: NativeObject {
|
||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example2_Monster.self) }
|
||||
|
||||
}
|
||||
internal struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferObject, ObjectAPIPacker {
|
||||
internal struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferObject, Verifiable, ObjectAPIPacker {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
internal var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -524,6 +560,12 @@ internal struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferObject, Object
|
||||
MyGame_Example_TestSimpleTableWithEnum.add(color: obj.color, &builder)
|
||||
return MyGame_Example_TestSimpleTableWithEnum.endTestSimpleTableWithEnum(&builder, start: __root)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.color.p, fieldName: "color", required: false, type: MyGame_Example_Color.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
internal class MyGame_Example_TestSimpleTableWithEnumT: NativeObject {
|
||||
@ -541,7 +583,7 @@ internal class MyGame_Example_TestSimpleTableWithEnumT: NativeObject {
|
||||
internal func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_TestSimpleTableWithEnum.self) }
|
||||
|
||||
}
|
||||
public struct MyGame_Example_Stat: FlatBufferObject, ObjectAPIPacker {
|
||||
public struct MyGame_Example_Stat: FlatBufferObject, Verifiable, ObjectAPIPacker {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -632,6 +674,14 @@ public struct MyGame_Example_Stat: FlatBufferObject, ObjectAPIPacker {
|
||||
MyGame_Example_Stat.add(count: obj.count, &builder)
|
||||
return MyGame_Example_Stat.endStat(&builder, start: __root)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.id.p, fieldName: "id", required: false, type: ForwardOffset<String>.self)
|
||||
try _v.visit(field: VTOFFSET.val.p, fieldName: "val", required: false, type: Int64.self)
|
||||
try _v.visit(field: VTOFFSET.count.p, fieldName: "count", required: false, type: UInt16.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
public class MyGame_Example_StatT: NativeObject {
|
||||
@ -654,7 +704,7 @@ public class MyGame_Example_StatT: NativeObject {
|
||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Stat.self) }
|
||||
|
||||
}
|
||||
public struct MyGame_Example_Referrable: FlatBufferObject, ObjectAPIPacker {
|
||||
public struct MyGame_Example_Referrable: FlatBufferObject, Verifiable, ObjectAPIPacker {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -724,6 +774,12 @@ public struct MyGame_Example_Referrable: FlatBufferObject, ObjectAPIPacker {
|
||||
MyGame_Example_Referrable.add(id: obj.id, &builder)
|
||||
return MyGame_Example_Referrable.endReferrable(&builder, start: __root)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.id.p, fieldName: "id", required: false, type: UInt64.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
public class MyGame_Example_ReferrableT: NativeObject {
|
||||
@ -742,7 +798,7 @@ public class MyGame_Example_ReferrableT: NativeObject {
|
||||
|
||||
}
|
||||
/// an example documentation comment: "monster object"
|
||||
public struct MyGame_Example_Monster: FlatBufferObject, ObjectAPIPacker {
|
||||
public struct MyGame_Example_Monster: FlatBufferObject, Verifiable, ObjectAPIPacker {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -1253,6 +1309,91 @@ public struct MyGame_Example_Monster: FlatBufferObject, ObjectAPIPacker {
|
||||
MyGame_Example_Monster.addVectorOf(scalarKeySortedTables: __scalarKeySortedTables, &builder)
|
||||
return MyGame_Example_Monster.endMonster(&builder, start: __root)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.pos.p, fieldName: "pos", required: false, type: MyGame_Example_Vec3.self)
|
||||
try _v.visit(field: VTOFFSET.mana.p, fieldName: "mana", required: false, type: Int16.self)
|
||||
try _v.visit(field: VTOFFSET.hp.p, fieldName: "hp", required: false, type: Int16.self)
|
||||
try _v.visit(field: VTOFFSET.name.p, fieldName: "name", required: true, type: ForwardOffset<String>.self)
|
||||
try _v.visit(field: VTOFFSET.inventory.p, fieldName: "inventory", required: false, type: ForwardOffset<Vector<UInt8, UInt8>>.self)
|
||||
try _v.visit(field: VTOFFSET.color.p, fieldName: "color", required: false, type: MyGame_Example_Color.self)
|
||||
try _v.visit(unionKey: VTOFFSET.testType.p, unionField: VTOFFSET.test.p, unionKeyName: "testType", fieldName: "test", required: false, completion: { (verifier, key: MyGame_Example_Any_, pos) in
|
||||
switch key {
|
||||
case .none_:
|
||||
break // NOTE - SWIFT doesnt support none
|
||||
case .monster:
|
||||
try ForwardOffset<MyGame_Example_Monster>.verify(&verifier, at: pos, of: MyGame_Example_Monster.self)
|
||||
case .testsimpletablewithenum:
|
||||
try ForwardOffset<MyGame_Example_TestSimpleTableWithEnum>.verify(&verifier, at: pos, of: MyGame_Example_TestSimpleTableWithEnum.self)
|
||||
case .mygameExample2Monster:
|
||||
try ForwardOffset<MyGame_Example2_Monster>.verify(&verifier, at: pos, of: MyGame_Example2_Monster.self)
|
||||
}
|
||||
})
|
||||
try _v.visit(field: VTOFFSET.test4.p, fieldName: "test4", required: false, type: ForwardOffset<Vector<MyGame_Example_Test, MyGame_Example_Test>>.self)
|
||||
try _v.visit(field: VTOFFSET.testarrayofstring.p, fieldName: "testarrayofstring", required: false, type: ForwardOffset<Vector<ForwardOffset<String>, String>>.self)
|
||||
try _v.visit(field: VTOFFSET.testarrayoftables.p, fieldName: "testarrayoftables", required: false, type: ForwardOffset<Vector<ForwardOffset<MyGame_Example_Monster>, MyGame_Example_Monster>>.self)
|
||||
try _v.visit(field: VTOFFSET.enemy.p, fieldName: "enemy", required: false, type: ForwardOffset<MyGame_Example_Monster>.self)
|
||||
try _v.visit(field: VTOFFSET.testnestedflatbuffer.p, fieldName: "testnestedflatbuffer", required: false, type: ForwardOffset<Vector<UInt8, UInt8>>.self)
|
||||
try _v.visit(field: VTOFFSET.testempty.p, fieldName: "testempty", required: false, type: ForwardOffset<MyGame_Example_Stat>.self)
|
||||
try _v.visit(field: VTOFFSET.testbool.p, fieldName: "testbool", required: false, type: Bool.self)
|
||||
try _v.visit(field: VTOFFSET.testhashs32Fnv1.p, fieldName: "testhashs32Fnv1", required: false, type: Int32.self)
|
||||
try _v.visit(field: VTOFFSET.testhashu32Fnv1.p, fieldName: "testhashu32Fnv1", required: false, type: UInt32.self)
|
||||
try _v.visit(field: VTOFFSET.testhashs64Fnv1.p, fieldName: "testhashs64Fnv1", required: false, type: Int64.self)
|
||||
try _v.visit(field: VTOFFSET.testhashu64Fnv1.p, fieldName: "testhashu64Fnv1", required: false, type: UInt64.self)
|
||||
try _v.visit(field: VTOFFSET.testhashs32Fnv1a.p, fieldName: "testhashs32Fnv1a", required: false, type: Int32.self)
|
||||
try _v.visit(field: VTOFFSET.testhashu32Fnv1a.p, fieldName: "testhashu32Fnv1a", required: false, type: UInt32.self)
|
||||
try _v.visit(field: VTOFFSET.testhashs64Fnv1a.p, fieldName: "testhashs64Fnv1a", required: false, type: Int64.self)
|
||||
try _v.visit(field: VTOFFSET.testhashu64Fnv1a.p, fieldName: "testhashu64Fnv1a", required: false, type: UInt64.self)
|
||||
try _v.visit(field: VTOFFSET.testarrayofbools.p, fieldName: "testarrayofbools", required: false, type: ForwardOffset<Vector<Bool, Bool>>.self)
|
||||
try _v.visit(field: VTOFFSET.testf.p, fieldName: "testf", required: false, type: Float32.self)
|
||||
try _v.visit(field: VTOFFSET.testf2.p, fieldName: "testf2", required: false, type: Float32.self)
|
||||
try _v.visit(field: VTOFFSET.testf3.p, fieldName: "testf3", required: false, type: Float32.self)
|
||||
try _v.visit(field: VTOFFSET.testarrayofstring2.p, fieldName: "testarrayofstring2", required: false, type: ForwardOffset<Vector<ForwardOffset<String>, String>>.self)
|
||||
try _v.visit(field: VTOFFSET.testarrayofsortedstruct.p, fieldName: "testarrayofsortedstruct", required: false, type: ForwardOffset<Vector<MyGame_Example_Ability, MyGame_Example_Ability>>.self)
|
||||
try _v.visit(field: VTOFFSET.flex.p, fieldName: "flex", required: false, type: ForwardOffset<Vector<UInt8, UInt8>>.self)
|
||||
try _v.visit(field: VTOFFSET.test5.p, fieldName: "test5", required: false, type: ForwardOffset<Vector<MyGame_Example_Test, MyGame_Example_Test>>.self)
|
||||
try _v.visit(field: VTOFFSET.vectorOfLongs.p, fieldName: "vectorOfLongs", required: false, type: ForwardOffset<Vector<Int64, Int64>>.self)
|
||||
try _v.visit(field: VTOFFSET.vectorOfDoubles.p, fieldName: "vectorOfDoubles", required: false, type: ForwardOffset<Vector<Double, Double>>.self)
|
||||
try _v.visit(field: VTOFFSET.parentNamespaceTest.p, fieldName: "parentNamespaceTest", required: false, type: ForwardOffset<MyGame_InParentNamespace>.self)
|
||||
try _v.visit(field: VTOFFSET.vectorOfReferrables.p, fieldName: "vectorOfReferrables", required: false, type: ForwardOffset<Vector<ForwardOffset<MyGame_Example_Referrable>, MyGame_Example_Referrable>>.self)
|
||||
try _v.visit(field: VTOFFSET.singleWeakReference.p, fieldName: "singleWeakReference", required: false, type: UInt64.self)
|
||||
try _v.visit(field: VTOFFSET.vectorOfWeakReferences.p, fieldName: "vectorOfWeakReferences", required: false, type: ForwardOffset<Vector<UInt64, UInt64>>.self)
|
||||
try _v.visit(field: VTOFFSET.vectorOfStrongReferrables.p, fieldName: "vectorOfStrongReferrables", required: false, type: ForwardOffset<Vector<ForwardOffset<MyGame_Example_Referrable>, MyGame_Example_Referrable>>.self)
|
||||
try _v.visit(field: VTOFFSET.coOwningReference.p, fieldName: "coOwningReference", required: false, type: UInt64.self)
|
||||
try _v.visit(field: VTOFFSET.vectorOfCoOwningReferences.p, fieldName: "vectorOfCoOwningReferences", required: false, type: ForwardOffset<Vector<UInt64, UInt64>>.self)
|
||||
try _v.visit(field: VTOFFSET.nonOwningReference.p, fieldName: "nonOwningReference", required: false, type: UInt64.self)
|
||||
try _v.visit(field: VTOFFSET.vectorOfNonOwningReferences.p, fieldName: "vectorOfNonOwningReferences", required: false, type: ForwardOffset<Vector<UInt64, UInt64>>.self)
|
||||
try _v.visit(unionKey: VTOFFSET.anyUniqueType.p, unionField: VTOFFSET.anyUnique.p, unionKeyName: "anyUniqueType", fieldName: "anyUnique", required: false, completion: { (verifier, key: MyGame_Example_AnyUniqueAliases, pos) in
|
||||
switch key {
|
||||
case .none_:
|
||||
break // NOTE - SWIFT doesnt support none
|
||||
case .m:
|
||||
try ForwardOffset<MyGame_Example_Monster>.verify(&verifier, at: pos, of: MyGame_Example_Monster.self)
|
||||
case .ts:
|
||||
try ForwardOffset<MyGame_Example_TestSimpleTableWithEnum>.verify(&verifier, at: pos, of: MyGame_Example_TestSimpleTableWithEnum.self)
|
||||
case .m2:
|
||||
try ForwardOffset<MyGame_Example2_Monster>.verify(&verifier, at: pos, of: MyGame_Example2_Monster.self)
|
||||
}
|
||||
})
|
||||
try _v.visit(unionKey: VTOFFSET.anyAmbiguousType.p, unionField: VTOFFSET.anyAmbiguous.p, unionKeyName: "anyAmbiguousType", fieldName: "anyAmbiguous", required: false, completion: { (verifier, key: MyGame_Example_AnyAmbiguousAliases, pos) in
|
||||
switch key {
|
||||
case .none_:
|
||||
break // NOTE - SWIFT doesnt support none
|
||||
case .m1:
|
||||
try ForwardOffset<MyGame_Example_Monster>.verify(&verifier, at: pos, of: MyGame_Example_Monster.self)
|
||||
case .m2:
|
||||
try ForwardOffset<MyGame_Example_Monster>.verify(&verifier, at: pos, of: MyGame_Example_Monster.self)
|
||||
case .m3:
|
||||
try ForwardOffset<MyGame_Example_Monster>.verify(&verifier, at: pos, of: MyGame_Example_Monster.self)
|
||||
}
|
||||
})
|
||||
try _v.visit(field: VTOFFSET.vectorOfEnums.p, fieldName: "vectorOfEnums", required: false, type: ForwardOffset<Vector<MyGame_Example_Color, MyGame_Example_Color>>.self)
|
||||
try _v.visit(field: VTOFFSET.signedEnum.p, fieldName: "signedEnum", required: false, type: MyGame_Example_Race.self)
|
||||
try _v.visit(field: VTOFFSET.testrequirednestedflatbuffer.p, fieldName: "testrequirednestedflatbuffer", required: false, type: ForwardOffset<Vector<UInt8, UInt8>>.self)
|
||||
try _v.visit(field: VTOFFSET.scalarKeySortedTables.p, fieldName: "scalarKeySortedTables", required: false, type: ForwardOffset<Vector<ForwardOffset<MyGame_Example_Stat>, MyGame_Example_Stat>>.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
public class MyGame_Example_MonsterT: NativeObject {
|
||||
@ -1505,7 +1646,7 @@ public class MyGame_Example_MonsterT: NativeObject {
|
||||
public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Monster.self) }
|
||||
|
||||
}
|
||||
public struct MyGame_Example_TypeAliases: FlatBufferObject, ObjectAPIPacker {
|
||||
public struct MyGame_Example_TypeAliases: FlatBufferObject, Verifiable, ObjectAPIPacker {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -1634,6 +1775,23 @@ public struct MyGame_Example_TypeAliases: FlatBufferObject, ObjectAPIPacker {
|
||||
MyGame_Example_TypeAliases.addVectorOf(vf64: __vf64, &builder)
|
||||
return MyGame_Example_TypeAliases.endTypeAliases(&builder, start: __root)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.i8.p, fieldName: "i8", required: false, type: Int8.self)
|
||||
try _v.visit(field: VTOFFSET.u8.p, fieldName: "u8", required: false, type: UInt8.self)
|
||||
try _v.visit(field: VTOFFSET.i16.p, fieldName: "i16", required: false, type: Int16.self)
|
||||
try _v.visit(field: VTOFFSET.u16.p, fieldName: "u16", required: false, type: UInt16.self)
|
||||
try _v.visit(field: VTOFFSET.i32.p, fieldName: "i32", required: false, type: Int32.self)
|
||||
try _v.visit(field: VTOFFSET.u32.p, fieldName: "u32", required: false, type: UInt32.self)
|
||||
try _v.visit(field: VTOFFSET.i64.p, fieldName: "i64", required: false, type: Int64.self)
|
||||
try _v.visit(field: VTOFFSET.u64.p, fieldName: "u64", required: false, type: UInt64.self)
|
||||
try _v.visit(field: VTOFFSET.f32.p, fieldName: "f32", required: false, type: Float32.self)
|
||||
try _v.visit(field: VTOFFSET.f64.p, fieldName: "f64", required: false, type: Double.self)
|
||||
try _v.visit(field: VTOFFSET.v8.p, fieldName: "v8", required: false, type: ForwardOffset<Vector<Int8, Int8>>.self)
|
||||
try _v.visit(field: VTOFFSET.vf64.p, fieldName: "vf64", required: false, type: ForwardOffset<Vector<Double, Double>>.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
public class MyGame_Example_TypeAliasesT: NativeObject {
|
||||
|
@ -4,20 +4,19 @@
|
||||
|
||||
import FlatBuffers
|
||||
|
||||
public enum ABC: Int32, Enum {
|
||||
public enum ABC: Int32, Enum, Verifiable {
|
||||
public typealias T = Int32
|
||||
public static var byteSize: Int { return MemoryLayout<Int32>.size }
|
||||
public var value: Int32 { return self.rawValue }
|
||||
case a = 0
|
||||
case b = 1
|
||||
case c = 2
|
||||
|
||||
|
||||
public static var max: ABC { return .c }
|
||||
public static var min: ABC { return .a }
|
||||
}
|
||||
|
||||
public struct MoreDefaults: FlatBufferObject, ObjectAPIPacker {
|
||||
public struct MoreDefaults: FlatBufferObject, Verifiable, ObjectAPIPacker {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -118,6 +117,17 @@ public struct MoreDefaults: FlatBufferObject, ObjectAPIPacker {
|
||||
MoreDefaults.addVectorOf(bools: __bools, &builder)
|
||||
return MoreDefaults.endMoreDefaults(&builder, start: __root)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.ints.p, fieldName: "ints", required: false, type: ForwardOffset<Vector<Int32, Int32>>.self)
|
||||
try _v.visit(field: VTOFFSET.floats.p, fieldName: "floats", required: false, type: ForwardOffset<Vector<Float32, Float32>>.self)
|
||||
try _v.visit(field: VTOFFSET.emptyString.p, fieldName: "emptyString", required: false, type: ForwardOffset<String>.self)
|
||||
try _v.visit(field: VTOFFSET.someString.p, fieldName: "someString", required: false, type: ForwardOffset<String>.self)
|
||||
try _v.visit(field: VTOFFSET.abcs.p, fieldName: "abcs", required: false, type: ForwardOffset<Vector<ABC, ABC>>.self)
|
||||
try _v.visit(field: VTOFFSET.bools.p, fieldName: "bools", required: false, type: ForwardOffset<Vector<Bool, Bool>>.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
public class MoreDefaultsT: NativeObject {
|
||||
|
@ -4,20 +4,19 @@
|
||||
|
||||
import FlatBuffers
|
||||
|
||||
public enum optional_scalars_OptionalByte: Int8, Enum {
|
||||
public enum optional_scalars_OptionalByte: Int8, Enum, Verifiable {
|
||||
public typealias T = Int8
|
||||
public static var byteSize: Int { return MemoryLayout<Int8>.size }
|
||||
public var value: Int8 { return self.rawValue }
|
||||
case none_ = 0
|
||||
case one = 1
|
||||
case two = 2
|
||||
|
||||
|
||||
public static var max: optional_scalars_OptionalByte { return .two }
|
||||
public static var min: optional_scalars_OptionalByte { return .none_ }
|
||||
}
|
||||
|
||||
public struct optional_scalars_ScalarStuff: FlatBufferObject {
|
||||
public struct optional_scalars_ScalarStuff: FlatBufferObject, Verifiable {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -224,5 +223,46 @@ public struct optional_scalars_ScalarStuff: FlatBufferObject {
|
||||
optional_scalars_ScalarStuff.add(defaultEnum: defaultEnum, &fbb)
|
||||
return optional_scalars_ScalarStuff.endScalarStuff(&fbb, start: __start)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.justI8.p, fieldName: "justI8", required: false, type: Int8.self)
|
||||
try _v.visit(field: VTOFFSET.maybeI8.p, fieldName: "maybeI8", required: false, type: Int8.self)
|
||||
try _v.visit(field: VTOFFSET.defaultI8.p, fieldName: "defaultI8", required: false, type: Int8.self)
|
||||
try _v.visit(field: VTOFFSET.justU8.p, fieldName: "justU8", required: false, type: UInt8.self)
|
||||
try _v.visit(field: VTOFFSET.maybeU8.p, fieldName: "maybeU8", required: false, type: UInt8.self)
|
||||
try _v.visit(field: VTOFFSET.defaultU8.p, fieldName: "defaultU8", required: false, type: UInt8.self)
|
||||
try _v.visit(field: VTOFFSET.justI16.p, fieldName: "justI16", required: false, type: Int16.self)
|
||||
try _v.visit(field: VTOFFSET.maybeI16.p, fieldName: "maybeI16", required: false, type: Int16.self)
|
||||
try _v.visit(field: VTOFFSET.defaultI16.p, fieldName: "defaultI16", required: false, type: Int16.self)
|
||||
try _v.visit(field: VTOFFSET.justU16.p, fieldName: "justU16", required: false, type: UInt16.self)
|
||||
try _v.visit(field: VTOFFSET.maybeU16.p, fieldName: "maybeU16", required: false, type: UInt16.self)
|
||||
try _v.visit(field: VTOFFSET.defaultU16.p, fieldName: "defaultU16", required: false, type: UInt16.self)
|
||||
try _v.visit(field: VTOFFSET.justI32.p, fieldName: "justI32", required: false, type: Int32.self)
|
||||
try _v.visit(field: VTOFFSET.maybeI32.p, fieldName: "maybeI32", required: false, type: Int32.self)
|
||||
try _v.visit(field: VTOFFSET.defaultI32.p, fieldName: "defaultI32", required: false, type: Int32.self)
|
||||
try _v.visit(field: VTOFFSET.justU32.p, fieldName: "justU32", required: false, type: UInt32.self)
|
||||
try _v.visit(field: VTOFFSET.maybeU32.p, fieldName: "maybeU32", required: false, type: UInt32.self)
|
||||
try _v.visit(field: VTOFFSET.defaultU32.p, fieldName: "defaultU32", required: false, type: UInt32.self)
|
||||
try _v.visit(field: VTOFFSET.justI64.p, fieldName: "justI64", required: false, type: Int64.self)
|
||||
try _v.visit(field: VTOFFSET.maybeI64.p, fieldName: "maybeI64", required: false, type: Int64.self)
|
||||
try _v.visit(field: VTOFFSET.defaultI64.p, fieldName: "defaultI64", required: false, type: Int64.self)
|
||||
try _v.visit(field: VTOFFSET.justU64.p, fieldName: "justU64", required: false, type: UInt64.self)
|
||||
try _v.visit(field: VTOFFSET.maybeU64.p, fieldName: "maybeU64", required: false, type: UInt64.self)
|
||||
try _v.visit(field: VTOFFSET.defaultU64.p, fieldName: "defaultU64", required: false, type: UInt64.self)
|
||||
try _v.visit(field: VTOFFSET.justF32.p, fieldName: "justF32", required: false, type: Float32.self)
|
||||
try _v.visit(field: VTOFFSET.maybeF32.p, fieldName: "maybeF32", required: false, type: Float32.self)
|
||||
try _v.visit(field: VTOFFSET.defaultF32.p, fieldName: "defaultF32", required: false, type: Float32.self)
|
||||
try _v.visit(field: VTOFFSET.justF64.p, fieldName: "justF64", required: false, type: Double.self)
|
||||
try _v.visit(field: VTOFFSET.maybeF64.p, fieldName: "maybeF64", required: false, type: Double.self)
|
||||
try _v.visit(field: VTOFFSET.defaultF64.p, fieldName: "defaultF64", required: false, type: Double.self)
|
||||
try _v.visit(field: VTOFFSET.justBool.p, fieldName: "justBool", required: false, type: Bool.self)
|
||||
try _v.visit(field: VTOFFSET.maybeBool.p, fieldName: "maybeBool", required: false, type: Bool.self)
|
||||
try _v.visit(field: VTOFFSET.defaultBool.p, fieldName: "defaultBool", required: false, type: Bool.self)
|
||||
try _v.visit(field: VTOFFSET.justEnum.p, fieldName: "justEnum", required: false, type: optional_scalars_OptionalByte.self)
|
||||
try _v.visit(field: VTOFFSET.maybeEnum.p, fieldName: "maybeEnum", required: false, type: optional_scalars_OptionalByte.self)
|
||||
try _v.visit(field: VTOFFSET.defaultEnum.p, fieldName: "defaultEnum", required: false, type: optional_scalars_OptionalByte.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,13 @@
|
||||
|
||||
import FlatBuffers
|
||||
|
||||
public enum Character: UInt8, Enum {
|
||||
public enum Character: UInt8, UnionEnum {
|
||||
public typealias T = UInt8
|
||||
|
||||
public init?(value: T) {
|
||||
self.init(rawValue: value)
|
||||
}
|
||||
|
||||
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
|
||||
public var value: UInt8 { return self.rawValue }
|
||||
case none_ = 0
|
||||
@ -15,7 +20,6 @@ public enum Character: UInt8, Enum {
|
||||
case bookfan = 4
|
||||
case other = 5
|
||||
case unused = 6
|
||||
|
||||
|
||||
public static var max: Character { return .unused }
|
||||
public static var min: Character { return .none_ }
|
||||
@ -52,7 +56,7 @@ public struct CharacterUnion {
|
||||
}
|
||||
}
|
||||
}
|
||||
public struct Rapunzel: NativeStruct, NativeObject {
|
||||
public struct Rapunzel: NativeStruct, Verifiable, NativeObject {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
|
||||
@ -71,6 +75,10 @@ public struct Rapunzel: NativeStruct, NativeObject {
|
||||
}
|
||||
|
||||
public var hairLength: Int32 { _hairLength }
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
try verifier.inBuffer(position: position, of: Rapunzel.self)
|
||||
}
|
||||
}
|
||||
|
||||
public struct Rapunzel_Mutable: FlatBufferObject {
|
||||
@ -98,7 +106,7 @@ public struct Rapunzel_Mutable: FlatBufferObject {
|
||||
}
|
||||
}
|
||||
|
||||
public struct BookReader: NativeStruct, NativeObject {
|
||||
public struct BookReader: NativeStruct, Verifiable, NativeObject {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
|
||||
@ -117,6 +125,10 @@ public struct BookReader: NativeStruct, NativeObject {
|
||||
}
|
||||
|
||||
public var booksRead: Int32 { _booksRead }
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
try verifier.inBuffer(position: position, of: BookReader.self)
|
||||
}
|
||||
}
|
||||
|
||||
public struct BookReader_Mutable: FlatBufferObject {
|
||||
@ -144,7 +156,7 @@ public struct BookReader_Mutable: FlatBufferObject {
|
||||
}
|
||||
}
|
||||
|
||||
public struct Attacker: FlatBufferObject, ObjectAPIPacker {
|
||||
public struct Attacker: FlatBufferObject, Verifiable, ObjectAPIPacker {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -190,6 +202,12 @@ public struct Attacker: FlatBufferObject, ObjectAPIPacker {
|
||||
Attacker.add(swordAttackDamage: obj.swordAttackDamage, &builder)
|
||||
return Attacker.endAttacker(&builder, start: __root)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.swordAttackDamage.p, fieldName: "swordAttackDamage", required: false, type: Int32.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
public class AttackerT: NativeObject {
|
||||
@ -207,7 +225,7 @@ public class AttackerT: NativeObject {
|
||||
public func serialize() -> ByteBuffer { return serialize(type: Attacker.self) }
|
||||
|
||||
}
|
||||
public struct Movie: FlatBufferObject, ObjectAPIPacker {
|
||||
public struct Movie: FlatBufferObject, Verifiable, ObjectAPIPacker {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_2_0_0() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
@ -283,6 +301,47 @@ public struct Movie: FlatBufferObject, ObjectAPIPacker {
|
||||
Movie.addVectorOf(characters: __characters, &builder)
|
||||
return Movie.endMovie(&builder, start: __root)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(unionKey: VTOFFSET.mainCharacterType.p, unionField: VTOFFSET.mainCharacter.p, unionKeyName: "mainCharacterType", fieldName: "mainCharacter", required: false, completion: { (verifier, key: Character, pos) in
|
||||
switch key {
|
||||
case .none_:
|
||||
break // NOTE - SWIFT doesnt support none
|
||||
case .mulan:
|
||||
try ForwardOffset<Attacker>.verify(&verifier, at: pos, of: Attacker.self)
|
||||
case .rapunzel:
|
||||
try Rapunzel.verify(&verifier, at: pos, of: Rapunzel.self)
|
||||
case .belle:
|
||||
try BookReader.verify(&verifier, at: pos, of: BookReader.self)
|
||||
case .bookfan:
|
||||
try BookReader.verify(&verifier, at: pos, of: BookReader.self)
|
||||
case .other:
|
||||
try ForwardOffset<String>.verify(&verifier, at: pos, of: String.self)
|
||||
case .unused:
|
||||
try ForwardOffset<String>.verify(&verifier, at: pos, of: String.self)
|
||||
}
|
||||
})
|
||||
try _v.visitUnionVector(unionKey: VTOFFSET.charactersType.p, unionField: VTOFFSET.characters.p, unionKeyName: "charactersType", fieldName: "characters", required: false, completion: { (verifier, key: Character, pos) in
|
||||
switch key {
|
||||
case .none_:
|
||||
break // NOTE - SWIFT doesnt support none
|
||||
case .mulan:
|
||||
try ForwardOffset<Attacker>.verify(&verifier, at: pos, of: Attacker.self)
|
||||
case .rapunzel:
|
||||
try Rapunzel.verify(&verifier, at: pos, of: Rapunzel.self)
|
||||
case .belle:
|
||||
try BookReader.verify(&verifier, at: pos, of: BookReader.self)
|
||||
case .bookfan:
|
||||
try BookReader.verify(&verifier, at: pos, of: BookReader.self)
|
||||
case .other:
|
||||
try ForwardOffset<String>.verify(&verifier, at: pos, of: String.self)
|
||||
case .unused:
|
||||
try ForwardOffset<String>.verify(&verifier, at: pos, of: String.self)
|
||||
}
|
||||
})
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
public class MovieT: NativeObject {
|
||||
|
Loading…
x
Reference in New Issue
Block a user