gh-Dev1an-MsgPack/MsgPack/Format.swift
2017-07-31 20:31:37 +02:00

175 lines
5 KiB
Swift

//
// Formats.swift
// MsgPack
//
// Created by Damiaan on 30/07/17.
// Copyright © 2017 dPro. All rights reserved.
//
import Foundation
import Foundation
enum Format {
case `nil`
case boolean(Bool)
case positiveInt7(UInt8)
case negativeInt5(UInt8)
case uInt8 (UInt8)
case uInt16(UInt16)
case uInt32(UInt32)
case uInt64(UInt64)
case int8 (Int8)
case int16(Int16)
case int32(Int32)
case int64(Int64)
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 {
// MARK: Optional
case .nil:
data.append(0xC0)
// MARK: Boolean
case .boolean(let boolean):
data.append(boolean ? 0xC3 : 0xC2)
// MARK: Small integers (< 8 bit)
case .positiveInt7(let value):
data.append(value | 0b10000000)
case .negativeInt5(let value):
data.append(value | 0b11100000)
// MARK: Unsigned integers
case .uInt8(let value):
data.append(0xCC)
data.append(value)
case .uInt16(let value):
var newData = Data(count: 3)
newData.withUnsafeMutableBytes({ (byteContainer: UnsafeMutablePointer<UInt8>) -> Void in
byteContainer.pointee = 0xCD
byteContainer.advanced(by: 1).withMemoryRebound(to: UInt16.self, capacity: 1) {
$0.pointee = value.bigEndian
}
})
data.append(newData)
case .uInt32(let value):
var newData = Data(count: 5)
newData.withUnsafeMutableBytes({ (byteContainer: UnsafeMutablePointer<UInt8>) -> Void in
byteContainer.pointee = 0xCE
byteContainer.advanced(by: 1).withMemoryRebound(to: UInt32.self, capacity: 1) {
$0.pointee = value.bigEndian
}
})
data.append(newData)
case .uInt64(let value):
var newData = Data(count: 9)
newData.withUnsafeMutableBytes({ (byteContainer: UnsafeMutablePointer<UInt8>) -> Void in
byteContainer.pointee = 0xCF
byteContainer.advanced(by: 1).withMemoryRebound(to: UInt64.self, capacity: 1) {
$0.pointee = value.bigEndian
}
})
data.append(newData)
// 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)
// MARK: Floats
case .float32(let value):
var newData = Data(count: 5)
newData.withUnsafeMutableBytes({ (byteContainer: UnsafeMutablePointer<UInt8>) -> Void in
byteContainer.pointee = 0xCA
byteContainer.advanced(by: 1).withMemoryRebound(to: UInt32.self, capacity: 1) {
$0.pointee = value.bitPattern.bigEndian
}
})
data.append(newData)
case .float64(let value):
var newData = Data(count: 9)
newData.withUnsafeMutableBytes({ (byteContainer: UnsafeMutablePointer<UInt8>) -> Void in
byteContainer.pointee = 0xCB
byteContainer.advanced(by: 1).withMemoryRebound(to: UInt64.self, capacity: 1) {
$0.pointee = value.bitPattern.bigEndian
}
})
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)
}
}
}