mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-19 23:25:44 +00:00
[Swift] Adds a format file and reformats the swift project (#6250)
* Formats files & adds licence * Revert arrays * Keeps array indentation as is * Adds licence to code formatter * Updates code generators
This commit is contained in:
@@ -1,22 +1,35 @@
|
||||
// swift-tools-version:5.2
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "FlatBuffers",
|
||||
platforms: [
|
||||
.iOS(.v11),
|
||||
.macOS(.v10_14),
|
||||
],
|
||||
products: [
|
||||
.library(
|
||||
name: "FlatBuffers",
|
||||
targets: ["FlatBuffers"]),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "FlatBuffers",
|
||||
dependencies: []),
|
||||
]
|
||||
)
|
||||
name: "FlatBuffers",
|
||||
platforms: [
|
||||
.iOS(.v11),
|
||||
.macOS(.v10_14),
|
||||
],
|
||||
products: [
|
||||
.library(
|
||||
name: "FlatBuffers",
|
||||
targets: ["FlatBuffers"]),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "FlatBuffers",
|
||||
dependencies: []),
|
||||
])
|
||||
|
||||
@@ -1,345 +1,398 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct ByteBuffer {
|
||||
|
||||
/// Storage is a container that would hold the memory pointer to solve the issue of
|
||||
/// deallocating the memory that was held by (memory: UnsafeMutableRawPointer)
|
||||
@usableFromInline final class Storage {
|
||||
// This storage doesn't own the memory, therefore, we won't deallocate on deinit.
|
||||
private let unowned: Bool
|
||||
/// pointer to the start of the buffer object in memory
|
||||
var memory: UnsafeMutableRawPointer
|
||||
/// Capacity of UInt8 the buffer can hold
|
||||
var capacity: Int
|
||||
|
||||
init(count: Int, alignment: Int) {
|
||||
memory = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: alignment)
|
||||
capacity = count
|
||||
unowned = false
|
||||
}
|
||||
|
||||
init(memory: UnsafeMutableRawPointer, capacity: Int, unowned: Bool) {
|
||||
self.memory = memory
|
||||
self.capacity = capacity
|
||||
self.unowned = unowned
|
||||
}
|
||||
|
||||
deinit {
|
||||
if !unowned {
|
||||
memory.deallocate()
|
||||
}
|
||||
}
|
||||
|
||||
func copy(from ptr: UnsafeRawPointer, count: Int) {
|
||||
assert(!unowned, "copy should NOT be called on a buffer that is built by assumingMemoryBound")
|
||||
memory.copyMemory(from: ptr, byteCount: count)
|
||||
}
|
||||
|
||||
func initialize(for size: Int) {
|
||||
assert(!unowned, "initalize should NOT be called on a buffer that is built by assumingMemoryBound")
|
||||
memset(memory, 0, size)
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
let currentWritingIndex = capacity &- writerSize
|
||||
while capacity <= writerSize &+ size {
|
||||
capacity = capacity << 1
|
||||
}
|
||||
|
||||
/// solution take from Apple-NIO
|
||||
capacity = capacity.convertToPowerofTwo
|
||||
|
||||
let newData = UnsafeMutableRawPointer.allocate(byteCount: capacity, alignment: alignment)
|
||||
memset(newData, 0, capacity &- writerSize)
|
||||
memcpy(newData.advanced(by: capacity &- writerSize), memory.advanced(by: currentWritingIndex), writerSize)
|
||||
memory.deallocate()
|
||||
memory = newData
|
||||
}
|
||||
}
|
||||
|
||||
@usableFromInline var _storage: Storage
|
||||
|
||||
/// 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
|
||||
/// 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 { return _storage.capacity &- _writerSize }
|
||||
/// Storage is a container that would hold the memory pointer to solve the issue of
|
||||
/// deallocating the memory that was held by (memory: UnsafeMutableRawPointer)
|
||||
@usableFromInline
|
||||
final class Storage {
|
||||
// This storage doesn't own the memory, therefore, we won't deallocate on deinit.
|
||||
private let unowned: Bool
|
||||
/// pointer to the start of the buffer object in memory
|
||||
var memory: UnsafeMutableRawPointer
|
||||
/// Capacity of UInt8 the buffer can hold
|
||||
var capacity: Int
|
||||
|
||||
/// Reader is the position of the current Writer Index (capacity - size)
|
||||
public var reader: Int { return writerIndex }
|
||||
/// Current size of the buffer
|
||||
public var size: UOffset { return UOffset(_writerSize) }
|
||||
/// Public Pointer to the buffer object in memory. This should NOT be modified for any reason
|
||||
public var memory: UnsafeMutableRawPointer { return _storage.memory }
|
||||
/// Current capacity for the buffer
|
||||
public var capacity: Int { return _storage.capacity }
|
||||
|
||||
/// Constructor that creates a Flatbuffer object from a UInt8
|
||||
/// - Parameter bytes: Array of UInt8
|
||||
public init(bytes: [UInt8]) {
|
||||
var b = bytes
|
||||
_storage = Storage(count: bytes.count, alignment: alignment)
|
||||
_writerSize = _storage.capacity
|
||||
b.withUnsafeMutableBytes { bufferPointer in
|
||||
self._storage.copy(from: bufferPointer.baseAddress!, count: bytes.count)
|
||||
}
|
||||
init(count: Int, alignment: Int) {
|
||||
memory = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: alignment)
|
||||
capacity = count
|
||||
unowned = false
|
||||
}
|
||||
|
||||
/// Constructor that creates a Flatbuffer from the Swift Data type object
|
||||
/// - Parameter data: Swift data Object
|
||||
public init(data: Data) {
|
||||
var b = data
|
||||
_storage = Storage(count: data.count, alignment: alignment)
|
||||
_writerSize = _storage.capacity
|
||||
b.withUnsafeMutableBytes { bufferPointer in
|
||||
self._storage.copy(from: bufferPointer.baseAddress!, count: data.count)
|
||||
}
|
||||
init(memory: UnsafeMutableRawPointer, capacity: Int, unowned: Bool) {
|
||||
self.memory = memory
|
||||
self.capacity = capacity
|
||||
self.unowned = unowned
|
||||
}
|
||||
|
||||
/// Constructor that creates a Flatbuffer instance with a size
|
||||
/// - Parameter size: Length of the buffer
|
||||
init(initialSize size: Int) {
|
||||
let size = size.convertToPowerofTwo
|
||||
_storage = Storage(count: size, alignment: alignment)
|
||||
_storage.initialize(for: size)
|
||||
}
|
||||
|
||||
#if swift(>=5.0)
|
||||
/// Constructor that creates a Flatbuffer object from a ContiguousBytes
|
||||
/// - Parameters:
|
||||
/// - contiguousBytes: Binary stripe to use as the buffer
|
||||
/// - count: amount of readable bytes
|
||||
public init<Bytes: ContiguousBytes>(
|
||||
contiguousBytes: Bytes,
|
||||
count: Int
|
||||
) {
|
||||
_storage = Storage(count: count, alignment: alignment)
|
||||
_writerSize = _storage.capacity
|
||||
contiguousBytes.withUnsafeBytes { buf in
|
||||
_storage.copy(from: buf.baseAddress!, count: buf.count)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Constructor that creates a Flatbuffer from unsafe memory region without copying
|
||||
/// - Parameter assumingMemoryBound: The unsafe memory region
|
||||
/// - Parameter capacity: The size of the given memory region
|
||||
public init(assumingMemoryBound memory: UnsafeMutableRawPointer, capacity: Int) {
|
||||
_storage = Storage(memory: memory, capacity: capacity, unowned: true)
|
||||
_writerSize = capacity
|
||||
deinit {
|
||||
if !unowned {
|
||||
memory.deallocate()
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a copy of the buffer that's being built by calling sizedBuffer
|
||||
/// - Parameters:
|
||||
/// - memory: Current memory of the buffer
|
||||
/// - count: count of bytes
|
||||
internal init(memory: UnsafeMutableRawPointer, count: Int) {
|
||||
_storage = Storage(count: count, alignment: alignment)
|
||||
_storage.copy(from: memory, count: count)
|
||||
_writerSize = _storage.capacity
|
||||
func copy(from ptr: UnsafeRawPointer, count: Int) {
|
||||
assert(
|
||||
!unowned,
|
||||
"copy should NOT be called on a buffer that is built by assumingMemoryBound")
|
||||
memory.copyMemory(from: ptr, byteCount: count)
|
||||
}
|
||||
|
||||
/// Creates a copy of the existing flatbuffer, by copying it to a different memory.
|
||||
/// - Parameters:
|
||||
/// - 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) {
|
||||
_storage = Storage(count: count, alignment: alignment)
|
||||
_storage.copy(from: memory, count: count)
|
||||
_writerSize = removeBytes
|
||||
func initialize(for size: Int) {
|
||||
assert(
|
||||
!unowned,
|
||||
"initalize should NOT be called on a buffer that is built by assumingMemoryBound")
|
||||
memset(memory, 0, size)
|
||||
}
|
||||
|
||||
/// Fills the buffer with padding by adding to the writersize
|
||||
/// - Parameter padding: Amount of padding between two to be serialized objects
|
||||
@usableFromInline mutating func fill(padding: Int) {
|
||||
assert(padding >= 0, "Fill should be larger than or equal to zero")
|
||||
ensureSpace(size: padding)
|
||||
_writerSize = _writerSize &+ (MemoryLayout<UInt8>.size &* padding)
|
||||
}
|
||||
|
||||
///Adds an array of type Scalar to the buffer memory
|
||||
/// - Parameter elements: An array of Scalars
|
||||
@usableFromInline mutating func push<T: Scalar>(elements: [T]) {
|
||||
let size = elements.count &* MemoryLayout<T>.size
|
||||
ensureSpace(size: size)
|
||||
elements.reversed().forEach { (s) in
|
||||
push(value: s, len: MemoryLayout.size(ofValue: s))
|
||||
}
|
||||
}
|
||||
/// 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) {
|
||||
let currentWritingIndex = capacity &- writerSize
|
||||
while capacity <= writerSize &+ size {
|
||||
capacity = capacity << 1
|
||||
}
|
||||
|
||||
/// A custom type of structs that are padded according to the flatbuffer padding,
|
||||
/// - Parameters:
|
||||
/// - value: Pointer to the object in memory
|
||||
/// - size: Size of Value being written to the buffer
|
||||
@available(*, deprecated, message: "0.9.0 will be removing the following method. Regenerate the code")
|
||||
@usableFromInline mutating func push(struct value: UnsafeMutableRawPointer, size: Int) {
|
||||
ensureSpace(size: size)
|
||||
memcpy(_storage.memory.advanced(by: writerIndex &- size), value, size)
|
||||
defer { value.deallocate() }
|
||||
_writerSize = _writerSize &+ size
|
||||
}
|
||||
|
||||
/// Prepares the buffer to receive a struct of certian size.
|
||||
/// The alignment of the memory is already handled since we already called preAlign
|
||||
/// - Parameter size: size of the struct
|
||||
@usableFromInline mutating func prepareBufferToReceiveStruct(of size: Int) {
|
||||
ensureSpace(size: size)
|
||||
_writerSize = _writerSize &+ size
|
||||
}
|
||||
|
||||
/// Reverse the input direction to the buffer, since `FlatBuffers` uses a back to front, following method will take current `writerIndex`
|
||||
/// and writes front to back into the buffer, respecting the padding & the alignment
|
||||
/// - Parameters:
|
||||
/// - value: value of type Scalar
|
||||
/// - position: position relative to the `writerIndex`
|
||||
/// - len: length of the value in terms of bytes
|
||||
@usableFromInline mutating func reversePush<T: Scalar>(value: T, position: Int, len: Int) {
|
||||
var v = value
|
||||
memcpy(_storage.memory.advanced(by: writerIndex &+ position), &v, len)
|
||||
}
|
||||
/// solution take from Apple-NIO
|
||||
capacity = capacity.convertToPowerofTwo
|
||||
|
||||
/// Adds an object of type Scalar into the buffer
|
||||
/// - Parameters:
|
||||
/// - value: Object that will be written to the buffer
|
||||
/// - len: Offset to subtract from the WriterIndex
|
||||
@usableFromInline mutating func push<T: Scalar>(value: T, len: Int) {
|
||||
ensureSpace(size: len)
|
||||
var v = value
|
||||
memcpy(_storage.memory.advanced(by: writerIndex &- len), &v, len)
|
||||
_writerSize = _writerSize &+ len
|
||||
let newData = UnsafeMutableRawPointer.allocate(byteCount: capacity, alignment: alignment)
|
||||
memset(newData, 0, capacity &- writerSize)
|
||||
memcpy(
|
||||
newData.advanced(by: capacity &- writerSize),
|
||||
memory.advanced(by: currentWritingIndex),
|
||||
writerSize)
|
||||
memory.deallocate()
|
||||
memory = newData
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a string to the buffer using swift.utf8 object
|
||||
/// - Parameter str: String that will be added to the buffer
|
||||
/// - Parameter len: length of the string
|
||||
@usableFromInline mutating func push(string str: String, len: Int) {
|
||||
ensureSpace(size: len)
|
||||
if str.utf8.withContiguousStorageIfAvailable({ self.push(bytes: $0, len: len) }) != nil {
|
||||
} else {
|
||||
let utf8View = str.utf8
|
||||
for c in utf8View.reversed() {
|
||||
push(value: c, len: 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@usableFromInline var _storage: Storage
|
||||
|
||||
/// Writes a string to Bytebuffer using UTF8View
|
||||
/// - Parameters:
|
||||
/// - bytes: Pointer to the view
|
||||
/// - len: Size of string
|
||||
@usableFromInline mutating internal func push(bytes: UnsafeBufferPointer<String.UTF8View.Element>, len: Int) -> Bool {
|
||||
memcpy(_storage.memory.advanced(by: writerIndex &- len), UnsafeRawPointer(bytes.baseAddress!), len)
|
||||
_writerSize = _writerSize &+ len
|
||||
return true
|
||||
}
|
||||
/// 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
|
||||
/// 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 }
|
||||
|
||||
/// Write stores an object into the buffer directly or indirectly.
|
||||
///
|
||||
/// Direct: ignores the capacity of buffer which would mean we are referring to the direct point in memory
|
||||
/// indirect: takes into respect the current capacity of the buffer (capacity - index), writing to the buffer from the end
|
||||
/// - Parameters:
|
||||
/// - value: Value that needs to be written to the buffer
|
||||
/// - index: index to write to
|
||||
/// - direct: Should take into consideration the capacity of the buffer
|
||||
func write<T>(value: T, index: Int, direct: Bool = false) {
|
||||
var index = index
|
||||
if !direct {
|
||||
index = _storage.capacity &- index
|
||||
}
|
||||
assert(index < _storage.capacity, "Write index is out of writing bound")
|
||||
assert(index >= 0, "Writer index should be above zero")
|
||||
_storage.memory.storeBytes(of: value, toByteOffset: index, as: T.self)
|
||||
}
|
||||
/// Reader is the position of the current Writer Index (capacity - size)
|
||||
public var reader: Int { writerIndex }
|
||||
/// Current size of the buffer
|
||||
public var size: UOffset { UOffset(_writerSize) }
|
||||
/// Public Pointer to the buffer object in memory. This should NOT be modified for any reason
|
||||
public var memory: UnsafeMutableRawPointer { _storage.memory }
|
||||
/// Current capacity for the buffer
|
||||
public var capacity: Int { _storage.capacity }
|
||||
|
||||
/// Makes sure that buffer has enouch space for each of the objects that will be written into it
|
||||
/// - Parameter size: size of object
|
||||
@discardableResult
|
||||
@usableFromInline mutating func ensureSpace(size: Int) -> Int {
|
||||
if size &+ _writerSize > _storage.capacity {
|
||||
_storage.reallocate(size, writerSize: _writerSize, alignment: alignment)
|
||||
}
|
||||
assert(size < FlatBufferMaxSize, "Buffer can't grow beyond 2 Gigabytes")
|
||||
return size
|
||||
}
|
||||
|
||||
/// pops the written VTable if it's already written into the buffer
|
||||
/// - Parameter size: size of the `VTable`
|
||||
@usableFromInline mutating internal 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
|
||||
mutating public func clearSize() {
|
||||
_writerSize = 0
|
||||
/// Constructor that creates a Flatbuffer object from a UInt8
|
||||
/// - Parameter bytes: Array of UInt8
|
||||
public init(bytes: [UInt8]) {
|
||||
var b = bytes
|
||||
_storage = Storage(count: bytes.count, alignment: alignment)
|
||||
_writerSize = _storage.capacity
|
||||
b.withUnsafeMutableBytes { bufferPointer in
|
||||
self._storage.copy(from: bufferPointer.baseAddress!, count: bytes.count)
|
||||
}
|
||||
}
|
||||
|
||||
/// Clears the current instance of the buffer, replacing it with new memory
|
||||
mutating public func clear() {
|
||||
_writerSize = 0
|
||||
alignment = 1
|
||||
_storage.initialize(for: _storage.capacity)
|
||||
}
|
||||
|
||||
/// Reads an object from the buffer
|
||||
/// - Parameters:
|
||||
/// - 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)
|
||||
/// Constructor that creates a Flatbuffer from the Swift Data type object
|
||||
/// - Parameter data: Swift data Object
|
||||
public init(data: Data) {
|
||||
var b = data
|
||||
_storage = Storage(count: data.count, alignment: alignment)
|
||||
_writerSize = _storage.capacity
|
||||
b.withUnsafeMutableBytes { bufferPointer in
|
||||
self._storage.copy(from: bufferPointer.baseAddress!, count: data.count)
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads a slice from the memory assuming a type of T
|
||||
/// - Parameters:
|
||||
/// - index: index of the object to be read from the buffer
|
||||
/// - count: count of bytes in memory
|
||||
public func readSlice<T>(index: Int32,
|
||||
count: Int32) -> [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)
|
||||
return Array(array)
|
||||
}
|
||||
/// Constructor that creates a Flatbuffer instance with a size
|
||||
/// - Parameter size: Length of the buffer
|
||||
init(initialSize size: Int) {
|
||||
let size = size.convertToPowerofTwo
|
||||
_storage = Storage(count: size, alignment: alignment)
|
||||
_storage.initialize(for: size)
|
||||
}
|
||||
|
||||
/// Reads a string from the buffer and encodes it to a swift string
|
||||
/// - Parameters:
|
||||
/// - index: index of the string in the buffer
|
||||
/// - count: length of the string
|
||||
/// - type: Encoding of the string
|
||||
public func readString(at index: Int32,
|
||||
count: Int32,
|
||||
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)
|
||||
return String(bytes: Array(bufprt), encoding: type)
|
||||
#if swift(>=5.0)
|
||||
/// Constructor that creates a Flatbuffer object from a ContiguousBytes
|
||||
/// - Parameters:
|
||||
/// - contiguousBytes: Binary stripe to use as the buffer
|
||||
/// - count: amount of readable bytes
|
||||
public init<Bytes: ContiguousBytes>(
|
||||
contiguousBytes: Bytes,
|
||||
count: Int)
|
||||
{
|
||||
_storage = Storage(count: count, alignment: alignment)
|
||||
_writerSize = _storage.capacity
|
||||
contiguousBytes.withUnsafeBytes { buf in
|
||||
_storage.copy(from: buf.baseAddress!, count: buf.count)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Creates a new Flatbuffer object that's duplicated from the current one
|
||||
/// - 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")
|
||||
return ByteBuffer(memory: _storage.memory, count: _storage.capacity, removing: _writerSize &- removeBytes)
|
||||
/// Constructor that creates a Flatbuffer from unsafe memory region without copying
|
||||
/// - Parameter assumingMemoryBound: The unsafe memory region
|
||||
/// - Parameter capacity: The size of the given memory region
|
||||
public init(assumingMemoryBound memory: UnsafeMutableRawPointer, capacity: Int) {
|
||||
_storage = Storage(memory: memory, capacity: capacity, unowned: true)
|
||||
_writerSize = capacity
|
||||
}
|
||||
|
||||
/// Creates a copy of the buffer that's being built by calling sizedBuffer
|
||||
/// - Parameters:
|
||||
/// - memory: Current memory of the buffer
|
||||
/// - count: count of bytes
|
||||
internal init(memory: UnsafeMutableRawPointer, count: Int) {
|
||||
_storage = Storage(count: count, alignment: alignment)
|
||||
_storage.copy(from: memory, count: count)
|
||||
_writerSize = _storage.capacity
|
||||
}
|
||||
|
||||
/// Creates a copy of the existing flatbuffer, by copying it to a different memory.
|
||||
/// - Parameters:
|
||||
/// - 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) {
|
||||
_storage = Storage(count: count, alignment: alignment)
|
||||
_storage.copy(from: memory, count: count)
|
||||
_writerSize = removeBytes
|
||||
}
|
||||
|
||||
/// Fills the buffer with padding by adding to the writersize
|
||||
/// - Parameter padding: Amount of padding between two to be serialized objects
|
||||
@usableFromInline
|
||||
mutating func fill(padding: Int) {
|
||||
assert(padding >= 0, "Fill should be larger than or equal to zero")
|
||||
ensureSpace(size: padding)
|
||||
_writerSize = _writerSize &+ (MemoryLayout<UInt8>.size &* padding)
|
||||
}
|
||||
|
||||
///Adds an array of type Scalar to the buffer memory
|
||||
/// - Parameter elements: An array of Scalars
|
||||
@usableFromInline
|
||||
mutating func push<T: Scalar>(elements: [T]) {
|
||||
let size = elements.count &* MemoryLayout<T>.size
|
||||
ensureSpace(size: size)
|
||||
elements.reversed().forEach { s in
|
||||
push(value: s, len: MemoryLayout.size(ofValue: s))
|
||||
}
|
||||
}
|
||||
|
||||
/// A custom type of structs that are padded according to the flatbuffer padding,
|
||||
/// - Parameters:
|
||||
/// - value: Pointer to the object in memory
|
||||
/// - size: Size of Value being written to the buffer
|
||||
@available(
|
||||
*,
|
||||
deprecated,
|
||||
message: "0.9.0 will be removing the following method. Regenerate the code")
|
||||
@usableFromInline
|
||||
mutating func push(struct value: UnsafeMutableRawPointer, size: Int) {
|
||||
ensureSpace(size: size)
|
||||
memcpy(_storage.memory.advanced(by: writerIndex &- size), value, size)
|
||||
defer { value.deallocate() }
|
||||
_writerSize = _writerSize &+ size
|
||||
}
|
||||
|
||||
/// Prepares the buffer to receive a struct of certian size.
|
||||
/// The alignment of the memory is already handled since we already called preAlign
|
||||
/// - Parameter size: size of the struct
|
||||
@usableFromInline
|
||||
mutating func prepareBufferToReceiveStruct(of size: Int) {
|
||||
ensureSpace(size: size)
|
||||
_writerSize = _writerSize &+ size
|
||||
}
|
||||
|
||||
/// Reverse the input direction to the buffer, since `FlatBuffers` uses a back to front, following method will take current `writerIndex`
|
||||
/// and writes front to back into the buffer, respecting the padding & the alignment
|
||||
/// - Parameters:
|
||||
/// - value: value of type Scalar
|
||||
/// - position: position relative to the `writerIndex`
|
||||
/// - len: length of the value in terms of bytes
|
||||
@usableFromInline
|
||||
mutating func reversePush<T: Scalar>(value: T, position: Int, len: Int) {
|
||||
var v = value
|
||||
memcpy(_storage.memory.advanced(by: writerIndex &+ position), &v, len)
|
||||
}
|
||||
|
||||
/// Adds an object of type Scalar into the buffer
|
||||
/// - Parameters:
|
||||
/// - value: Object that will be written to the buffer
|
||||
/// - len: Offset to subtract from the WriterIndex
|
||||
@usableFromInline
|
||||
mutating func push<T: Scalar>(value: T, len: Int) {
|
||||
ensureSpace(size: len)
|
||||
var v = value
|
||||
memcpy(_storage.memory.advanced(by: writerIndex &- len), &v, len)
|
||||
_writerSize = _writerSize &+ len
|
||||
}
|
||||
|
||||
/// Adds a string to the buffer using swift.utf8 object
|
||||
/// - Parameter str: String that will be added to the buffer
|
||||
/// - Parameter len: length of the string
|
||||
@usableFromInline
|
||||
mutating func push(string str: String, len: Int) {
|
||||
ensureSpace(size: len)
|
||||
if str.utf8.withContiguousStorageIfAvailable({ self.push(bytes: $0, len: len) }) != nil {
|
||||
} else {
|
||||
let utf8View = str.utf8
|
||||
for c in utf8View.reversed() {
|
||||
push(value: c, len: 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes a string to Bytebuffer using UTF8View
|
||||
/// - Parameters:
|
||||
/// - bytes: Pointer to the view
|
||||
/// - len: Size of string
|
||||
@usableFromInline
|
||||
mutating internal func push(
|
||||
bytes: UnsafeBufferPointer<String.UTF8View.Element>,
|
||||
len: Int) -> Bool
|
||||
{
|
||||
memcpy(
|
||||
_storage.memory.advanced(by: writerIndex &- len),
|
||||
UnsafeRawPointer(bytes.baseAddress!),
|
||||
len)
|
||||
_writerSize = _writerSize &+ len
|
||||
return true
|
||||
}
|
||||
|
||||
/// Write stores an object into the buffer directly or indirectly.
|
||||
///
|
||||
/// Direct: ignores the capacity of buffer which would mean we are referring to the direct point in memory
|
||||
/// indirect: takes into respect the current capacity of the buffer (capacity - index), writing to the buffer from the end
|
||||
/// - Parameters:
|
||||
/// - value: Value that needs to be written to the buffer
|
||||
/// - index: index to write to
|
||||
/// - direct: Should take into consideration the capacity of the buffer
|
||||
func write<T>(value: T, index: Int, direct: Bool = false) {
|
||||
var index = index
|
||||
if !direct {
|
||||
index = _storage.capacity &- index
|
||||
}
|
||||
assert(index < _storage.capacity, "Write index is out of writing bound")
|
||||
assert(index >= 0, "Writer index should be above zero")
|
||||
_storage.memory.storeBytes(of: value, toByteOffset: index, as: T.self)
|
||||
}
|
||||
|
||||
/// Makes sure that buffer has enouch space for each of the objects that will be written into it
|
||||
/// - Parameter size: size of object
|
||||
@discardableResult
|
||||
@usableFromInline
|
||||
mutating func ensureSpace(size: Int) -> Int {
|
||||
if size &+ _writerSize > _storage.capacity {
|
||||
_storage.reallocate(size, writerSize: _writerSize, alignment: alignment)
|
||||
}
|
||||
assert(size < FlatBufferMaxSize, "Buffer can't grow beyond 2 Gigabytes")
|
||||
return size
|
||||
}
|
||||
|
||||
/// pops the written VTable if it's already written into the buffer
|
||||
/// - Parameter size: size of the `VTable`
|
||||
@usableFromInline
|
||||
mutating internal 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
|
||||
mutating public func clearSize() {
|
||||
_writerSize = 0
|
||||
}
|
||||
|
||||
/// Clears the current instance of the buffer, replacing it with new memory
|
||||
mutating public func clear() {
|
||||
_writerSize = 0
|
||||
alignment = 1
|
||||
_storage.initialize(for: _storage.capacity)
|
||||
}
|
||||
|
||||
/// Reads an object from the buffer
|
||||
/// - Parameters:
|
||||
/// - 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)
|
||||
}
|
||||
|
||||
/// Reads a slice from the memory assuming a type of T
|
||||
/// - Parameters:
|
||||
/// - index: index of the object to be read from the buffer
|
||||
/// - count: count of bytes in memory
|
||||
public func readSlice<T>(
|
||||
index: Int32,
|
||||
count: Int32) -> [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)
|
||||
return Array(array)
|
||||
}
|
||||
|
||||
/// Reads a string from the buffer and encodes it to a swift string
|
||||
/// - Parameters:
|
||||
/// - index: index of the string in the buffer
|
||||
/// - count: length of the string
|
||||
/// - type: Encoding of the string
|
||||
public func readString(
|
||||
at index: Int32,
|
||||
count: Int32,
|
||||
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)
|
||||
return String(bytes: Array(bufprt), encoding: type)
|
||||
}
|
||||
|
||||
/// Creates a new Flatbuffer object that's duplicated from the current one
|
||||
/// - 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")
|
||||
return ByteBuffer(
|
||||
memory: _storage.memory,
|
||||
count: _storage.capacity,
|
||||
removing: _writerSize &- removeBytes)
|
||||
}
|
||||
}
|
||||
|
||||
extension ByteBuffer: CustomDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
"""
|
||||
buffer located at: \(_storage.memory), with capacity of \(_storage.capacity)
|
||||
{ writerSize: \(_writerSize), readerSize: \(reader), writerIndex: \(writerIndex) }
|
||||
"""
|
||||
}
|
||||
public var debugDescription: String {
|
||||
"""
|
||||
buffer located at: \(_storage.memory), with capacity of \(_storage.capacity)
|
||||
{ writerSize: \(_writerSize), readerSize: \(reader), writerIndex: \(writerIndex) }
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if os(Linux)
|
||||
import CoreFoundation
|
||||
#else
|
||||
@@ -20,77 +36,77 @@ public let FlatBufferMaxSize = UInt32.max << ((MemoryLayout<SOffset>.size * 8 -
|
||||
///
|
||||
/// Scalar is used to confirm 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 }
|
||||
associatedtype NumericValue
|
||||
var convertedEndian: NumericValue { get }
|
||||
}
|
||||
|
||||
extension Scalar where Self: FixedWidthInteger {
|
||||
/// Converts the value from BigEndian to LittleEndian
|
||||
///
|
||||
/// Converts values to little endian on machines that work with BigEndian, however this is NOT TESTED yet.
|
||||
public var convertedEndian: NumericValue {
|
||||
return self as! Self.NumericValue
|
||||
}
|
||||
/// Converts the value from BigEndian to LittleEndian
|
||||
///
|
||||
/// Converts values to little endian on machines that work with BigEndian, however this is NOT TESTED yet.
|
||||
public var convertedEndian: NumericValue {
|
||||
self as! Self.NumericValue
|
||||
}
|
||||
}
|
||||
|
||||
extension Double: Scalar {
|
||||
public typealias NumericValue = UInt64
|
||||
|
||||
public var convertedEndian: UInt64 {
|
||||
return self.bitPattern.littleEndian
|
||||
}
|
||||
public typealias NumericValue = UInt64
|
||||
|
||||
public var convertedEndian: UInt64 {
|
||||
bitPattern.littleEndian
|
||||
}
|
||||
}
|
||||
|
||||
extension Float32: Scalar {
|
||||
public typealias NumericValue = UInt32
|
||||
|
||||
public var convertedEndian: UInt32 {
|
||||
return self.bitPattern.littleEndian
|
||||
}
|
||||
public typealias NumericValue = UInt32
|
||||
|
||||
public var convertedEndian: UInt32 {
|
||||
bitPattern.littleEndian
|
||||
}
|
||||
}
|
||||
|
||||
extension Bool: Scalar {
|
||||
public var convertedEndian: UInt8 {
|
||||
return self == true ? 1 : 0
|
||||
}
|
||||
|
||||
public typealias NumericValue = UInt8
|
||||
public var convertedEndian: UInt8 {
|
||||
self == true ? 1 : 0
|
||||
}
|
||||
|
||||
public typealias NumericValue = UInt8
|
||||
}
|
||||
|
||||
extension Int: Scalar {
|
||||
public typealias NumericValue = Int
|
||||
public typealias NumericValue = Int
|
||||
}
|
||||
|
||||
extension Int8: Scalar {
|
||||
public typealias NumericValue = Int8
|
||||
public typealias NumericValue = Int8
|
||||
}
|
||||
|
||||
extension Int16: Scalar {
|
||||
public typealias NumericValue = Int16
|
||||
public typealias NumericValue = Int16
|
||||
}
|
||||
|
||||
extension Int32: Scalar {
|
||||
public typealias NumericValue = Int32
|
||||
public typealias NumericValue = Int32
|
||||
}
|
||||
|
||||
extension Int64: Scalar {
|
||||
public typealias NumericValue = Int64
|
||||
public typealias NumericValue = Int64
|
||||
}
|
||||
|
||||
extension UInt8: Scalar {
|
||||
public typealias NumericValue = UInt8
|
||||
public typealias NumericValue = UInt8
|
||||
}
|
||||
|
||||
extension UInt16: Scalar {
|
||||
public typealias NumericValue = UInt16
|
||||
public typealias NumericValue = UInt16
|
||||
}
|
||||
|
||||
extension UInt32: Scalar {
|
||||
public typealias NumericValue = UInt32
|
||||
public typealias NumericValue = UInt32
|
||||
}
|
||||
|
||||
extension UInt64: Scalar {
|
||||
public typealias NumericValue = UInt64
|
||||
public typealias NumericValue = UInt64
|
||||
}
|
||||
|
||||
public func FlatBuffersVersion_1_12_0() {}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,31 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
/// FlatbufferObject structures all the Flatbuffers objects
|
||||
public protocol FlatBufferObject {
|
||||
var __buffer: ByteBuffer! { get }
|
||||
init(_ bb: ByteBuffer, o: Int32)
|
||||
var __buffer: ByteBuffer! { get }
|
||||
init(_ bb: ByteBuffer, o: Int32)
|
||||
}
|
||||
|
||||
public protocol ObjectAPI {
|
||||
associatedtype T
|
||||
static func pack(_ builder: inout FlatBufferBuilder, obj: inout T) -> Offset<UOffset>
|
||||
mutating func unpack() -> T
|
||||
associatedtype T
|
||||
static func pack(_ builder: inout FlatBufferBuilder, obj: inout T) -> Offset<UOffset>
|
||||
mutating func unpack() -> T
|
||||
}
|
||||
|
||||
/// Readable is structures all the Flatbuffers structs
|
||||
@@ -17,12 +33,12 @@ public protocol ObjectAPI {
|
||||
/// Readable is a procotol that each Flatbuffer struct should confirm to since
|
||||
/// FlatBufferBuilder would require a Type to both create(struct:) and createVector(structs:) functions
|
||||
public protocol Readable: FlatBufferObject {
|
||||
static var size: Int { get }
|
||||
static var alignment: Int { get }
|
||||
static var size: Int { get }
|
||||
static var alignment: Int { get }
|
||||
}
|
||||
|
||||
public protocol Enum {
|
||||
associatedtype T: Scalar
|
||||
static var byteSize: Int { get }
|
||||
var value: T { get }
|
||||
associatedtype T: Scalar
|
||||
static var byteSize: Int { get }
|
||||
var value: T { get }
|
||||
}
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
public final class FlatBuffersUtils {
|
||||
|
||||
/// Gets the size of the prefix
|
||||
/// - Parameter bb: Flatbuffer object
|
||||
public static func getSizePrefix(bb: ByteBuffer) -> Int32 {
|
||||
return bb.read(def: Int32.self, position: bb.reader)
|
||||
}
|
||||
|
||||
/// Removes the prefix by duplicating the Flatbuffer
|
||||
/// - Parameter bb: Flatbuffer object
|
||||
public static func removeSizePrefix(bb: ByteBuffer) -> ByteBuffer {
|
||||
return bb.duplicate(removing: MemoryLayout<Int32>.size)
|
||||
}
|
||||
|
||||
/// Gets the size of the prefix
|
||||
/// - Parameter bb: Flatbuffer object
|
||||
public static func getSizePrefix(bb: ByteBuffer) -> Int32 {
|
||||
bb.read(def: Int32.self, position: bb.reader)
|
||||
}
|
||||
|
||||
/// Removes the prefix by duplicating the Flatbuffer
|
||||
/// - Parameter bb: Flatbuffer object
|
||||
public static func removeSizePrefix(bb: ByteBuffer) -> ByteBuffer {
|
||||
bb.duplicate(removing: MemoryLayout<Int32>.size)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,47 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Int {
|
||||
|
||||
/// Moves the current int into the nearest power of two
|
||||
///
|
||||
/// This is used since the UnsafeMutableRawPointer will face issues when writing/reading
|
||||
/// if the buffer alignment exceeds that actual size of the buffer
|
||||
var convertToPowerofTwo: Int {
|
||||
guard self > 0 else { return 1 }
|
||||
var n = UOffset(self)
|
||||
|
||||
#if arch(arm) || arch(i386)
|
||||
let max = UInt32(Int.max)
|
||||
#else
|
||||
let max = UInt32.max
|
||||
#endif
|
||||
|
||||
n -= 1
|
||||
n |= n >> 1
|
||||
n |= n >> 2
|
||||
n |= n >> 4
|
||||
n |= n >> 8
|
||||
n |= n >> 16
|
||||
if n != max {
|
||||
n += 1
|
||||
}
|
||||
|
||||
return Int(n)
|
||||
/// Moves the current int into the nearest power of two
|
||||
///
|
||||
/// This is used since the UnsafeMutableRawPointer will face issues when writing/reading
|
||||
/// if the buffer alignment exceeds that actual size of the buffer
|
||||
var convertToPowerofTwo: Int {
|
||||
guard self > 0 else { return 1 }
|
||||
var n = UOffset(self)
|
||||
|
||||
#if arch(arm) || arch(i386)
|
||||
let max = UInt32(Int.max)
|
||||
#else
|
||||
let max = UInt32.max
|
||||
#endif
|
||||
|
||||
n -= 1
|
||||
n |= n >> 1
|
||||
n |= n >> 2
|
||||
n |= n >> 4
|
||||
n |= n >> 8
|
||||
n |= n >> 16
|
||||
if n != max {
|
||||
n += 1
|
||||
}
|
||||
|
||||
return Int(n)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +1,59 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
public protocol FlatBufferGRPCMessage {
|
||||
|
||||
/// Raw pointer which would be pointing to the beginning of the readable bytes
|
||||
var rawPointer: UnsafeMutableRawPointer { get }
|
||||
|
||||
/// Size of readable bytes in the buffer
|
||||
var size: Int { get }
|
||||
|
||||
init(byteBuffer: ByteBuffer)
|
||||
|
||||
/// Raw pointer which would be pointing to the beginning of the readable bytes
|
||||
var rawPointer: UnsafeMutableRawPointer { get }
|
||||
|
||||
/// Size of readable bytes in the buffer
|
||||
var size: Int { get }
|
||||
|
||||
init(byteBuffer: ByteBuffer)
|
||||
}
|
||||
|
||||
/// Message is a wrapper around Buffers to to able to send Flatbuffers `Buffers` through the
|
||||
/// GRPC library
|
||||
public final class Message<T: FlatBufferObject>: FlatBufferGRPCMessage {
|
||||
internal var buffer: ByteBuffer
|
||||
|
||||
/// Returns the an object of type T that would be read from the buffer
|
||||
public var object: T {
|
||||
T.init(buffer, o: Int32(buffer.read(def: UOffset.self, position: buffer.reader)) + Int32(buffer.reader))
|
||||
}
|
||||
|
||||
public var rawPointer: UnsafeMutableRawPointer { return buffer.memory.advanced(by: buffer.reader) }
|
||||
|
||||
public var size: Int { return Int(buffer.size) }
|
||||
|
||||
/// Initializes the message with the type Flatbuffer.Bytebuffer that is transmitted over
|
||||
/// GRPC
|
||||
/// - Parameter byteBuffer: Flatbuffer ByteBuffer object
|
||||
public init(byteBuffer: ByteBuffer) {
|
||||
buffer = byteBuffer
|
||||
}
|
||||
|
||||
/// Initializes the message by copying the buffer to the message to be sent.
|
||||
/// from the builder
|
||||
/// - Parameter builder: FlatbufferBuilder that has the bytes created in
|
||||
/// - Note: Use `builder.finish(offset)` before passing the builder without prefixing anything to it
|
||||
public init(builder: inout FlatBufferBuilder) {
|
||||
buffer = builder.sizedBuffer
|
||||
builder.clear()
|
||||
}
|
||||
internal var buffer: ByteBuffer
|
||||
|
||||
/// Returns the an object of type T that would be read from the buffer
|
||||
public var object: T {
|
||||
T.init(
|
||||
buffer,
|
||||
o: Int32(buffer.read(def: UOffset.self, position: buffer.reader)) + Int32(buffer.reader))
|
||||
}
|
||||
|
||||
public var rawPointer: UnsafeMutableRawPointer { buffer.memory.advanced(by: buffer.reader) }
|
||||
|
||||
public var size: Int { Int(buffer.size) }
|
||||
|
||||
/// Initializes the message with the type Flatbuffer.Bytebuffer that is transmitted over
|
||||
/// GRPC
|
||||
/// - Parameter byteBuffer: Flatbuffer ByteBuffer object
|
||||
public init(byteBuffer: ByteBuffer) {
|
||||
buffer = byteBuffer
|
||||
}
|
||||
|
||||
/// Initializes the message by copying the buffer to the message to be sent.
|
||||
/// from the builder
|
||||
/// - Parameter builder: FlatbufferBuilder that has the bytes created in
|
||||
/// - Note: Use `builder.finish(offset)` before passing the builder without prefixing anything to it
|
||||
public init(builder: inout FlatBufferBuilder) {
|
||||
buffer = builder.sizedBuffer
|
||||
builder.clear()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +1,83 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Mutable is a protocol that allows us to mutate Scalar values within the buffer
|
||||
public protocol Mutable {
|
||||
/// makes Flatbuffer accessed within the Protocol
|
||||
var bb: ByteBuffer { get }
|
||||
/// makes position of the table/struct accessed within the Protocol
|
||||
var postion: Int32 { get }
|
||||
/// makes Flatbuffer accessed within the Protocol
|
||||
var bb: ByteBuffer { get }
|
||||
/// makes position of the table/struct accessed within the Protocol
|
||||
var postion: Int32 { get }
|
||||
}
|
||||
|
||||
extension Mutable {
|
||||
|
||||
/// Mutates the memory in the buffer, this is only called from the access function of table and structs
|
||||
/// - Parameters:
|
||||
/// - value: New value to be inserted to the buffer
|
||||
/// - index: index of the Element
|
||||
func mutate<T: Scalar>(value: T, o: Int32) -> Bool {
|
||||
guard o != 0 else { return false }
|
||||
bb.write(value: value, index: Int(o), direct: true)
|
||||
return true
|
||||
}
|
||||
|
||||
/// Mutates the memory in the buffer, this is only called from the access function of table and structs
|
||||
/// - Parameters:
|
||||
/// - value: New value to be inserted to the buffer
|
||||
/// - index: index of the Element
|
||||
func mutate<T: Scalar>(value: T, o: Int32) -> Bool {
|
||||
guard o != 0 else { return false }
|
||||
bb.write(value: value, index: Int(o), direct: true)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Mutable where Self == Table {
|
||||
|
||||
/// Mutates a value by calling mutate with respect to the position in the table
|
||||
/// - Parameters:
|
||||
/// - value: New value to be inserted to the buffer
|
||||
/// - index: index of the Element
|
||||
public func mutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
|
||||
guard index != 0 else { return false }
|
||||
return mutate(value: value, o: index + postion)
|
||||
}
|
||||
|
||||
/// Directly mutates the element by calling mutate
|
||||
///
|
||||
/// Mutates the Element at index ignoring the current position by calling mutate
|
||||
/// - Parameters:
|
||||
/// - value: New value to be inserted to the buffer
|
||||
/// - index: index of the Element
|
||||
public func directMutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
|
||||
return mutate(value: value, o: index)
|
||||
}
|
||||
|
||||
/// Mutates a value by calling mutate with respect to the position in the table
|
||||
/// - Parameters:
|
||||
/// - value: New value to be inserted to the buffer
|
||||
/// - index: index of the Element
|
||||
public func mutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
|
||||
guard index != 0 else { return false }
|
||||
return mutate(value: value, o: index + postion)
|
||||
}
|
||||
|
||||
/// Directly mutates the element by calling mutate
|
||||
///
|
||||
/// Mutates the Element at index ignoring the current position by calling mutate
|
||||
/// - Parameters:
|
||||
/// - value: New value to be inserted to the buffer
|
||||
/// - index: index of the Element
|
||||
public func directMutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
|
||||
mutate(value: value, o: index)
|
||||
}
|
||||
}
|
||||
|
||||
extension Mutable where Self == Struct {
|
||||
|
||||
/// Mutates a value by calling mutate with respect to the position in the struct
|
||||
/// - Parameters:
|
||||
/// - value: New value to be inserted to the buffer
|
||||
/// - index: index of the Element
|
||||
public func mutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
|
||||
return mutate(value: value, o: index + postion)
|
||||
}
|
||||
|
||||
/// Directly mutates the element by calling mutate
|
||||
///
|
||||
/// Mutates the Element at index ignoring the current position by calling mutate
|
||||
/// - Parameters:
|
||||
/// - value: New value to be inserted to the buffer
|
||||
/// - index: index of the Element
|
||||
public func directMutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
|
||||
return mutate(value: value, o: index)
|
||||
}
|
||||
|
||||
/// Mutates a value by calling mutate with respect to the position in the struct
|
||||
/// - Parameters:
|
||||
/// - value: New value to be inserted to the buffer
|
||||
/// - index: index of the Element
|
||||
public func mutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
|
||||
mutate(value: value, o: index + postion)
|
||||
}
|
||||
|
||||
/// Directly mutates the element by calling mutate
|
||||
///
|
||||
/// Mutates the Element at index ignoring the current position by calling mutate
|
||||
/// - Parameters:
|
||||
/// - value: New value to be inserted to the buffer
|
||||
/// - index: index of the Element
|
||||
public func directMutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
|
||||
mutate(value: value, o: index)
|
||||
}
|
||||
}
|
||||
|
||||
extension Struct: Mutable {}
|
||||
|
||||
@@ -1,29 +1,45 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol NativeTable {}
|
||||
|
||||
extension NativeTable {
|
||||
|
||||
/// Serialize is a helper function that serailizes the data from the Object API to a bytebuffer directly th
|
||||
/// - Parameter type: Type of the Flatbuffer object
|
||||
/// - Returns: returns the encoded sized ByteBuffer
|
||||
public func serialize<T: ObjectAPI>(type: T.Type) -> ByteBuffer where T.T == Self {
|
||||
var builder = FlatBufferBuilder(initialSize: 1024)
|
||||
return serialize(builder: &builder, type: type.self)
|
||||
}
|
||||
|
||||
/// Serialize is a helper function that serailizes the data from the Object API to a bytebuffer directly.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - builder: A FlatBufferBuilder
|
||||
/// - type: Type of the Flatbuffer object
|
||||
/// - Returns: returns the encoded sized ByteBuffer
|
||||
/// - Note: The `serialize(builder:type)` can be considered as a function that allows you to create smaller builder instead of the default `1024`.
|
||||
/// It can be considered less expensive in terms of memory allocation
|
||||
public func serialize<T: ObjectAPI>(builder: inout FlatBufferBuilder, type: T.Type) -> ByteBuffer where T.T == Self {
|
||||
var s = self
|
||||
let root = type.pack(&builder, obj: &s)
|
||||
builder.finish(offset: root)
|
||||
return builder.sizedBuffer
|
||||
}
|
||||
|
||||
/// Serialize is a helper function that serailizes the data from the Object API to a bytebuffer directly th
|
||||
/// - Parameter type: Type of the Flatbuffer object
|
||||
/// - Returns: returns the encoded sized ByteBuffer
|
||||
public func serialize<T: ObjectAPI>(type: T.Type) -> ByteBuffer where T.T == Self {
|
||||
var builder = FlatBufferBuilder(initialSize: 1024)
|
||||
return serialize(builder: &builder, type: type.self)
|
||||
}
|
||||
|
||||
/// Serialize is a helper function that serailizes the data from the Object API to a bytebuffer directly.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - builder: A FlatBufferBuilder
|
||||
/// - type: Type of the Flatbuffer object
|
||||
/// - Returns: returns the encoded sized ByteBuffer
|
||||
/// - Note: The `serialize(builder:type)` can be considered as a function that allows you to create smaller builder instead of the default `1024`.
|
||||
/// It can be considered less expensive in terms of memory allocation
|
||||
public func serialize<T: ObjectAPI>(builder: inout FlatBufferBuilder, type: T.Type) -> ByteBuffer where T.T == Self {
|
||||
var s = self
|
||||
let root = type.pack(&builder, obj: &s)
|
||||
builder.finish(offset: root)
|
||||
return builder.sizedBuffer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,28 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Offset object for all the Objects that are written into the buffer
|
||||
public struct Offset<T> {
|
||||
/// Offset of the object in the buffer
|
||||
public var o: UOffset
|
||||
/// Returns false if the offset is equal to zero
|
||||
public var isEmpty: Bool { return o == 0 }
|
||||
|
||||
public init(offset: UOffset) { o = offset }
|
||||
public init() { o = 0 }
|
||||
/// Offset of the object in the buffer
|
||||
public var o: UOffset
|
||||
/// Returns false if the offset is equal to zero
|
||||
public var isEmpty: Bool { o == 0 }
|
||||
|
||||
public init(offset: UOffset) { o = offset }
|
||||
public init() { o = 0 }
|
||||
}
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct Struct {
|
||||
public private(set) var bb: ByteBuffer
|
||||
public private(set) var postion: Int32
|
||||
|
||||
public init(bb: ByteBuffer, position: Int32 = 0) {
|
||||
self.bb = bb
|
||||
self.postion = position
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
public private(set) var bb: ByteBuffer
|
||||
public private(set) var postion: Int32
|
||||
|
||||
public init(bb: ByteBuffer, position: Int32 = 0) {
|
||||
self.bb = bb
|
||||
postion = position
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,144 +1,166 @@
|
||||
/*
|
||||
* Copyright 2020 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct Table {
|
||||
public private(set) var bb: ByteBuffer
|
||||
public private(set) var postion: Int32
|
||||
|
||||
public init(bb: ByteBuffer, position: Int32 = 0) {
|
||||
guard isLitteEndian else {
|
||||
fatalError("Reading/Writing a buffer in big endian machine is not supported on swift")
|
||||
}
|
||||
self.bb = bb
|
||||
self.postion = position
|
||||
}
|
||||
|
||||
public func offset(_ o: Int32) -> Int32 {
|
||||
let vtable = postion - bb.read(def: Int32.self, position: Int(postion))
|
||||
return o < bb.read(def: VOffset.self, position: Int(vtable)) ? Int32(bb.read(def: Int16.self, position: Int(vtable + o))) : 0
|
||||
}
|
||||
|
||||
public func indirect(_ o: Int32) -> Int32 { return o + bb.read(def: Int32.self, position: Int(o)) }
|
||||
public private(set) var bb: ByteBuffer
|
||||
public private(set) var postion: Int32
|
||||
|
||||
/// String reads from the buffer with respect to position of the current table.
|
||||
/// - Parameter offset: Offset of the string
|
||||
public func string(at offset: Int32) -> String? {
|
||||
return directString(at: offset + postion)
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// - 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)
|
||||
}
|
||||
|
||||
/// Reads from the buffer with respect to the position in the table.
|
||||
/// - Parameters:
|
||||
/// - type: Type of Scalar that needs to be read from the buffer
|
||||
/// - o: Offset of the Element
|
||||
public func readBuffer<T: Scalar>(of type: T.Type, at o: Int32) -> T {
|
||||
return directRead(of: T.self, offset: o + postion)
|
||||
}
|
||||
|
||||
/// Reads from the buffer disregarding the position of the table.
|
||||
/// It would be used when reading from an
|
||||
/// ```
|
||||
/// let offset = __t.offset(10)
|
||||
/// //Only used when the we already know what is the
|
||||
/// // position in the table since __t.vector(at:)
|
||||
/// // returns the index with respect to the position
|
||||
/// __t.directRead(of: Byte.self,
|
||||
/// offset: __t.vector(at: offset) + index * 1)
|
||||
/// ```
|
||||
/// - Parameters:
|
||||
/// - type: Type of Scalar that needs to be read from the buffer
|
||||
/// - o: Offset of the Element
|
||||
public func directRead<T: Scalar>(of type: T.Type, offset o: Int32) -> T {
|
||||
let r = bb.read(def: T.self, position: Int(o))
|
||||
return r
|
||||
}
|
||||
|
||||
public func union<T: FlatBufferObject>(_ o: Int32) -> T {
|
||||
let o = o + postion
|
||||
return directUnion(o)
|
||||
public init(bb: ByteBuffer, position: Int32 = 0) {
|
||||
guard isLitteEndian else {
|
||||
fatalError("Reading/Writing a buffer in big endian machine is not supported on swift")
|
||||
}
|
||||
self.bb = bb
|
||||
postion = position
|
||||
}
|
||||
|
||||
public func directUnion<T: FlatBufferObject>(_ o: Int32) -> T {
|
||||
return T.init(bb, o: o + bb.read(def: Int32.self, position: Int(o)))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
/// Vector count gets the count of Elements within the array
|
||||
/// - Parameter o: start offset of the vector
|
||||
/// - returns: Count of elements
|
||||
public func vector(count o: Int32) -> Int32 {
|
||||
var o = o
|
||||
o += postion
|
||||
o += bb.read(def: Int32.self, position: Int(o))
|
||||
return bb.read(def: Int32.self, position: Int(o))
|
||||
}
|
||||
|
||||
/// Vector start index in the buffer
|
||||
/// - Parameter o:start offset of the vector
|
||||
/// - returns: the start index of the vector
|
||||
public func vector(at o: Int32) -> Int32 {
|
||||
var o = o
|
||||
o += postion
|
||||
return o + bb.read(def: Int32.self, position: Int(o)) + 4
|
||||
}
|
||||
public func offset(_ o: Int32) -> Int32 {
|
||||
let vtable = postion - bb.read(def: Int32.self, position: Int(postion))
|
||||
return o < bb.read(def: VOffset.self, position: Int(vtable)) ? Int32(bb.read(
|
||||
def: Int16.self,
|
||||
position: Int(vtable + o))) : 0
|
||||
}
|
||||
|
||||
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
|
||||
public func string(at offset: Int32) -> String? {
|
||||
directString(at: offset + postion)
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// - 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)
|
||||
}
|
||||
|
||||
/// Reads from the buffer with respect to the position in the table.
|
||||
/// - Parameters:
|
||||
/// - type: Type of Scalar that needs to be read from the buffer
|
||||
/// - o: Offset of the Element
|
||||
public func readBuffer<T: Scalar>(of type: T.Type, at o: Int32) -> T {
|
||||
directRead(of: T.self, offset: o + postion)
|
||||
}
|
||||
|
||||
/// Reads from the buffer disregarding the position of the table.
|
||||
/// It would be used when reading from an
|
||||
/// ```
|
||||
/// let offset = __t.offset(10)
|
||||
/// //Only used when the we already know what is the
|
||||
/// // position in the table since __t.vector(at:)
|
||||
/// // returns the index with respect to the position
|
||||
/// __t.directRead(of: Byte.self,
|
||||
/// offset: __t.vector(at: offset) + index * 1)
|
||||
/// ```
|
||||
/// - Parameters:
|
||||
/// - type: Type of Scalar that needs to be read from the buffer
|
||||
/// - o: Offset of the Element
|
||||
public func directRead<T: Scalar>(of type: T.Type, offset o: Int32) -> T {
|
||||
let r = bb.read(def: T.self, position: Int(o))
|
||||
return r
|
||||
}
|
||||
|
||||
public func union<T: FlatBufferObject>(_ o: Int32) -> T {
|
||||
let o = o + postion
|
||||
return directUnion(o)
|
||||
}
|
||||
|
||||
public func directUnion<T: FlatBufferObject>(_ o: Int32) -> T {
|
||||
T.init(bb, o: o + bb.read(def: Int32.self, position: Int(o)))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
/// Vector count gets the count of Elements within the array
|
||||
/// - Parameter o: start offset of the vector
|
||||
/// - returns: Count of elements
|
||||
public func vector(count o: Int32) -> Int32 {
|
||||
var o = o
|
||||
o += postion
|
||||
o += bb.read(def: Int32.self, position: Int(o))
|
||||
return bb.read(def: Int32.self, position: Int(o))
|
||||
}
|
||||
|
||||
/// Vector start index in the buffer
|
||||
/// - Parameter o:start offset of the vector
|
||||
/// - returns: the start index of the vector
|
||||
public func vector(at o: Int32) -> Int32 {
|
||||
var o = o
|
||||
o += postion
|
||||
return o + bb.read(def: Int32.self, position: Int(o)) + 4
|
||||
}
|
||||
}
|
||||
|
||||
extension Table {
|
||||
|
||||
static public func indirect(_ o: Int32, _ fbb: ByteBuffer) -> Int32 { return o + fbb.read(def: Int32.self, position: Int(o)) }
|
||||
|
||||
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)))))
|
||||
|
||||
static public func indirect(_ o: Int32, _ fbb: ByteBuffer) -> Int32 { o + fbb.read(
|
||||
def: Int32.self,
|
||||
position: Int(o)) }
|
||||
|
||||
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)))))
|
||||
}
|
||||
|
||||
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))
|
||||
let _off2 = off2 + fbb.read(def: Int32.self, position: Int(off2))
|
||||
let len1 = fbb.read(def: Int32.self, position: Int(_off1))
|
||||
let len2 = fbb.read(def: Int32.self, position: Int(_off2))
|
||||
let startPos1 = _off1 + memorySize
|
||||
let startPos2 = _off2 + memorySize
|
||||
let minValue = min(len1, len2)
|
||||
for i in 0...minValue {
|
||||
let b1 = fbb.read(def: Int8.self, position: Int(i + startPos1))
|
||||
let b2 = fbb.read(def: Int8.self, position: Int(i + startPos2))
|
||||
if b1 != b2 {
|
||||
return Int32(b2 - b1)
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
let _off2 = off2 + fbb.read(def: Int32.self, position: Int(off2))
|
||||
let len1 = fbb.read(def: Int32.self, position: Int(_off1))
|
||||
let len2 = fbb.read(def: Int32.self, position: Int(_off2))
|
||||
let startPos1 = _off1 + memorySize
|
||||
let startPos2 = _off2 + memorySize
|
||||
let minValue = min(len1, len2)
|
||||
for i in 0...minValue {
|
||||
let b1 = fbb.read(def: Int8.self, position: Int(i + startPos1))
|
||||
let b2 = fbb.read(def: Int8.self, position: Int(i + startPos2))
|
||||
if b1 != b2 {
|
||||
return Int32(b2 - b1)
|
||||
}
|
||||
}
|
||||
return len1 - len2
|
||||
}
|
||||
|
||||
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))
|
||||
let len1 = fbb.read(def: Int32.self, position: Int(_off1))
|
||||
let len2 = Int32(key.count)
|
||||
let startPos1 = _off1 + memorySize
|
||||
let minValue = min(len1, len2)
|
||||
for i in 0..<minValue {
|
||||
let b = fbb.read(def: Int8.self, position: Int(i + startPos1))
|
||||
let byte = key[Int(i)]
|
||||
if b != byte {
|
||||
return Int32(b - Int8(byte))
|
||||
}
|
||||
}
|
||||
return len1 - len2
|
||||
return len1 - len2
|
||||
}
|
||||
|
||||
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))
|
||||
let len1 = fbb.read(def: Int32.self, position: Int(_off1))
|
||||
let len2 = Int32(key.count)
|
||||
let startPos1 = _off1 + memorySize
|
||||
let minValue = min(len1, len2)
|
||||
for i in 0..<minValue {
|
||||
let b = fbb.read(def: Int8.self, position: Int(i + startPos1))
|
||||
let byte = key[Int(i)]
|
||||
if b != byte {
|
||||
return Int32(b - Int8(byte))
|
||||
}
|
||||
}
|
||||
return len1 - len2
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user