这是基于以下 PR #96 的原始 SwiftCBOR 库的分支。原始库可在这里找到
Swift 中的 CBOR (RFC 7049 简洁二进制对象表示) 解码器和编码器。直接从 Swift 类型编码或使用包装器对象。解码为 CBOR 值类型,可以使用原生 Swift 下标访问,并使用等效的字面量表示法表示。
Codable
支持!NegativeInt(UInt)
,其中实际数字为 -1 - i
(CBOR 的负整数可以大于 64 位有符号整数)。CBOR
类型定义!subscript
(下标)也是。因此您可以像这样访问 CBOR 映射和数组:myDecodedObject["numbers"][1]
。CBORInputStream
协议,并像这样创建解码器:CBORDecoder(stream: yourStream)
。有很多方法:Swift Package Manager、CocoaPods、git submodule...
CocoaPod 是由贡献者提交的,那里的更新可能会延迟。
Swift Package Manager 是推荐的依赖管理器。
import SwiftCBOR
let decoded = try! CBOR.decode([0x9f, 0x18, 255, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2, 0x18, 1, 0x79, 0x00, 3, 0x41, 0x42, 0x43, 0x79, 0x00, 3, 0x41, 0x42, 0x43, 0xff])
print(decoded)
// CBOR.array([CBOR.unsignedInt(255), CBOR.array([CBOR.unsignedInt(1), CBOR.utf8String("ABC")]), CBOR.utf8String("ABC")])
要解包解码后的 CBOR
值,请使用 模式匹配!!
编码值会返回一个字节数组,[UInt8]
。您可以使用 CBOR.encode(myValue)
或 myValue.encode()
进行编码。任何符合 CBOREncodable
协议的类型都可以被编码。您可以为您的类型实现 CBOREncodable
协议,然后像往常一样进行编码。
CBOR.encode(100) // --> [0x18, 0x64] of type [UInt8]
Int(100).encode() // --> [0x18, 0x64]. Int conforms to the CBOREncodable protocol
"hello".encode() // --> [0x65, 0x68, 0x65, 0x6c, 0x6c, 0x6f]. So does String
CBOR.encode(["a", "b", "c"])
let byteString: [UInt8] = [0x01, 0x02]
CBOR.encode(byteString, asByteString: true)
由于 Swift 的不完整的泛型系统,您不能调用 someArray.encode()
或 someDictionary.encode()
,但只要您的数组项或映射键和值类型符合 CBOREncodable
,您就可以简单地使用 CBOR.encode(someArrayOrMap)
。
在某些情况下,可能需要先创建一个 CBOR
中间表示形式,然后再进行编码。例如,如果您想编码一个包含异构类型的数组或字典(这在类似 JSON 的对象中很常见),您还不能使用原生 Swift 映射。您可以对您的类型实现 CBOREncodable
,这将构建一个 CBOR
值并对其进行编码,或者在不使用 CBOREncodable
的情况下执行 CBOR
值操作。
CBOR
枚举可以使用字面量表示,但请注意,变量不是字面量,因此您可能需要手动调用构造函数。
public protocol CBOREncodable {
func encode(options: CBOROptions) -> [UInt8]
}
struct MyStruct: CBOREncodable {
var x: Int
var y: String
public func encode(options: CBOROptions = CBOROption()) -> [UInt8] {
let cborWrapper: CBOR = [
"x": CBOR(integerLiteral: self.x), // You can use the literal constructors
"y": CBOR.utf8String(self.y), // Or the enum variants
"z": 123 // Or literals
]
return cborWrapper.encode()
}
}
MyStruct(x: 42, y: "words").encode()
// --> bytes (as hex): a2 61 79 65 77 6f 72 64 73 61 78 18 2a
encode
函数不必一定是那样的。如果您想做一些自定义操作,例如保留映射键的顺序,您可以手动构建 [UInt8]
。查看 Encoder 函数 以获取灵感。
当前的通用 API 列在下面。当您需要对要编码的类型进行精细控制时,请使用以下 API。
func encode<T: CBOREncodable>(_ value: T) -> [UInt8]
func encode<A: CBOREncodable, B: CBOREncodable>(_ dict: [A: B]) -> [UInt8]
// NOTE: Please see the note on encoding byte strings at the end of this readme.
func encode<T: CBOREncodable>(_ array: [T], asByteString: Bool = false) -> [UInt8]
/// Only needed for fine-grained control:
func encodeUInt{8, 16, 32, 64}(_ x: UInt8) -> [UInt8]
func encodeNegativeInt(_ x: Int) -> [UInt8]
func encodeByteString(_ bs: [UInt8]) -> [UInt8] // does no endian interpretation
func encodeString(_ str: String) -> [UInt8]
func encodeArray<T: CBOREncodable>(_ arr: [T]) -> [UInt8]
func encodeMap<A: CBOREncodable, B: CBOREncodable>(_ map: [A: B]) -> [UInt8]
func encodeTagged<T: CBOREncodable>(tag: UInt8, value: T) -> [UInt8]
func encodeSimpleValue(_ x: UInt8) -> [UInt8]
func encode{Null, Undefined, Break}() -> [UInt8]
func encodeFloat(_ x: Float) -> [UInt8]
func encodeDouble(_ x: Double) -> [UInt8]
func encodeBool(_ x: Bool) -> [UInt8]
要编码无限长度的数组、映射、字符串和字节字符串,请显式使用打开和关闭流 CBOR 值。在这两个值之间,使用带有 CBOR.encodeArrayChunk
和 CBOR.encodeMapChunk
的编码数组和映射块。无限字符串和字节字符串可以像正常方式编码(即,它们不需要自己的“块”函数)。
let map: [String: Int] = ["a": 1]
let map2 = ["B": 2]
CBOR.encodeMapStreamStart() + CBOR.encodeMapChunk(map) + CBOR.encodeMapChunk(map2) + CBOR.encodeStreamEnd()
let bs: [UInt8] = [0xf0]
let bs2: [UInt8] = [0xff]
CBOR.encodeByteStringStreamStart()
+ CBOR.encode(bs, asByteString: true)
+ CBOR.encode(bs2, asByteString: true)
+ CBOR.encodeStreamEnd()
// Current stream-encoding API:
func encodeArrayStreamStart() -> [UInt8]
func encodeMapStreamStart() -> [UInt8]
func encodeStringStreamStart() -> [UInt8]
func encodeByteStringStreamStart() -> [UInt8]
func encodeStreamEnd() -> [UInt8] // Equal to CBOR.encodeBreak()
func encodeArrayChunk<T: CBOREncodable>(_ chunk: [T]) -> [UInt8]
func encodeMapChunk<A: CBOREncodable, B: CBOREncodable>(_ map: [A: B]) -> [UInt8]
最后,关于使用通用数组编码器 CBOR.encode(..)
编码字节字符串的技术说明。如果函数参数 asByteString
为 true,则除了 UInt8 之外的所有类型的数组,如果计算机是小端字节序(CBOR 使用大端字节序或网络字节序),则每个项目的原始字节将被反转(但项目本身的顺序不会反转)。UInt8 数组被认为已经使用网络字节序。
通过参与本项目,您同意遵守贡献者行为准则。
这是发布到公共领域的自由且不受限制的软件。有关更多信息,请参阅 UNLICENSE
文件或 unlicense.org。