mirror of
https://github.com/Dev1an/MsgPack.git
synced 2026-03-25 08:45:55 +00:00
Encode arrays
This commit is contained in:
parent
8dd5237c36
commit
264fd16a28
3 changed files with 237 additions and 64 deletions
|
|
@ -35,7 +35,9 @@ class IntermediateEncoder: Swift.Encoder {
|
|||
}
|
||||
|
||||
func unkeyedContainer() -> UnkeyedEncodingContainer {
|
||||
preconditionFailure()
|
||||
let unkeyedContainer = MsgPackUnkeyedEncodingContainer()
|
||||
container = unkeyedContainer
|
||||
return unkeyedContainer
|
||||
}
|
||||
|
||||
func singleValueContainer() -> SingleValueEncodingContainer {
|
||||
|
|
@ -71,6 +73,17 @@ extension Format {
|
|||
}
|
||||
}
|
||||
|
||||
static func from(array: [Format]) -> Format {
|
||||
switch array.count {
|
||||
case 1..<16:
|
||||
return .fixArray(array)
|
||||
case 16..<65536:
|
||||
return .array16(array)
|
||||
default:
|
||||
return .array32(array)
|
||||
}
|
||||
}
|
||||
|
||||
static func from(int: Int) -> Format {
|
||||
#if arch(arm) || arch(i386)
|
||||
return .int32(Int32(int))
|
||||
|
|
@ -88,12 +101,34 @@ extension Format {
|
|||
}
|
||||
}
|
||||
|
||||
class MessagePackEncodingContainer {
|
||||
class MessagePackEncodingContainer: Swift.Encoder {
|
||||
var userInfo = [CodingUserInfoKey : Any]()
|
||||
var codingPath: [CodingKey] = []
|
||||
|
||||
var temporaryContainer: MessagePackEncodingContainer?
|
||||
|
||||
func getFormat() throws -> Format {
|
||||
preconditionFailure()
|
||||
fatalError("subclasses should implement this method")
|
||||
}
|
||||
|
||||
func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key : CodingKey {
|
||||
let keyedContainer = MsgPackKeyedEncodingContainer<Key>()
|
||||
temporaryContainer = keyedContainer
|
||||
return KeyedEncodingContainer(keyedContainer)
|
||||
}
|
||||
|
||||
func unkeyedContainer() -> UnkeyedEncodingContainer {
|
||||
let unkeyedContainer = MsgPackUnkeyedEncodingContainer()
|
||||
temporaryContainer = unkeyedContainer
|
||||
return unkeyedContainer
|
||||
}
|
||||
|
||||
func singleValueContainer() -> SingleValueEncodingContainer {
|
||||
let singleValueContainer = MsgPackSingleValueEncodingContainer()
|
||||
temporaryContainer = singleValueContainer
|
||||
return singleValueContainer
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum MsgPackEncodingError: Swift.Error {
|
||||
|
|
@ -183,75 +218,77 @@ class MsgPackSingleValueEncodingContainer: MessagePackEncodingContainer, SingleV
|
|||
}
|
||||
|
||||
class MsgPackKeyedEncodingContainer<K: CodingKey>: MessagePackEncodingContainer, KeyedEncodingContainerProtocol {
|
||||
var userInfo = [CodingUserInfoKey : Any]()
|
||||
|
||||
var storage = [String: MessagePackEncodingContainer]()
|
||||
var temporaryContainer: MessagePackEncodingContainer?
|
||||
|
||||
let storageReference: KeyedStorageContainer
|
||||
|
||||
init(storage: KeyedStorageContainer = KeyedStorageContainer()) {
|
||||
storageReference = storage
|
||||
}
|
||||
|
||||
override func getFormat() throws -> Format {
|
||||
return try Format.from(keyValuePairs: storage.map {
|
||||
return try Format.from(keyValuePairs: storageReference.storage.map {
|
||||
(try Format.from(string: $0.key), try $0.value.getFormat())
|
||||
})
|
||||
}
|
||||
|
||||
func encodeNil(forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .nil)
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .nil)
|
||||
}
|
||||
|
||||
func encode(_ value: Bool, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .boolean(value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .boolean(value) )
|
||||
}
|
||||
|
||||
func encode(_ value: Int, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .from(int: value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .from(int: value) )
|
||||
}
|
||||
|
||||
func encode(_ value: Int8, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .int8(value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .int8(value) )
|
||||
}
|
||||
|
||||
func encode(_ value: Int16, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .int16(value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .int16(value) )
|
||||
}
|
||||
|
||||
func encode(_ value: Int32, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .int32(value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .int32(value) )
|
||||
}
|
||||
|
||||
func encode(_ value: Int64, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .int64(value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .int64(value) )
|
||||
}
|
||||
|
||||
func encode(_ value: UInt, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .from(uInt: value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .from(uInt: value) )
|
||||
}
|
||||
|
||||
func encode(_ value: UInt8, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .uInt8(value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .uInt8(value) )
|
||||
}
|
||||
|
||||
func encode(_ value: UInt16, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .uInt16(value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .uInt16(value) )
|
||||
}
|
||||
|
||||
func encode(_ value: UInt32, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .uInt32(value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .uInt32(value) )
|
||||
}
|
||||
|
||||
func encode(_ value: UInt64, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .uInt64(value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .uInt64(value) )
|
||||
}
|
||||
|
||||
func encode(_ value: Float, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .float32(value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .float32(value) )
|
||||
}
|
||||
|
||||
func encode(_ value: Double, forKey key: K) throws {
|
||||
storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .float64(value) )
|
||||
storageReference.storage[key.stringValue] = MsgPackSingleValueEncodingContainer(with: .float64(value) )
|
||||
}
|
||||
|
||||
func encode(_ value: String, forKey key: K) throws {
|
||||
storage[key.stringValue] = try MsgPackSingleValueEncodingContainer(with: .from(string: value) )
|
||||
storageReference.storage[key.stringValue] = try MsgPackSingleValueEncodingContainer(with: .from(string: value) )
|
||||
}
|
||||
|
||||
func encode<T>(_ value: T, forKey key: K) throws where T : Encodable {
|
||||
|
|
@ -259,21 +296,23 @@ class MsgPackKeyedEncodingContainer<K: CodingKey>: MessagePackEncodingContainer,
|
|||
guard let container = temporaryContainer else {
|
||||
throw MsgPackEncodingError.valueDidNotAskForContainer
|
||||
}
|
||||
storage[key.stringValue] = container
|
||||
storageReference.storage[key.stringValue] = container
|
||||
}
|
||||
|
||||
func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type, forKey key: K) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey {
|
||||
let keyedContainer = MsgPackKeyedEncodingContainer<NestedKey>()
|
||||
storage[key.stringValue] = keyedContainer
|
||||
storageReference.storage[key.stringValue] = keyedContainer
|
||||
return KeyedEncodingContainer(keyedContainer)
|
||||
}
|
||||
|
||||
func nestedUnkeyedContainer(forKey key: K) -> UnkeyedEncodingContainer {
|
||||
preconditionFailure("not implemented")
|
||||
let unkeyedContainer = MsgPackUnkeyedEncodingContainer()
|
||||
storageReference.storage[key.stringValue] = unkeyedContainer
|
||||
return unkeyedContainer
|
||||
}
|
||||
|
||||
func superEncoder() -> Swift.Encoder {
|
||||
preconditionFailure("not implemented")
|
||||
return KeyedEncoder(referencing: storageReference)
|
||||
}
|
||||
|
||||
func superEncoder(forKey key: K) -> Swift.Encoder {
|
||||
|
|
@ -281,20 +320,155 @@ class MsgPackKeyedEncodingContainer<K: CodingKey>: MessagePackEncodingContainer,
|
|||
}
|
||||
}
|
||||
|
||||
extension MsgPackKeyedEncodingContainer: Swift.Encoder {
|
||||
class KeyedStorageContainer {
|
||||
var storage: [String: MessagePackEncodingContainer]
|
||||
init(storage: [String:MessagePackEncodingContainer] = [:]) {
|
||||
self.storage = storage
|
||||
}
|
||||
}
|
||||
|
||||
class KeyedEncoder: Swift.Encoder {
|
||||
var codingPath = [CodingKey]()
|
||||
|
||||
var userInfo = [CodingUserInfoKey : Any]()
|
||||
|
||||
let storageReference: KeyedStorageContainer
|
||||
|
||||
init(referencing storage: KeyedStorageContainer) {
|
||||
storageReference = storage
|
||||
}
|
||||
|
||||
func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key : CodingKey {
|
||||
return KeyedEncodingContainer(MsgPackKeyedEncodingContainer())
|
||||
}
|
||||
|
||||
func unkeyedContainer() -> UnkeyedEncodingContainer {
|
||||
preconditionFailure("impossible to give an unkeyed container")
|
||||
}
|
||||
|
||||
func singleValueContainer() -> SingleValueEncodingContainer {
|
||||
preconditionFailure("impossible to give a single value container")
|
||||
}
|
||||
}
|
||||
|
||||
class MsgPackUnkeyedEncodingContainer: MessagePackEncodingContainer, UnkeyedEncodingContainer {
|
||||
var count: Int { return storage.count }
|
||||
|
||||
var storage = [MessagePackEncodingContainer]()
|
||||
|
||||
override func getFormat() throws -> Format {
|
||||
return try .from(array: storage.map {try $0.getFormat()} )
|
||||
}
|
||||
|
||||
func encodeNil() throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .nil))
|
||||
}
|
||||
|
||||
func encode(_ value: Bool) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .boolean(value)))
|
||||
}
|
||||
|
||||
func encode(_ value: Int) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .from(int: value)))
|
||||
}
|
||||
|
||||
func encode(_ value: Int8) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .int8(value)))
|
||||
}
|
||||
|
||||
func encode(_ value: Int16) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .int16(value)))
|
||||
}
|
||||
|
||||
func encode(_ value: Int32) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .int32(value)))
|
||||
}
|
||||
|
||||
func encode(_ value: Int64) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .int64(value)))
|
||||
}
|
||||
|
||||
func encode(_ value: UInt) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .from(uInt: value)))
|
||||
}
|
||||
|
||||
func encode(_ value: UInt8) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .uInt8(value)))
|
||||
}
|
||||
|
||||
func encode(_ value: UInt16) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .uInt16(value)))
|
||||
}
|
||||
|
||||
func encode(_ value: UInt32) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .uInt32(value)))
|
||||
}
|
||||
|
||||
func encode(_ value: UInt64) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .uInt64(value)))
|
||||
}
|
||||
|
||||
func encode(_ value: Float) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .float32(value)))
|
||||
}
|
||||
|
||||
func encode(_ value: Double) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: .float64(value)))
|
||||
}
|
||||
|
||||
func encode(_ value: String) throws {
|
||||
storage.append(MsgPackSingleValueEncodingContainer(with: try .from(string: value)))
|
||||
}
|
||||
|
||||
func encode<T : Encodable>(_ value: T) throws {
|
||||
try value.encode(to: self)
|
||||
guard let container = temporaryContainer else { throw MsgPackEncodingError.valueDidNotAskForContainer }
|
||||
storage.append(container)
|
||||
}
|
||||
|
||||
func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey {
|
||||
let container = MsgPackKeyedEncodingContainer<NestedKey>()
|
||||
storage.append(container)
|
||||
return KeyedEncodingContainer(container)
|
||||
}
|
||||
|
||||
func nestedUnkeyedContainer() -> UnkeyedEncodingContainer {
|
||||
let container = MsgPackUnkeyedEncodingContainer()
|
||||
storage.append(container)
|
||||
return container
|
||||
}
|
||||
|
||||
func superEncoder() -> Swift.Encoder {
|
||||
return UnkeyedEncoder(referencing: self)
|
||||
}
|
||||
}
|
||||
|
||||
class UnkeyedEncoder: Swift.Encoder {
|
||||
var codingPath = [CodingKey]()
|
||||
|
||||
var userInfo = [CodingUserInfoKey : Any]()
|
||||
|
||||
let container: MsgPackUnkeyedEncodingContainer
|
||||
|
||||
init(referencing container: MsgPackUnkeyedEncodingContainer) {
|
||||
self.container = container
|
||||
}
|
||||
|
||||
func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key : CodingKey {
|
||||
let keyedContainer = MsgPackKeyedEncodingContainer<Key>()
|
||||
temporaryContainer = keyedContainer
|
||||
container.storage.append(keyedContainer)
|
||||
return KeyedEncodingContainer(keyedContainer)
|
||||
}
|
||||
|
||||
func unkeyedContainer() -> UnkeyedEncodingContainer {
|
||||
preconditionFailure()
|
||||
let unkeyedContainer = MsgPackUnkeyedEncodingContainer()
|
||||
container.storage.append(unkeyedContainer)
|
||||
return unkeyedContainer
|
||||
}
|
||||
|
||||
func singleValueContainer() -> SingleValueEncodingContainer {
|
||||
let singleValueContainer = MsgPackSingleValueEncodingContainer()
|
||||
temporaryContainer = singleValueContainer
|
||||
container.storage.append(singleValueContainer)
|
||||
return singleValueContainer
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,26 +108,12 @@ class MsgPackTests: XCTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
// var encoder = MsgPack.JSONEncoder2()
|
||||
//
|
||||
// struct Obj: Encodable {
|
||||
// let i: Int
|
||||
// let p: Person
|
||||
// }
|
||||
//
|
||||
// struct Person: Encodable {
|
||||
// let name: String
|
||||
// let friend: Friend
|
||||
// }
|
||||
//
|
||||
// struct Friend: Encodable {
|
||||
// let count: Double
|
||||
// }
|
||||
//
|
||||
// func testDinges() {
|
||||
// try! encoder.encode(
|
||||
// Obj(i: 3, p: Person(name: "Dinges", friend: Friend(count: 8)))
|
||||
// )
|
||||
// }
|
||||
func testExample() {
|
||||
do {
|
||||
print(try encoder.encode([[Int8(-3)], [5], [8]]))
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,23 +5,36 @@ import Foundation
|
|||
|
||||
let encoder = Encoder()
|
||||
|
||||
try encoder.encode(0x0102030405060708)
|
||||
struct Graph: Encodable {
|
||||
let title: String
|
||||
let circles: [Circle]
|
||||
}
|
||||
|
||||
try encoder.encode("Hello")
|
||||
|
||||
try encoder.encode("😇")
|
||||
|
||||
var n: Int?
|
||||
try encoder.encode(n)
|
||||
struct Circle: Encodable {
|
||||
let radius: UInt
|
||||
let center: Position
|
||||
}
|
||||
|
||||
struct Position: Encodable {
|
||||
let x: Int8
|
||||
let y: Int8
|
||||
}
|
||||
|
||||
struct Circle: Encodable {
|
||||
let center: Position
|
||||
let radius: UInt
|
||||
}
|
||||
let graph = Graph(
|
||||
title: "My graph",
|
||||
circles: [
|
||||
Circle(
|
||||
radius: 0x0102030405060708,
|
||||
center: Position(x: -123, y: 2)
|
||||
),
|
||||
Circle(
|
||||
radius: 1000,
|
||||
center: Position(x: 116, y: 81)
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
try encoder.encode(Circle(center: Position(x: -1, y: 2), radius: 67))
|
||||
let encodedGraph = try encoder.encode(graph)
|
||||
for byte in encodedGraph {
|
||||
print(String(byte, radix:16))
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue