mirror of
https://github.com/Dev1an/MsgPack.git
synced 2026-03-25 08:45:55 +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 {
|
||||
fatalError("not implemented")
|
||||
return try Format.string(from: &decoder.storage)
|
||||
}
|
||||
|
||||
func decode<T>(_ type: T.Type) throws -> T where T : Decodable {
|
||||
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 {
|
||||
case notImplemented, stringNotConvertibleToUTF8(String), valueDidNotAskForContainer
|
||||
case stringNotConvertibleToUTF8(String), valueDidNotAskForContainer
|
||||
}
|
||||
|
||||
class IntermediateEncoder: Swift.Encoder {
|
||||
|
|
@ -159,7 +159,7 @@ class MsgPackSingleValueEncodingContainer: MessagePackEncodingContainer, SingleV
|
|||
}
|
||||
|
||||
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 {
|
||||
preconditionFailure("not implemented")
|
||||
fatalError("not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,9 +63,12 @@ public enum FormatID: UInt8 {
|
|||
case float32
|
||||
case float64
|
||||
|
||||
case positiveInt7 = 0
|
||||
case negativeInt5 = 0b11100000
|
||||
case firstPositiveInt7 = 0b00000000
|
||||
case lastPositiveInt7 = 0b01111111
|
||||
|
||||
case firstNegativeInt5 = 0b11100000
|
||||
case lastNegativeInt5 = 0b11111111
|
||||
|
||||
case uInt8 = 0xCC
|
||||
case uInt16
|
||||
case uInt32
|
||||
|
|
@ -82,16 +85,19 @@ public enum FormatID: UInt8 {
|
|||
case fixExt8
|
||||
case fixExt16
|
||||
|
||||
case fixString = 0b10100000
|
||||
case fixStringStart = 0b10100000
|
||||
case fixStringEnd = 0b10111111
|
||||
case string8 = 0xD9
|
||||
case string16
|
||||
case string32
|
||||
|
||||
case fixArray = 0b10010000
|
||||
case fixArrayStart = 0b10010000
|
||||
case fixArrayEnd = 0b10011111
|
||||
case array16 = 0xDC
|
||||
case array32
|
||||
|
||||
case fixMap = 0b10000000
|
||||
case fixMapStart = 0b10000000
|
||||
case fixMapEnd = 0b10001111
|
||||
case map16 = 0xDE
|
||||
case map32
|
||||
}
|
||||
|
|
@ -110,9 +116,9 @@ extension Format {
|
|||
|
||||
// MARK: Small integers (< 8 bit)
|
||||
case .positiveInt7(let value):
|
||||
data.append(value | FormatID.positiveInt7.rawValue)
|
||||
data.append(value | FormatID.firstPositiveInt7.rawValue)
|
||||
case .negativeInt5(let value):
|
||||
data.append(value | FormatID.negativeInt5.rawValue)
|
||||
data.append(value | FormatID.firstNegativeInt5.rawValue)
|
||||
|
||||
// MARK: Unsigned integers
|
||||
case .uInt8(let value):
|
||||
|
|
@ -173,7 +179,7 @@ extension Format {
|
|||
// MARK: Strings
|
||||
case .fixString(let utf8Data):
|
||||
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)
|
||||
case .string8(let utf8Data):
|
||||
data.append(contentsOf: [FormatID.string8.rawValue, UInt8(utf8Data.count)])
|
||||
|
|
@ -194,7 +200,7 @@ extension Format {
|
|||
// MARK: Arrays
|
||||
case .fixArray(let array):
|
||||
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 {
|
||||
element.appendTo(data: &data)
|
||||
}
|
||||
|
|
@ -218,7 +224,7 @@ extension Format {
|
|||
// MARK: Maps
|
||||
case .fixMap(let 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 {
|
||||
key.appendTo(data: &data)
|
||||
value.appendTo(data: &data)
|
||||
|
|
@ -321,3 +327,44 @@ extension Format {
|
|||
#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))
|
||||
}
|
||||
|
||||
var x: UInt64? = nil
|
||||
try roundtrip(value: false)
|
||||
try roundtrip(value: "Hello")
|
||||
|
|
|
|||
Loading…
Reference in a new issue