Encode signed Integers

This commit is contained in:
Damiaan Dufaux 2017-07-31 18:50:39 +02:00
parent 5eddff1fdc
commit afae5bb0bc
6 changed files with 110 additions and 25 deletions

View file

@ -353,7 +353,7 @@
DYLIB_CURRENT_VERSION = 1; DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath"; DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_VERSION = A; FRAMEWORK_VERSION = A;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = fast;
INFOPLIST_FILE = MsgPack/Info.plist; INFOPLIST_FILE = MsgPack/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";

View file

@ -16,6 +16,28 @@
<string>Local Baseline</string> <string>Local Baseline</string>
</dict> </dict>
</dict> </dict>
<key>testPerformanceOf1MilionUInt32Encodings()</key>
<dict>
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
<dict>
<key>baselineAverage</key>
<real>3.075</real>
<key>baselineIntegrationDisplayName</key>
<string>Local Baseline</string>
</dict>
</dict>
<key>testPerformanceOf1MilionUInt32EncodingsUsingClass()</key>
<dict>
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
<dict>
<key>baselineAverage</key>
<real>4.2</real>
<key>baselineIntegrationDisplayName</key>
<string>Local Baseline</string>
<key>maxPercentRelativeStandardDeviation</key>
<real>100</real>
</dict>
</dict>
</dict> </dict>
</dict> </dict>
</dict> </dict>

View file

@ -54,27 +54,27 @@ extension MsgPack.Serialiser: SingleValueEncodingContainer {
} }
func encode(_ value: Int) throws { func encode(_ value: Int) throws {
throw Error.notImplemented storage = .int(value)
} }
func encode(_ value: Int8) throws { func encode(_ value: Int8) throws {
throw Error.notImplemented storage = .int8(value)
} }
func encode(_ value: Int16) throws { func encode(_ value: Int16) throws {
throw Error.notImplemented storage = .int16(value)
} }
func encode(_ value: Int32) throws { func encode(_ value: Int32) throws {
throw Error.notImplemented storage = .int32(value)
} }
func encode(_ value: Int64) throws { func encode(_ value: Int64) throws {
throw Error.notImplemented storage = .int64(value)
} }
func encode(_ value: UInt) throws { func encode(_ value: UInt) throws {
throw Error.notImplemented storage = .uInt(value)
} }
func encode(_ value: UInt8) throws { func encode(_ value: UInt8) throws {

View file

@ -12,26 +12,42 @@ import Foundation
enum Format { enum Format {
case `nil` case `nil`
case boolean(Bool) case boolean(Bool)
case positiveInt7(UInt8) case positiveInt7(UInt8)
case negativeInt5(UInt8) case negativeInt5(UInt8)
case uInt(UInt)
case uInt8(UInt8) case uInt (UInt)
case uInt8 (UInt8)
case uInt16(UInt16) case uInt16(UInt16)
case uInt32(UInt32) case uInt32(UInt32)
case uInt64(UInt64) case uInt64(UInt64)
case int (Int)
case int8 (Int8)
case int16(Int16)
case int32(Int32)
case int64(Int64)
func appendTo(data: inout Data) { func appendTo(data: inout Data) {
switch self { switch self {
// MARK: Optional
case .nil: case .nil:
data.append(0xC0) data.append(0xC0)
// MARK: Boolean
case .boolean(let boolean): case .boolean(let boolean):
data.append(boolean ? 0xC3 : 0xC2) data.append(boolean ? 0xC3 : 0xC2)
// MARK: Small integers (< 8 bit)
case .positiveInt7(let value): case .positiveInt7(let value):
data.append(value | 0b10000000) data.append(value | 0b10000000)
case .negativeInt5(let value): case .negativeInt5(let value):
data.append(value | 0b11100000) data.append(value | 0b11100000)
// MARK: Unsigned integers
case .uInt8(let value): case .uInt8(let value):
data.append(0xCC) data.append(0xCC)
data.append(value) data.append(value)
@ -68,6 +84,50 @@ enum Format {
#else #else
Format.uInt64(UInt64(value)).appendTo(data: &data) Format.uInt64(UInt64(value)).appendTo(data: &data)
#endif #endif
// MARK: Signed integers
case .int8(let value):
var newData = Data(count: 2)
newData.withUnsafeMutableBytes({ (byteContainer: UnsafeMutablePointer<UInt8>) -> Void in
byteContainer.pointee = 0xD1
byteContainer.advanced(by: 1).withMemoryRebound(to: Int8.self, capacity: 1) {
$0.pointee = value.bigEndian
}
})
data.append(newData)
case .int16(let value):
var newData = Data(count: 3)
newData.withUnsafeMutableBytes({ (byteContainer: UnsafeMutablePointer<UInt8>) -> Void in
byteContainer.pointee = 0xD2
byteContainer.advanced(by: 1).withMemoryRebound(to: Int16.self, capacity: 1) {
$0.pointee = value.bigEndian
}
})
data.append(newData)
case .int32(let value):
var newData = Data(count: 5)
newData.withUnsafeMutableBytes({ (byteContainer: UnsafeMutablePointer<UInt8>) -> Void in
byteContainer.pointee = 0xD2
byteContainer.advanced(by: 1).withMemoryRebound(to: Int32.self, capacity: 1) {
$0.pointee = value.bigEndian
}
})
data.append(newData)
case .int64(let value):
var newData = Data(count: 9)
newData.withUnsafeMutableBytes({ (byteContainer: UnsafeMutablePointer<UInt8>) -> Void in
byteContainer.pointee = 0xD3
byteContainer.advanced(by: 1).withMemoryRebound(to: Int64.self, capacity: 1) {
$0.pointee = value.bigEndian
}
})
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
} }
} }
} }

View file

@ -100,11 +100,10 @@ class MsgPackTests: XCTestCase {
} }
} }
func testPerformanceOf1MilionUInt32Encodings() { func testPerformanceOf2MilionUInt32Encodings() {
var d = Data()
self.measure { self.measure {
for _ in 0 ..< 1000000 { for _ in 0 ..< 2000000 {
Format.uInt32(136315908).appendTo(data: &d) try! encoder.encode(UInt32(136315908))
} }
} }
} }

View file

@ -3,15 +3,19 @@
import MsgPack import MsgPack
import Foundation import Foundation
var number: UInt16? = 0x0906
let encoder = Encoder() let encoder = Encoder()
let data = try encoder.encode(number) let data = try encoder.encode(0x0102030405060708)
String(data[0], radix: 16)
data[1] data[1]
data[2] data[2]
data[3]
data[4]
data[5]
data[6]
data[7]
data[8]
number = nil try encoder.encode(Int8(6))[1]
let data2 = try encoder.encode(number)
data2[0]