mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-30 05:30:00 +00:00
[Swift] Flexbuffers native swift port (#8577)
* Offical Swift port for FlexBuffers This is the offical port for FlexBuffers within swift, and it introcudes a Common Module where code is shared between flatbuffers and flexbuffers. Writing most supported values like maps, vectors, nil and scalars into a flexbuffer buffer. And includes tests to verify that its similar to cpp * Reading a flexbuffer Implementing reading from a flexbuffer, enabling most of the buffers features, like most types, maps, vectors, typedvectors, and fixedtypedvectors. Currently, if an offset/object cant be read we default to a swift nil instead of the default flexbuffers 'null' with all values. * Fixes bazel breaking due to new project structure Address warnings within the library * Adds comment on why we added the code & properly enforce the amout of bytes needed
This commit is contained in:
53
swift/Sources/FlexBuffers/Reader/FixedTypedVector.swift
Normal file
53
swift/Sources/FlexBuffers/Reader/FixedTypedVector.swift
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2024 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 FixedTypedVector: FlexBufferVector {
|
||||
public let byteBuffer: ByteBuffer
|
||||
public let offset: Int
|
||||
public let type: FlexBufferType
|
||||
public let count: Int
|
||||
public var isEmpty: Bool { count == 0 }
|
||||
|
||||
let byteWidth: UInt8
|
||||
|
||||
@inline(__always)
|
||||
init(
|
||||
byteBuffer: ByteBuffer,
|
||||
offset: Int,
|
||||
byteWidth: UInt8,
|
||||
type: FlexBufferType,
|
||||
count: Int)
|
||||
{
|
||||
self.byteBuffer = byteBuffer
|
||||
self.offset = offset
|
||||
self.byteWidth = byteWidth
|
||||
self.type = type
|
||||
self.count = count
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public subscript(index: Int) -> Reference? {
|
||||
let elementOffset = offset &+ (numericCast(index) &* numericCast(byteWidth))
|
||||
return Reference(
|
||||
byteBuffer: byteBuffer,
|
||||
offset: elementOffset,
|
||||
parentWidth: byteWidth,
|
||||
byteWidth: 1,
|
||||
type: type)
|
||||
}
|
||||
}
|
||||
54
swift/Sources/FlexBuffers/Reader/FlexBufferVector.swift
Normal file
54
swift/Sources/FlexBuffers/Reader/FlexBufferVector.swift
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2024 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
|
||||
|
||||
protocol FlexBufferVector: Sized & FlexBufferContiguousBytes {
|
||||
subscript(index: Int) -> Reference? { get }
|
||||
}
|
||||
|
||||
extension FlexBufferVector {
|
||||
public func jsonBuilder(json: inout String) {
|
||||
json += "["
|
||||
for i in 0..<count {
|
||||
if let val = self[i]?.jsonString() {
|
||||
let comma = i == count - 1 ? "" : ", "
|
||||
json += "\(val)\(comma)"
|
||||
}
|
||||
}
|
||||
json += "]"
|
||||
}
|
||||
}
|
||||
|
||||
public protocol FlexBufferContiguousBytes {
|
||||
var byteBuffer: ByteBuffer { get }
|
||||
var offset: Int { get }
|
||||
var count: Int { get }
|
||||
|
||||
func withUnsafeRawBufferPointer<Result>(
|
||||
_ body: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result
|
||||
}
|
||||
|
||||
extension FlexBufferContiguousBytes {
|
||||
public func withUnsafeRawBufferPointer<Result>(
|
||||
_ body: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result
|
||||
{
|
||||
try byteBuffer.withUnsafePointerToSlice(
|
||||
index: offset,
|
||||
count: count,
|
||||
body: body)
|
||||
}
|
||||
}
|
||||
62
swift/Sources/FlexBuffers/Reader/Map.swift
Normal file
62
swift/Sources/FlexBuffers/Reader/Map.swift
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2024 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 struct Map: Sized {
|
||||
let byteBuffer: ByteBuffer
|
||||
let offset: Int
|
||||
let byteWidth: UInt8
|
||||
public let keys: TypedVector
|
||||
public let count: Int
|
||||
|
||||
public var values: Vector {
|
||||
return Vector(byteBuffer: byteBuffer, offset: offset, byteWidth: byteWidth)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
init(byteBuffer: ByteBuffer, offset: Int, byteWidth: UInt8) {
|
||||
self.byteBuffer = byteBuffer
|
||||
self.offset = offset
|
||||
self.byteWidth = byteWidth
|
||||
|
||||
count = getCount(buffer: byteBuffer, offset: offset, byteWidth: byteWidth)
|
||||
keys = TypedVector.mapKeys(
|
||||
byteBuffer: byteBuffer,
|
||||
offset: offset,
|
||||
byteWidth: byteWidth)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public subscript(key: String) -> Reference? {
|
||||
guard let position = binarySearch(vector: keys, target: key)
|
||||
else { return nil }
|
||||
|
||||
return getReference(at: position)
|
||||
}
|
||||
}
|
||||
|
||||
extension Map {
|
||||
public func jsonBuilder(json: inout String) {
|
||||
json += "{"
|
||||
for i in 0..<count {
|
||||
if let key = keys[i]?.cString {
|
||||
let comma = i == count - 1 ? "" : ", "
|
||||
let value = values[i]?.jsonString() ?? StaticJSON.null
|
||||
json += "\"\(key)\": \(value)\(comma)"
|
||||
}
|
||||
}
|
||||
json += "}"
|
||||
}
|
||||
}
|
||||
298
swift/Sources/FlexBuffers/Reader/Reference.swift
Normal file
298
swift/Sources/FlexBuffers/Reader/Reference.swift
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright 2024 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 FlexBuffersErrors: Error {
|
||||
case sizeOfBufferIsTooSmall
|
||||
case typeCouldNotBeDetermined
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func getRoot(buffer: ByteBuffer) throws -> Reference? {
|
||||
let end = buffer.count
|
||||
if buffer.count < 3 {
|
||||
throw FlexBuffersErrors.sizeOfBufferIsTooSmall
|
||||
}
|
||||
|
||||
let byteWidth = buffer.read(def: UInt8.self, position: end &- 1)
|
||||
let packedType = buffer.read(def: UInt8.self, position: end &- 2)
|
||||
let offset = end &- 2 &- numericCast(byteWidth)
|
||||
|
||||
return Reference(
|
||||
byteBuffer: buffer,
|
||||
offset: offset,
|
||||
parentWidth: byteWidth,
|
||||
packedType: packedType)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func getRootChecked(buffer: ByteBuffer) throws -> Reference? {
|
||||
// TODO(mustiikhalil): implement verifier
|
||||
return try getRoot(buffer: buffer)
|
||||
}
|
||||
|
||||
public struct Reference {
|
||||
private let byteBuffer: ByteBuffer
|
||||
private let offset: Int
|
||||
private let parentWidth: UInt8
|
||||
private let byteWidth: UInt8
|
||||
|
||||
public let type: FlexBufferType
|
||||
|
||||
@inline(__always)
|
||||
init?(
|
||||
byteBuffer: ByteBuffer,
|
||||
offset: Int,
|
||||
parentWidth: UInt8,
|
||||
packedType: UInt8)
|
||||
{
|
||||
guard let type = FlexBufferType(rawValue: UInt64(packedType >> 2)) else {
|
||||
return nil
|
||||
}
|
||||
self.byteBuffer = byteBuffer
|
||||
self.offset = offset
|
||||
self.parentWidth = parentWidth
|
||||
byteWidth = 1 << (packedType & 3)
|
||||
self.type = type
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
init(
|
||||
byteBuffer: ByteBuffer,
|
||||
offset: Int,
|
||||
parentWidth: UInt8,
|
||||
byteWidth: UInt8,
|
||||
type: FlexBufferType)
|
||||
{
|
||||
self.byteBuffer = byteBuffer
|
||||
self.offset = offset
|
||||
self.parentWidth = parentWidth
|
||||
self.byteWidth = byteWidth
|
||||
self.type = type
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public var bool: Bool? {
|
||||
return switch type {
|
||||
case .bool: byteBuffer.readUInt64(offset: offset, byteWidth: byteWidth) != 0
|
||||
default: nil
|
||||
}
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public var uint: UInt64? {
|
||||
return switch type {
|
||||
case .uint: byteBuffer.readUInt64(offset: offset, byteWidth: byteWidth)
|
||||
case .indirectUInt: byteBuffer.readUInt64(
|
||||
offset: indirect(),
|
||||
byteWidth: byteWidth)
|
||||
default: nil
|
||||
}
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public var int: Int64? {
|
||||
return switch type {
|
||||
case .int: byteBuffer.readInt64(offset: offset, byteWidth: byteWidth)
|
||||
case .indirectInt: byteBuffer.readInt64(
|
||||
offset: indirect(),
|
||||
byteWidth: byteWidth)
|
||||
default: nil
|
||||
}
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public var double: Double? {
|
||||
return switch type {
|
||||
case .float: byteBuffer.readDouble(offset: offset, byteWidth: byteWidth)
|
||||
case .indirectFloat: byteBuffer.readDouble(
|
||||
offset: indirect(),
|
||||
byteWidth: byteWidth)
|
||||
default: nil
|
||||
}
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public var map: Map? {
|
||||
guard type == .map else { return nil }
|
||||
return Map(
|
||||
byteBuffer: byteBuffer,
|
||||
offset: indirect(),
|
||||
byteWidth: byteWidth)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public var vector: Vector? {
|
||||
guard type == .vector || type == .map else { return nil }
|
||||
return Vector(
|
||||
byteBuffer: byteBuffer,
|
||||
offset: indirect(),
|
||||
byteWidth: byteWidth)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public var cString: String? {
|
||||
guard type == .string || type == .key else { return nil }
|
||||
let offset = indirect()
|
||||
|
||||
let count = getCount(
|
||||
buffer: byteBuffer,
|
||||
offset: offset,
|
||||
byteWidth: byteWidth)
|
||||
|
||||
return byteBuffer.readString(
|
||||
at: offset,
|
||||
count: count)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func blob<Result>(_ completion: (UnsafeRawBufferPointer) -> Result)
|
||||
-> Result?
|
||||
{
|
||||
guard type == .blob || type == .string else { return nil }
|
||||
|
||||
let offset = indirect()
|
||||
let count = getCount(
|
||||
buffer: byteBuffer,
|
||||
offset: offset,
|
||||
byteWidth: byteWidth)
|
||||
return byteBuffer.withUnsafePointerToSlice(
|
||||
index: offset,
|
||||
count: count,
|
||||
body: completion)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public var typedVector: TypedVector? {
|
||||
guard isTypedVectorType(type: type) else { return nil }
|
||||
guard var type = toTypedVectorElementType(type: type) else { return nil }
|
||||
if type == .string {
|
||||
type = .key
|
||||
}
|
||||
return TypedVector(
|
||||
byteBuffer: byteBuffer,
|
||||
offset: indirect(),
|
||||
byteWidth: byteWidth,
|
||||
type: type)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public var fixedTypedVector: FixedTypedVector? {
|
||||
guard isFixedTypedVectorType(type: type) else { return nil }
|
||||
let t = toFixedTypedVectorElementType(type: type)
|
||||
guard let type = t.type else { return nil }
|
||||
return FixedTypedVector(
|
||||
byteBuffer: byteBuffer,
|
||||
offset: indirect(),
|
||||
byteWidth: byteWidth,
|
||||
type: type,
|
||||
count: t.count)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func string(encoding: String.Encoding = .utf8) -> String? {
|
||||
guard type == .string else { return nil }
|
||||
let offset = indirect()
|
||||
|
||||
let count = getCount(
|
||||
buffer: byteBuffer,
|
||||
offset: offset,
|
||||
byteWidth: byteWidth)
|
||||
|
||||
return byteBuffer.readString(
|
||||
at: offset,
|
||||
count: count,
|
||||
type: encoding)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func asInt<T: FixedWidthInteger>() -> T? {
|
||||
guard let v = int else {
|
||||
return nil
|
||||
}
|
||||
return numericCast(v)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func asUInt<T: FixedWidthInteger>() -> T? {
|
||||
guard let v = uint else {
|
||||
return nil
|
||||
}
|
||||
return numericCast(v)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func withUnsafeRawPointer<Result>(
|
||||
_ completion: (UnsafeRawPointer) throws
|
||||
-> Result)
|
||||
rethrows -> Result?
|
||||
{
|
||||
return try byteBuffer.readWithUnsafeRawPointer(
|
||||
position: indirect(),
|
||||
completion)
|
||||
}
|
||||
|
||||
private func indirect() -> Int {
|
||||
readIndirect(buffer: byteBuffer, offset: offset, parentWidth)
|
||||
}
|
||||
}
|
||||
|
||||
extension Reference {
|
||||
|
||||
public func jsonString() -> String {
|
||||
var str = ""
|
||||
jsonBuilder(json: &str)
|
||||
return str
|
||||
}
|
||||
|
||||
func jsonBuilder(json: inout String) {
|
||||
switch type {
|
||||
case .null:
|
||||
json += StaticJSON.null
|
||||
case .uint, .indirectUInt:
|
||||
json += uint.valueOrNull
|
||||
case .int, .indirectInt:
|
||||
json += int.valueOrNull
|
||||
case .float, .indirectFloat:
|
||||
json += double.valueOrNull
|
||||
case .string, .key:
|
||||
json += "\"\(cString ?? StaticJSON.null)\""
|
||||
case .map:
|
||||
map?.jsonBuilder(json: &json)
|
||||
case .bool:
|
||||
json += bool.valueOrNull
|
||||
case .blob:
|
||||
if let p = blob({ String(data: Data($0), encoding: .utf8) })?
|
||||
.valueOrNull
|
||||
{
|
||||
json += "\"\(p)\""
|
||||
} else {
|
||||
json += StaticJSON.null
|
||||
}
|
||||
default:
|
||||
if type == .vector {
|
||||
vector?.jsonBuilder(json: &json)
|
||||
} else if isTypedVectorType(type: type) {
|
||||
typedVector?.jsonBuilder(json: &json)
|
||||
} else if isFixedTypedVectorType(type: type) {
|
||||
fixedTypedVector?.jsonBuilder(json: &json)
|
||||
} else {
|
||||
json += StaticJSON.null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
43
swift/Sources/FlexBuffers/Reader/Sized.swift
Normal file
43
swift/Sources/FlexBuffers/Reader/Sized.swift
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
*/
|
||||
|
||||
protocol Sized {
|
||||
var byteBuffer: ByteBuffer { get }
|
||||
var offset: Int { get }
|
||||
var byteWidth: UInt8 { get }
|
||||
var count: Int { get }
|
||||
}
|
||||
|
||||
extension Sized {
|
||||
|
||||
@inline(__always)
|
||||
func getReference(at index: Int) -> Reference? {
|
||||
if index >= count { return nil }
|
||||
let bWidth = Int(byteWidth)
|
||||
|
||||
let packedType = byteBuffer.read(
|
||||
def: UInt8.self,
|
||||
position: (offset &+ (count &* bWidth)) &+ index)
|
||||
|
||||
let offset = offset &+ (index &* bWidth)
|
||||
|
||||
return Reference(
|
||||
byteBuffer: byteBuffer,
|
||||
offset: offset,
|
||||
parentWidth: byteWidth,
|
||||
packedType: packedType)
|
||||
}
|
||||
}
|
||||
99
swift/Sources/FlexBuffers/Reader/TypedVector.swift
Normal file
99
swift/Sources/FlexBuffers/Reader/TypedVector.swift
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2024 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 TypedVector: FlexBufferVector {
|
||||
public let byteBuffer: ByteBuffer
|
||||
public let offset: Int
|
||||
public let type: FlexBufferType
|
||||
public let count: Int
|
||||
public var isEmpty: Bool { count == 0 }
|
||||
|
||||
let byteWidth: UInt8
|
||||
|
||||
@inline(__always)
|
||||
init(
|
||||
byteBuffer: ByteBuffer,
|
||||
offset: Int,
|
||||
byteWidth: UInt8,
|
||||
type: FlexBufferType)
|
||||
{
|
||||
self.byteBuffer = byteBuffer
|
||||
self.offset = offset
|
||||
self.byteWidth = byteWidth
|
||||
self.type = type
|
||||
count = getCount(buffer: byteBuffer, offset: offset, byteWidth: byteWidth)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public subscript(index: Int) -> Reference? {
|
||||
let elementOffset = offset &+ (numericCast(index) &* numericCast(byteWidth))
|
||||
return Reference(
|
||||
byteBuffer: byteBuffer,
|
||||
offset: elementOffset,
|
||||
parentWidth: byteWidth,
|
||||
byteWidth: 1,
|
||||
type: type)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
static func mapKeys(
|
||||
byteBuffer: ByteBuffer,
|
||||
offset: Int,
|
||||
byteWidth: UInt8) -> TypedVector
|
||||
{
|
||||
let prefixedFields = 3
|
||||
let keysOffset = offset &- (numericCast(byteWidth) &* prefixedFields)
|
||||
|
||||
let indirectOffset = readIndirect(
|
||||
buffer: byteBuffer,
|
||||
offset: keysOffset,
|
||||
byteWidth)
|
||||
|
||||
let childByteWidth = byteBuffer.readUInt64(
|
||||
offset: keysOffset &+ numericCast(byteWidth),
|
||||
byteWidth: byteWidth)
|
||||
|
||||
return TypedVector(
|
||||
byteBuffer: byteBuffer,
|
||||
offset: indirectOffset,
|
||||
byteWidth: numericCast(childByteWidth),
|
||||
type: .key)
|
||||
}
|
||||
}
|
||||
|
||||
extension TypedVector {
|
||||
@inline(__always)
|
||||
func compare(offset off: Int, target: String) -> Int {
|
||||
|
||||
let elementOffset = offset &+ (off &* numericCast(byteWidth))
|
||||
|
||||
let indirectoffset = readIndirect(
|
||||
buffer: byteBuffer,
|
||||
offset: elementOffset,
|
||||
byteWidth)
|
||||
|
||||
return byteBuffer.readWithUnsafeRawPointer(
|
||||
position: indirectoffset)
|
||||
{ bufPointer in
|
||||
target.withCString { strPointer in
|
||||
Int(strcmp(bufPointer, strPointer))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
42
swift/Sources/FlexBuffers/Reader/Vector.swift
Normal file
42
swift/Sources/FlexBuffers/Reader/Vector.swift
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
*/
|
||||
|
||||
// MARK: - Vector
|
||||
|
||||
public struct Vector: FlexBufferVector {
|
||||
public let byteBuffer: ByteBuffer
|
||||
public let offset: Int
|
||||
public let count: Int
|
||||
public var isEmpty: Bool { count == 0 }
|
||||
|
||||
let byteWidth: UInt8
|
||||
|
||||
@inline(__always)
|
||||
init(byteBuffer: ByteBuffer, offset: Int, byteWidth: UInt8) {
|
||||
self.byteBuffer = byteBuffer
|
||||
self.offset = offset
|
||||
self.byteWidth = byteWidth
|
||||
count = getCount(
|
||||
buffer: byteBuffer,
|
||||
offset: offset,
|
||||
byteWidth: byteWidth)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public subscript(index: Int) -> Reference? {
|
||||
return getReference(at: index)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user