Encode strings

This commit is contained in:
Damiaan Dufaux 2017-07-31 20:31:37 +02:00
parent 112d35f359
commit 43dff2cc5b
3 changed files with 64 additions and 30 deletions

View file

@ -16,7 +16,7 @@ public class Encoder {
public func encode<T : Encodable>(_ value: T) throws -> Data {
try value.encode(to: serialiser)
var data = Data()
serialiser.storage?.appendTo(data: &data)
try serialiser.storage?.appendTo(data: &data)
return data
}
}
@ -42,7 +42,7 @@ class Serialiser: Swift.Encoder {
extension MsgPack.Serialiser: SingleValueEncodingContainer {
enum Error: Swift.Error {
case notImplemented
case notImplemented, stringNotConvertibleToUTF8
}
func encodeNil() throws {
@ -54,7 +54,11 @@ extension MsgPack.Serialiser: SingleValueEncodingContainer {
}
func encode(_ value: Int) throws {
storage = .int(value)
#if arch(arm) || arch(i386)
storage = .int32(Int32(value))
#else
storage = .int64(Int64(value))
#endif
}
func encode(_ value: Int8) throws {
@ -74,7 +78,11 @@ extension MsgPack.Serialiser: SingleValueEncodingContainer {
}
func encode(_ value: UInt) throws {
storage = .uInt(value)
#if arch(arm) || arch(i386)
storage = .uInt32(UInt32(value))
#else
storage = .uInt64(UInt64(value))
#endif
}
func encode(_ value: UInt8) throws {
@ -102,7 +110,17 @@ extension MsgPack.Serialiser: SingleValueEncodingContainer {
}
func encode(_ value: String) throws {
throw Error.notImplemented
guard let data = value.data(using: .utf8) else {throw Error.stringNotConvertibleToUTF8}
switch data.count {
case 1..<32:
storage = .fixString(data)
case 32..<256:
storage = .string8(data)
case 256..<65536:
storage = .string16(data)
default:
storage = .string32(data)
}
}
func encode<T : Encodable>(_ value: T) throws {

View file

@ -10,7 +10,7 @@ import Foundation
import Foundation
enum Format {
enum Format {
case `nil`
case boolean(Bool)
@ -18,13 +18,11 @@ enum Format {
case positiveInt7(UInt8)
case negativeInt5(UInt8)
case uInt (UInt)
case uInt8 (UInt8)
case uInt16(UInt16)
case uInt32(UInt32)
case uInt64(UInt64)
case int (Int)
case int8 (Int8)
case int16(Int16)
case int32(Int32)
@ -32,6 +30,11 @@ enum Format {
case float32(Float)
case float64(Double)
case fixString(Data)
case string8(Data)
case string16(Data)
case string32(Data)
func appendTo(data: inout Data) {
switch self {
@ -81,12 +84,6 @@ enum Format {
}
})
data.append(newData)
case .uInt(let value):
#if arch(arm) || arch(i386)
Format.uInt32(UInt32(value)).appendTo(data: &data)
#else
Format.uInt64(UInt64(value)).appendTo(data: &data)
#endif
// MARK: Signed integers
case .int8(let value):
@ -125,12 +122,6 @@ enum Format {
}
})
data.append(newData)
case .int(let value):
#if arch(arm) || arch(i386)
Format.int32(Int32(value)).appendTo(data: &data)
#else
Format.int64(Int64(value)).appendTo(data: &data)
#endif
// MARK: Floats
case .float32(let value):
@ -151,6 +142,34 @@ enum Format {
}
})
data.append(newData)
// MARK: Strings
case .fixString(let value):
data.append(UInt8(value.count) & 0b00011111 | 0b10100000)
data.append(value)
case .string8(let value):
data.append(contentsOf: [0xD9, UInt8(value.count)])
data.append(value)
case .string16(let value):
var prefix = Data(count: 3)
prefix.withUnsafeMutableBytes({ (byteContainer: UnsafeMutablePointer<UInt8>) -> Void in
byteContainer.pointee = 0xDA
byteContainer.advanced(by: 1).withMemoryRebound(to: UInt16.self, capacity: 1) {
$0.pointee = UInt16(value.count).bigEndian
}
})
data.append(prefix)
data.append(value)
case .string32(let value):
var prefix = Data(count: 5)
prefix.withUnsafeMutableBytes({ (byteContainer: UnsafeMutablePointer<UInt8>) -> Void in
byteContainer.pointee = 0xDB
byteContainer.advanced(by: 1).withMemoryRebound(to: UInt32.self, capacity: 1) {
$0.pointee = UInt32(value.count).bigEndian
}
})
data.append(prefix)
data.append(value)
}
}
}

View file

@ -6,7 +6,6 @@ import Foundation
let encoder = Encoder()
let integerData = try encoder.encode(0x0102030405060708)
String(integerData[0], radix: 16)
integerData[1]
@ -18,13 +17,11 @@ integerData[6]
integerData[7]
integerData[8]
let doubleData = try encoder.encode(2.5)
let doubleData = try encoder.encode("Hello there 123456789012345678901")
String(doubleData[0], radix: 16)
doubleData[1]
doubleData[2]
doubleData[3]
doubleData[4]
doubleData[5]
doubleData[6]
doubleData[7]
doubleData[8]
String(doubleData[1], radix: 16)
String(doubleData[2], radix: 16)
String(doubleData[3], radix: 16)
String(doubleData[4], radix: 16)
String(doubleData[5], radix: 16)