mirror of
https://github.com/Dev1an/MsgPack.git
synced 2026-04-27 14:57:46 +00:00
Refactor keyedencoder
This commit is contained in:
parent
d4a3b31dd1
commit
ba6625187d
1 changed files with 36 additions and 30 deletions
|
|
@ -42,6 +42,7 @@ class IntermediateDecoder: Swift.Decoder {
|
||||||
var storage: Data
|
var storage: Data
|
||||||
|
|
||||||
let dictionary: PartiallyDecodedDictionary
|
let dictionary: PartiallyDecodedDictionary
|
||||||
|
var cursor = 0
|
||||||
|
|
||||||
init(with data: Data) {
|
init(with data: Data) {
|
||||||
storage = data
|
storage = data
|
||||||
|
|
@ -211,14 +212,22 @@ struct MsgPckKeyedDecodingContainer<K: CodingKey>: KeyedDecodingContainerProtoco
|
||||||
self.decoder = decoder
|
self.decoder = decoder
|
||||||
|
|
||||||
var link = decoder.dictionary
|
var link = decoder.dictionary
|
||||||
for x in codingPath {
|
for x in codingPath.dropLast() {
|
||||||
guard case let .dictionary(newLink) = link.storage[x.stringValue]! else {fatalError()}
|
guard case let .dictionary(newLink) = link.storage[x.stringValue]! else {fatalError()}
|
||||||
link = newLink
|
link = newLink
|
||||||
}
|
}
|
||||||
relativeDictionary = link
|
if let lastCodingKey = codingPath.last, let lastReference = link.storage[lastCodingKey.stringValue] {
|
||||||
var cursor = relativeDictionary.pointer
|
guard case .dictionary(let newLink) = lastReference else {fatalError()}
|
||||||
|
relativeDictionary = newLink
|
||||||
|
} else {
|
||||||
|
var cursor = decoder.cursor
|
||||||
|
if let lastCodingKey = codingPath.last {
|
||||||
|
relativeDictionary = PartiallyDecodedDictionary(pointer: cursor)
|
||||||
|
link.storage[lastCodingKey.stringValue] = .dictionary(relativeDictionary)
|
||||||
|
} else {
|
||||||
|
relativeDictionary = link
|
||||||
|
}
|
||||||
|
|
||||||
if relativeDictionary.storage.count == 0 {
|
|
||||||
let elementCount: Int
|
let elementCount: Int
|
||||||
switch decoder.storage[cursor] {
|
switch decoder.storage[cursor] {
|
||||||
case FormatID.fixMapRange:
|
case FormatID.fixMapRange:
|
||||||
|
|
@ -235,7 +244,6 @@ struct MsgPckKeyedDecodingContainer<K: CodingKey>: KeyedDecodingContainerProtoco
|
||||||
}
|
}
|
||||||
for _ in 0 ..< elementCount {
|
for _ in 0 ..< elementCount {
|
||||||
let key = try Format.string(from: &decoder.storage, base: &cursor)
|
let key = try Format.string(from: &decoder.storage, base: &cursor)
|
||||||
|
|
||||||
let valueFormat: FormatID
|
let valueFormat: FormatID
|
||||||
if let valueFormatLookup = FormatID(rawValue: decoder.storage[cursor]) {
|
if let valueFormatLookup = FormatID(rawValue: decoder.storage[cursor]) {
|
||||||
valueFormat = valueFormatLookup
|
valueFormat = valueFormatLookup
|
||||||
|
|
@ -289,18 +297,15 @@ struct MsgPckKeyedDecodingContainer<K: CodingKey>: KeyedDecodingContainerProtoco
|
||||||
relativeDictionary.storage[key] = .variableWidth(valueFormat, pointer: cursor, length: length)
|
relativeDictionary.storage[key] = .variableWidth(valueFormat, pointer: cursor, length: length)
|
||||||
cursor += length
|
cursor += length
|
||||||
case .fixArray, .array16, .array32:
|
case .fixArray, .array16, .array32:
|
||||||
let length = Int(decoder.storage[cursor] - valueFormat.rawValue)
|
|
||||||
cursor += 1
|
|
||||||
fatalError("not implemented")
|
fatalError("not implemented")
|
||||||
case .fixMap, .map16, .map32:
|
case .fixMap, .map16, .map32:
|
||||||
let partial = PartiallyDecodedDictionary(pointer: cursor)
|
decoder.cursor = cursor
|
||||||
relativeDictionary.storage[key] = .dictionary(partial)
|
let container = try MsgPckKeyedDecodingContainer<TemporaryCodingKey>(referringTo: decoder, with: codingPath + [TemporaryCodingKey(stringValue: key)!])
|
||||||
try MsgPckKeyedDecodingContainer(referringTo: decoder, with: codingPath + [TemporaryCodingKey(stringValue: key)!])
|
cursor += container.relativeDictionary.byteCount
|
||||||
cursor += partial.byteCount
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
relativeDictionary.byteCount = cursor - relativeDictionary.pointer
|
||||||
}
|
}
|
||||||
relativeDictionary.byteCount = cursor - relativeDictionary.pointer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func contains(_ key: K) -> Bool {
|
func contains(_ key: K) -> Bool {
|
||||||
|
|
@ -413,12 +418,29 @@ struct MsgPckKeyedDecodingContainer<K: CodingKey>: KeyedDecodingContainerProtoco
|
||||||
}
|
}
|
||||||
|
|
||||||
func decode<T>(_ type: T.Type, forKey key: K) throws -> T where T : Decodable {
|
func decode<T>(_ type: T.Type, forKey key: K) throws -> T where T : Decodable {
|
||||||
|
let sliceDecoder = try superDecoder(forKey: key)
|
||||||
|
return try T(from: sliceDecoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type, forKey key: K) throws -> KeyedDecodingContainer<NestedKey> where NestedKey : CodingKey {
|
||||||
|
return KeyedDecodingContainer(try MsgPckKeyedDecodingContainer<NestedKey>(referringTo: decoder, with: codingPath + [key]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func nestedUnkeyedContainer(forKey key: K) throws -> UnkeyedDecodingContainer {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func superDecoder() throws -> Swift.Decoder {
|
||||||
|
return decoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func superDecoder(forKey key: K) throws -> Swift.Decoder {
|
||||||
guard let value = relativeDictionary.storage[key.stringValue] else {
|
guard let value = relativeDictionary.storage[key.stringValue] else {
|
||||||
throw DecodingError.keyNotFound(key, .init(codingPath: codingPath, debugDescription: "Key not found: \(key.stringValue)"))
|
throw DecodingError.keyNotFound(key, .init(codingPath: codingPath, debugDescription: "Key not found: \(key.stringValue)"))
|
||||||
}
|
}
|
||||||
let sliceDecoder: IntermediateDecoder
|
let sliceDecoder: IntermediateDecoder
|
||||||
switch value {
|
switch value {
|
||||||
|
|
||||||
case .constant(let format):
|
case .constant(let format):
|
||||||
sliceDecoder = IntermediateDecoder(with: Data([format.rawValue]))
|
sliceDecoder = IntermediateDecoder(with: Data([format.rawValue]))
|
||||||
case let .fixedWidth(format, pointer):
|
case let .fixedWidth(format, pointer):
|
||||||
|
|
@ -431,23 +453,7 @@ struct MsgPckKeyedDecodingContainer<K: CodingKey>: KeyedDecodingContainerProtoco
|
||||||
sliceDecoder = IntermediateDecoder(withUnsafeDataFrom: decoder, start: reference.pointer, length: reference.byteCount)
|
sliceDecoder = IntermediateDecoder(withUnsafeDataFrom: decoder, start: reference.pointer, length: reference.byteCount)
|
||||||
}
|
}
|
||||||
sliceDecoder.codingPath = codingPath + [key]
|
sliceDecoder.codingPath = codingPath + [key]
|
||||||
return try T(from: sliceDecoder)
|
return sliceDecoder
|
||||||
}
|
|
||||||
|
|
||||||
func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type, forKey key: K) throws -> KeyedDecodingContainer<NestedKey> where NestedKey : CodingKey {
|
|
||||||
fatalError("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func nestedUnkeyedContainer(forKey key: K) throws -> UnkeyedDecodingContainer {
|
|
||||||
fatalError("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func superDecoder() throws -> Swift.Decoder {
|
|
||||||
fatalError("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func superDecoder(forKey key: K) throws -> Swift.Decoder {
|
|
||||||
fatalError("not implemented")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typealias Key = K
|
typealias Key = K
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue