mirror of
https://github.com/Dev1an/MsgPack.git
synced 2026-04-27 14:57:46 +00:00
Decode string
This commit is contained in:
parent
101abe3e46
commit
aca03f1952
4 changed files with 155 additions and 16 deletions
|
|
@ -148,10 +148,103 @@ struct MsgPckSingleValueDecodingContainer: SingleValueDecodingContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
func decode(_ type: String.Type) throws -> String {
|
func decode(_ type: String.Type) throws -> String {
|
||||||
fatalError("not implemented")
|
return try Format.string(from: &decoder.storage)
|
||||||
}
|
}
|
||||||
|
|
||||||
func decode<T>(_ type: T.Type) throws -> T where T : Decodable {
|
func decode<T>(_ type: T.Type) throws -> T where T : Decodable {
|
||||||
fatalError("not implemented")
|
fatalError("not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct MsgPckKeyedDecodingContainer<K: CodingKey>: KeyedDecodingContainerProtocol {
|
||||||
|
var codingPath: [CodingKey]
|
||||||
|
|
||||||
|
var allKeys: [K]
|
||||||
|
|
||||||
|
func contains(_ key: K) -> Bool {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeNil(forKey key: K) throws -> Bool {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Bool.Type, forKey key: K) throws -> Bool {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Int.Type, forKey key: K) throws -> Int {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Int8.Type, forKey key: K) throws -> Int8 {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Int16.Type, forKey key: K) throws -> Int16 {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Int32.Type, forKey key: K) throws -> Int32 {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Int64.Type, forKey key: K) throws -> Int64 {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: UInt.Type, forKey key: K) throws -> UInt {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: UInt8.Type, forKey key: K) throws -> UInt8 {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: UInt16.Type, forKey key: K) throws -> UInt16 {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: UInt32.Type, forKey key: K) throws -> UInt32 {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: UInt64.Type, forKey key: K) throws -> UInt64 {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Float.Type, forKey key: K) throws -> Float {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Double.Type, forKey key: K) throws -> Double {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: String.Type, forKey key: K) throws -> String {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode<T>(_ type: T.Type, forKey key: K) throws -> T where T : Decodable {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ public class Encoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MsgPackEncodingError: Swift.Error {
|
enum MsgPackEncodingError: Swift.Error {
|
||||||
case notImplemented, stringNotConvertibleToUTF8(String), valueDidNotAskForContainer
|
case stringNotConvertibleToUTF8(String), valueDidNotAskForContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
class IntermediateEncoder: Swift.Encoder {
|
class IntermediateEncoder: Swift.Encoder {
|
||||||
|
|
@ -159,7 +159,7 @@ class MsgPackSingleValueEncodingContainer: MessagePackEncodingContainer, SingleV
|
||||||
}
|
}
|
||||||
|
|
||||||
func encode<T : Encodable>(_ value: T) throws {
|
func encode<T : Encodable>(_ value: T) throws {
|
||||||
throw MsgPackEncodingError.notImplemented
|
fatalError("Not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -262,7 +262,7 @@ class MsgPackKeyedEncodingContainer<K: CodingKey>: MessagePackEncodingContainer,
|
||||||
}
|
}
|
||||||
|
|
||||||
func superEncoder(forKey key: K) -> Swift.Encoder {
|
func superEncoder(forKey key: K) -> Swift.Encoder {
|
||||||
preconditionFailure("not implemented")
|
fatalError("not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,11 @@ public enum FormatID: UInt8 {
|
||||||
case float32
|
case float32
|
||||||
case float64
|
case float64
|
||||||
|
|
||||||
case positiveInt7 = 0
|
case firstPositiveInt7 = 0b00000000
|
||||||
case negativeInt5 = 0b11100000
|
case lastPositiveInt7 = 0b01111111
|
||||||
|
|
||||||
|
case firstNegativeInt5 = 0b11100000
|
||||||
|
case lastNegativeInt5 = 0b11111111
|
||||||
|
|
||||||
case uInt8 = 0xCC
|
case uInt8 = 0xCC
|
||||||
case uInt16
|
case uInt16
|
||||||
|
|
@ -82,16 +85,19 @@ public enum FormatID: UInt8 {
|
||||||
case fixExt8
|
case fixExt8
|
||||||
case fixExt16
|
case fixExt16
|
||||||
|
|
||||||
case fixString = 0b10100000
|
case fixStringStart = 0b10100000
|
||||||
|
case fixStringEnd = 0b10111111
|
||||||
case string8 = 0xD9
|
case string8 = 0xD9
|
||||||
case string16
|
case string16
|
||||||
case string32
|
case string32
|
||||||
|
|
||||||
case fixArray = 0b10010000
|
case fixArrayStart = 0b10010000
|
||||||
|
case fixArrayEnd = 0b10011111
|
||||||
case array16 = 0xDC
|
case array16 = 0xDC
|
||||||
case array32
|
case array32
|
||||||
|
|
||||||
case fixMap = 0b10000000
|
case fixMapStart = 0b10000000
|
||||||
|
case fixMapEnd = 0b10001111
|
||||||
case map16 = 0xDE
|
case map16 = 0xDE
|
||||||
case map32
|
case map32
|
||||||
}
|
}
|
||||||
|
|
@ -110,9 +116,9 @@ extension Format {
|
||||||
|
|
||||||
// MARK: Small integers (< 8 bit)
|
// MARK: Small integers (< 8 bit)
|
||||||
case .positiveInt7(let value):
|
case .positiveInt7(let value):
|
||||||
data.append(value | FormatID.positiveInt7.rawValue)
|
data.append(value | FormatID.firstPositiveInt7.rawValue)
|
||||||
case .negativeInt5(let value):
|
case .negativeInt5(let value):
|
||||||
data.append(value | FormatID.negativeInt5.rawValue)
|
data.append(value | FormatID.firstNegativeInt5.rawValue)
|
||||||
|
|
||||||
// MARK: Unsigned integers
|
// MARK: Unsigned integers
|
||||||
case .uInt8(let value):
|
case .uInt8(let value):
|
||||||
|
|
@ -173,7 +179,7 @@ extension Format {
|
||||||
// MARK: Strings
|
// MARK: Strings
|
||||||
case .fixString(let utf8Data):
|
case .fixString(let utf8Data):
|
||||||
precondition(utf8Data.count < 32, "fix strings cannot contain more than 31 bytes")
|
precondition(utf8Data.count < 32, "fix strings cannot contain more than 31 bytes")
|
||||||
data.append( UInt8(utf8Data.count) | FormatID.fixString.rawValue)
|
data.append( UInt8(utf8Data.count) | FormatID.fixStringStart.rawValue)
|
||||||
data.append(utf8Data)
|
data.append(utf8Data)
|
||||||
case .string8(let utf8Data):
|
case .string8(let utf8Data):
|
||||||
data.append(contentsOf: [FormatID.string8.rawValue, UInt8(utf8Data.count)])
|
data.append(contentsOf: [FormatID.string8.rawValue, UInt8(utf8Data.count)])
|
||||||
|
|
@ -194,7 +200,7 @@ extension Format {
|
||||||
// MARK: Arrays
|
// MARK: Arrays
|
||||||
case .fixArray(let array):
|
case .fixArray(let array):
|
||||||
precondition(array.count < 16, "fix arrays cannot contain more than 15 elements")
|
precondition(array.count < 16, "fix arrays cannot contain more than 15 elements")
|
||||||
data.append( UInt8(array.count) | FormatID.fixArray.rawValue)
|
data.append( UInt8(array.count) | FormatID.fixArrayStart.rawValue)
|
||||||
for element in array {
|
for element in array {
|
||||||
element.appendTo(data: &data)
|
element.appendTo(data: &data)
|
||||||
}
|
}
|
||||||
|
|
@ -218,7 +224,7 @@ extension Format {
|
||||||
// MARK: Maps
|
// MARK: Maps
|
||||||
case .fixMap(let pairs):
|
case .fixMap(let pairs):
|
||||||
precondition(pairs.count < 16, "fix maps cannot contain more than 15 key-value pairs")
|
precondition(pairs.count < 16, "fix maps cannot contain more than 15 key-value pairs")
|
||||||
data.append( UInt8(pairs.count) | FormatID.fixMap.rawValue)
|
data.append( UInt8(pairs.count) | FormatID.fixMapStart.rawValue)
|
||||||
for (key, value) in pairs {
|
for (key, value) in pairs {
|
||||||
key.appendTo(data: &data)
|
key.appendTo(data: &data)
|
||||||
value.appendTo(data: &data)
|
value.appendTo(data: &data)
|
||||||
|
|
@ -321,3 +327,44 @@ extension Format {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Format {
|
||||||
|
static func string(from data: inout Data, offset: Int = 0) throws -> String {
|
||||||
|
switch data[offset] {
|
||||||
|
case FormatID.fixStringStart.rawValue ... FormatID.fixStringEnd.rawValue:
|
||||||
|
let length = Int(data[offset] & 0b00011111)
|
||||||
|
guard let string = data.withUnsafeMutableBytes({
|
||||||
|
String(bytesNoCopy: $0.advanced(by: offset + 1), length: length, encoding: .utf8, freeWhenDone: false)
|
||||||
|
}) else {
|
||||||
|
throw DecodingError.dataCorrupted(.init(codingPath: [], debugDescription: "not a valid string"))
|
||||||
|
}
|
||||||
|
return string
|
||||||
|
case FormatID.string8.rawValue:
|
||||||
|
let length = Int(data[offset + 1])
|
||||||
|
guard let string = data.withUnsafeMutableBytes({
|
||||||
|
String(bytesNoCopy: $0.advanced(by: offset + 2), length: length, encoding: .utf8, freeWhenDone: false)
|
||||||
|
}) else {
|
||||||
|
throw DecodingError.dataCorrupted(.init(codingPath: [], debugDescription: "not a valid string"))
|
||||||
|
}
|
||||||
|
return string
|
||||||
|
case FormatID.string16.rawValue:
|
||||||
|
let length = Int(data.bigEndianInteger(at: offset) as UInt16)
|
||||||
|
guard let string = data.withUnsafeMutableBytes({
|
||||||
|
String(bytesNoCopy: $0.advanced(by: offset + 3), length: length, encoding: .utf8, freeWhenDone: false)
|
||||||
|
}) else {
|
||||||
|
throw DecodingError.dataCorrupted(.init(codingPath: [], debugDescription: "not a valid string"))
|
||||||
|
}
|
||||||
|
return string
|
||||||
|
case FormatID.string32.rawValue:
|
||||||
|
let length = Int(data.bigEndianInteger(at: offset) as UInt16)
|
||||||
|
guard let string = data.withUnsafeMutableBytes({
|
||||||
|
String(bytesNoCopy: $0.advanced(by: offset + 5), length: length, encoding: .utf8, freeWhenDone: false)
|
||||||
|
}) else {
|
||||||
|
throw DecodingError.dataCorrupted(.init(codingPath: [], debugDescription: "not a valid string"))
|
||||||
|
}
|
||||||
|
return string
|
||||||
|
default:
|
||||||
|
throw DecodingError.typeMismatch(String.self, .init(codingPath: [], debugDescription: "Wrong string format: \(data[offset])"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,5 +44,4 @@ func roundtrip<T: Codable>(value: T) throws -> T {
|
||||||
return try decoder.decode(T.self, from: encoder.encode(value))
|
return try decoder.decode(T.self, from: encoder.encode(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
var x: UInt64? = nil
|
try roundtrip(value: "Hello")
|
||||||
try roundtrip(value: false)
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue