mirror of
https://github.com/Dev1an/MsgPack.git
synced 2026-04-27 14:57:46 +00:00
Decode integers
This commit is contained in:
parent
9c06dd51a8
commit
1255f3c3a7
5 changed files with 256 additions and 60 deletions
|
|
@ -12,7 +12,7 @@
|
||||||
74FA3B501F2C9060005CE521 /* MsgPack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 74FA3B461F2C9060005CE521 /* MsgPack.framework */; };
|
74FA3B501F2C9060005CE521 /* MsgPack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 74FA3B461F2C9060005CE521 /* MsgPack.framework */; };
|
||||||
74FA3B551F2C9060005CE521 /* MsgPackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74FA3B541F2C9060005CE521 /* MsgPackTests.swift */; };
|
74FA3B551F2C9060005CE521 /* MsgPackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74FA3B541F2C9060005CE521 /* MsgPackTests.swift */; };
|
||||||
74FA3B571F2C9060005CE521 /* MsgPack.h in Headers */ = {isa = PBXBuildFile; fileRef = 74FA3B491F2C9060005CE521 /* MsgPack.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
74FA3B571F2C9060005CE521 /* MsgPack.h in Headers */ = {isa = PBXBuildFile; fileRef = 74FA3B491F2C9060005CE521 /* MsgPack.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
74FA3B611F2C908D005CE521 /* DecoderHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74FA3B601F2C908D005CE521 /* DecoderHelper.swift */; };
|
74FA3B611F2C908D005CE521 /* Decoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74FA3B601F2C908D005CE521 /* Decoder.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
74FA3B4F1F2C9060005CE521 /* MsgPackTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MsgPackTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
74FA3B4F1F2C9060005CE521 /* MsgPackTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MsgPackTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
74FA3B541F2C9060005CE521 /* MsgPackTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MsgPackTests.swift; sourceTree = "<group>"; };
|
74FA3B541F2C9060005CE521 /* MsgPackTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MsgPackTests.swift; sourceTree = "<group>"; };
|
||||||
74FA3B561F2C9060005CE521 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
74FA3B561F2C9060005CE521 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
74FA3B601F2C908D005CE521 /* DecoderHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecoderHelper.swift; sourceTree = "<group>"; };
|
74FA3B601F2C908D005CE521 /* Decoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Decoder.swift; sourceTree = "<group>"; };
|
||||||
74FA3B621F2C9096005CE521 /* Encoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Encoder.swift; sourceTree = "<group>"; };
|
74FA3B621F2C9096005CE521 /* Encoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Encoder.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
|
@ -79,7 +79,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
74FA3B491F2C9060005CE521 /* MsgPack.h */,
|
74FA3B491F2C9060005CE521 /* MsgPack.h */,
|
||||||
74FA3B601F2C908D005CE521 /* DecoderHelper.swift */,
|
74FA3B601F2C908D005CE521 /* Decoder.swift */,
|
||||||
74FA3B621F2C9096005CE521 /* Encoder.swift */,
|
74FA3B621F2C9096005CE521 /* Encoder.swift */,
|
||||||
74A1AE161F2E3E8300B139A3 /* Format.swift */,
|
74A1AE161F2E3E8300B139A3 /* Format.swift */,
|
||||||
74FA3B4A1F2C9060005CE521 /* Info.plist */,
|
74FA3B4A1F2C9060005CE521 /* Info.plist */,
|
||||||
|
|
@ -208,7 +208,7 @@
|
||||||
files = (
|
files = (
|
||||||
7495EA251F30B393000EBDF6 /* Encoder.swift in Sources */,
|
7495EA251F30B393000EBDF6 /* Encoder.swift in Sources */,
|
||||||
74A1AE171F2E3E8300B139A3 /* Format.swift in Sources */,
|
74A1AE171F2E3E8300B139A3 /* Format.swift in Sources */,
|
||||||
74FA3B611F2C908D005CE521 /* DecoderHelper.swift in Sources */,
|
74FA3B611F2C908D005CE521 /* Decoder.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
156
MsgPack/Decoder.swift
Normal file
156
MsgPack/Decoder.swift
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
//
|
||||||
|
// Decoder.swift
|
||||||
|
// MsgPack
|
||||||
|
//
|
||||||
|
// Created by Damiaan on 29/07/17.
|
||||||
|
// Copyright © 2017 dPro. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class Decoder {
|
||||||
|
public func decode<T : Decodable>(_ type: T.Type, from data: Data) throws -> T {
|
||||||
|
let decoder = IntermediateDecoder(with: data)
|
||||||
|
return try T(from: decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IntermediateDecoder: Swift.Decoder {
|
||||||
|
var codingPath = [CodingKey]()
|
||||||
|
|
||||||
|
var userInfo = [CodingUserInfoKey : Any]()
|
||||||
|
|
||||||
|
var storage: Data
|
||||||
|
var offset = 0
|
||||||
|
|
||||||
|
init(with data: Data) {
|
||||||
|
storage = data
|
||||||
|
}
|
||||||
|
|
||||||
|
func container<Key>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key> where Key : CodingKey {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
|
||||||
|
func unkeyedContainer() throws -> UnkeyedDecodingContainer {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
|
||||||
|
func singleValueContainer() throws -> SingleValueDecodingContainer {
|
||||||
|
return MsgPckSingleValueDecodingContainer(refferingTo: self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MsgPckSingleValueDecodingContainer: SingleValueDecodingContainer {
|
||||||
|
var codingPath = [CodingKey]()
|
||||||
|
var decoder: IntermediateDecoder
|
||||||
|
var base = 0
|
||||||
|
|
||||||
|
enum Error: Swift.Error {
|
||||||
|
case invalidFormat(UInt8)
|
||||||
|
}
|
||||||
|
|
||||||
|
init(refferingTo decoder: IntermediateDecoder) {
|
||||||
|
self.decoder = decoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeNil() -> Bool {
|
||||||
|
return decoder.storage[base] == FormatID.nil.rawValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Bool.Type) throws -> Bool {
|
||||||
|
let byte = decoder.storage[base]
|
||||||
|
guard byte & 0b11111110 == FormatID.false.rawValue else {
|
||||||
|
throw Error.invalidFormat(byte)
|
||||||
|
}
|
||||||
|
return byte == FormatID.true.rawValue
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Int.Type) throws -> Int {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Int8.Type) throws -> Int8 {
|
||||||
|
guard decoder.storage[base] == FormatID.int8.rawValue else {
|
||||||
|
throw Error.invalidFormat(decoder.storage[base])
|
||||||
|
}
|
||||||
|
return decoder.storage.read(at: base+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Int16.Type) throws -> Int16 {
|
||||||
|
guard decoder.storage[base] == FormatID.int16.rawValue else {
|
||||||
|
throw Error.invalidFormat(decoder.storage[base])
|
||||||
|
}
|
||||||
|
return decoder.storage.bigEndianInteger(at: base+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Int32.Type) throws -> Int32 {
|
||||||
|
guard decoder.storage[base] == FormatID.int32.rawValue else {
|
||||||
|
throw Error.invalidFormat(decoder.storage[base])
|
||||||
|
}
|
||||||
|
return decoder.storage.bigEndianInteger(at: base+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Int64.Type) throws -> Int64 {
|
||||||
|
guard decoder.storage[base] == FormatID.int64.rawValue else {
|
||||||
|
throw Error.invalidFormat(decoder.storage[base])
|
||||||
|
}
|
||||||
|
return decoder.storage.bigEndianInteger(at: base+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: UInt.Type) throws -> UInt {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: UInt8.Type) throws -> UInt8 {
|
||||||
|
guard decoder.storage[base] == FormatID.uInt8.rawValue else {
|
||||||
|
throw Error.invalidFormat(decoder.storage[base])
|
||||||
|
}
|
||||||
|
return decoder.storage.read(at: base+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: UInt16.Type) throws -> UInt16 {
|
||||||
|
guard decoder.storage[base] == FormatID.uInt16.rawValue else {
|
||||||
|
throw Error.invalidFormat(decoder.storage[base])
|
||||||
|
}
|
||||||
|
return decoder.storage.bigEndianInteger(at: base+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: UInt32.Type) throws -> UInt32 {
|
||||||
|
guard decoder.storage[base] == FormatID.uInt32.rawValue else {
|
||||||
|
throw Error.invalidFormat(decoder.storage[base])
|
||||||
|
}
|
||||||
|
return decoder.storage.bigEndianInteger(at: base+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: UInt64.Type) throws -> UInt64 {
|
||||||
|
guard decoder.storage[base] == FormatID.uInt64.rawValue else {
|
||||||
|
throw Error.invalidFormat(decoder.storage[base])
|
||||||
|
}
|
||||||
|
return decoder.storage.bigEndianInteger(at: base+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Float.Type) throws -> Float {
|
||||||
|
guard decoder.storage[base] == FormatID.float32.rawValue else {
|
||||||
|
throw Error.invalidFormat(decoder.storage[base])
|
||||||
|
}
|
||||||
|
return decoder.storage.read(at: base + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: Double.Type) throws -> Double {
|
||||||
|
guard decoder.storage[base] == FormatID.float64.rawValue else {
|
||||||
|
throw Error.invalidFormat(decoder.storage[base])
|
||||||
|
}
|
||||||
|
let bitPattern: UInt64 = decoder.storage.read(at: base + 1)
|
||||||
|
return .init(bitPattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(_ type: String.Type) throws -> String {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode<T>(_ type: T.Type) throws -> T where T : Decodable {
|
||||||
|
fatalError("not implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
//
|
|
||||||
// Decoder.swift
|
|
||||||
// MsgPack
|
|
||||||
//
|
|
||||||
// Created by Damiaan on 29/07/17.
|
|
||||||
// Copyright © 2017 dPro. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
//class MessagePackDecoder: Decoder {
|
|
||||||
// var codingPath = [CodingKey?]()
|
|
||||||
//
|
|
||||||
// var userInfo = [CodingUserInfoKey : Any]()
|
|
||||||
//
|
|
||||||
// func container<Key>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key> where Key : CodingKey {
|
|
||||||
// <#code#>
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func unkeyedContainer() throws -> UnkeyedDecodingContainer {
|
|
||||||
// <#code#>
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// func singleValueContainer() throws -> SingleValueDecodingContainer {
|
|
||||||
// <#code#>
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ enum Format {
|
||||||
case `nil`
|
case `nil`
|
||||||
|
|
||||||
case boolean(Bool)
|
case boolean(Bool)
|
||||||
|
|
||||||
case positiveInt7(UInt8)
|
case positiveInt7(UInt8)
|
||||||
case negativeInt5(UInt8)
|
case negativeInt5(UInt8)
|
||||||
|
|
||||||
|
|
@ -45,6 +45,56 @@ enum Format {
|
||||||
case map32 ([(key: Format, value: Format)])
|
case map32 ([(key: Format, value: Format)])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum FormatID: UInt8 {
|
||||||
|
// Do not reorder the cases because their raw values are infered based on the ordering
|
||||||
|
case `nil` = 0xC0
|
||||||
|
|
||||||
|
case `false` = 0xC2
|
||||||
|
case `true`
|
||||||
|
|
||||||
|
case bin8
|
||||||
|
case bin16
|
||||||
|
case bin32
|
||||||
|
|
||||||
|
case ext8
|
||||||
|
case ext16
|
||||||
|
case ext32
|
||||||
|
|
||||||
|
case float32
|
||||||
|
case float64
|
||||||
|
|
||||||
|
case positiveInt7 = 0
|
||||||
|
case negativeInt5 = 0b11100000
|
||||||
|
|
||||||
|
case uInt8 = 0xCC
|
||||||
|
case uInt16
|
||||||
|
case uInt32
|
||||||
|
case uInt64
|
||||||
|
|
||||||
|
case int8
|
||||||
|
case int16
|
||||||
|
case int32
|
||||||
|
case int64
|
||||||
|
|
||||||
|
case fixExt1
|
||||||
|
case fixExt2
|
||||||
|
case fixExt4
|
||||||
|
case fixExt8
|
||||||
|
case fixExt16
|
||||||
|
|
||||||
|
case fixString = 0b10100000
|
||||||
|
case string8 = 0xD9
|
||||||
|
case string16
|
||||||
|
case string32
|
||||||
|
|
||||||
|
case fixArray = 0b10010000
|
||||||
|
case array16 = 0xDC
|
||||||
|
case array32
|
||||||
|
|
||||||
|
case fixMap = 0b10000000
|
||||||
|
case map16 = 0xDE
|
||||||
|
case map32
|
||||||
|
}
|
||||||
|
|
||||||
extension Format {
|
extension Format {
|
||||||
func appendTo(data: inout Data) {
|
func appendTo(data: inout Data) {
|
||||||
|
|
@ -52,89 +102,91 @@ extension Format {
|
||||||
|
|
||||||
// MARK: Optional
|
// MARK: Optional
|
||||||
case .nil:
|
case .nil:
|
||||||
data.append(0xC0)
|
data.append(FormatID.nil.rawValue)
|
||||||
|
|
||||||
// MARK: Boolean
|
// MARK: Boolean
|
||||||
case .boolean(let boolean):
|
case .boolean(let boolean):
|
||||||
data.append(boolean ? 0xC3 : 0xC2)
|
data.append(boolean ? FormatID.true.rawValue : FormatID.false.rawValue)
|
||||||
|
|
||||||
// MARK: Small integers (< 8 bit)
|
// MARK: Small integers (< 8 bit)
|
||||||
case .positiveInt7(let value):
|
case .positiveInt7(let value):
|
||||||
data.append(value | 0b10000000)
|
data.append(value | FormatID.positiveInt7.rawValue)
|
||||||
case .negativeInt5(let value):
|
case .negativeInt5(let value):
|
||||||
data.append(value | 0b11100000)
|
data.append(value | FormatID.negativeInt5.rawValue)
|
||||||
|
|
||||||
// MARK: Unsigned integers
|
// MARK: Unsigned integers
|
||||||
case .uInt8(let value):
|
case .uInt8(let value):
|
||||||
data.append(0xCC)
|
data.append(contentsOf: [
|
||||||
data.append(value)
|
FormatID.uInt8.rawValue,
|
||||||
|
value
|
||||||
|
])
|
||||||
case .uInt16(let value):
|
case .uInt16(let value):
|
||||||
var newData = Data(count: 3)
|
var newData = Data(count: 3)
|
||||||
newData[0] = 0xCD
|
newData[0] = FormatID.uInt16.rawValue
|
||||||
newData.write(value: value.bigEndian, offset: 1)
|
newData.write(value: value.bigEndian, offset: 1)
|
||||||
data.append(newData)
|
data.append(newData)
|
||||||
case .uInt32(let value):
|
case .uInt32(let value):
|
||||||
var newData = Data(count: 5)
|
var newData = Data(count: 5)
|
||||||
newData[0] = 0xCE
|
newData[0] = FormatID.uInt32.rawValue
|
||||||
newData.write(value: value.bigEndian, offset: 1)
|
newData.write(value: value.bigEndian, offset: 1)
|
||||||
data.append(newData)
|
data.append(newData)
|
||||||
case .uInt64(let value):
|
case .uInt64(let value):
|
||||||
var newData = Data(count: 9)
|
var newData = Data(count: 9)
|
||||||
newData[0] = 0xCF
|
newData[0] = FormatID.uInt64.rawValue
|
||||||
newData.write(value: value.bigEndian, offset: 1)
|
newData.write(value: value.bigEndian, offset: 1)
|
||||||
data.append(newData)
|
data.append(newData)
|
||||||
|
|
||||||
// MARK: Signed integers
|
// MARK: Signed integers
|
||||||
case .int8(let value):
|
case .int8(let value):
|
||||||
var newData = Data(count: 2)
|
var newData = Data(count: 2)
|
||||||
newData[0] = 0xD0
|
newData[0] = FormatID.int8.rawValue
|
||||||
newData.write(value: value.bigEndian, offset: 1)
|
newData.write(value: value.bigEndian, offset: 1)
|
||||||
data.append(newData)
|
data.append(newData)
|
||||||
case .int16(let value):
|
case .int16(let value):
|
||||||
var newData = Data(count: 3)
|
var newData = Data(count: 3)
|
||||||
newData[0] = 0xD1
|
newData[0] = FormatID.int16.rawValue
|
||||||
newData.write(value: value.bigEndian, offset: 1)
|
newData.write(value: value.bigEndian, offset: 1)
|
||||||
data.append(newData)
|
data.append(newData)
|
||||||
case .int32(let value):
|
case .int32(let value):
|
||||||
var newData = Data(count: 5)
|
var newData = Data(count: 5)
|
||||||
newData[0] = 0xD2
|
newData[0] = FormatID.int32.rawValue
|
||||||
newData.write(value: value.bigEndian, offset: 1)
|
newData.write(value: value.bigEndian, offset: 1)
|
||||||
data.append(newData)
|
data.append(newData)
|
||||||
case .int64(let value):
|
case .int64(let value):
|
||||||
var newData = Data(count: 9)
|
var newData = Data(count: 9)
|
||||||
newData[0] = 0xD3
|
newData[0] = FormatID.int64.rawValue
|
||||||
newData.write(value: value.bigEndian, offset: 1)
|
newData.write(value: value.bigEndian, offset: 1)
|
||||||
data.append(newData)
|
data.append(newData)
|
||||||
|
|
||||||
// MARK: Floats
|
// MARK: Floats
|
||||||
case .float32(let value):
|
case .float32(let value):
|
||||||
var newData = Data(count: 5)
|
var newData = Data(count: 5)
|
||||||
newData[0] = 0xCA
|
newData[0] = FormatID.float32.rawValue
|
||||||
newData.write(value: value.bitPattern.bigEndian, offset: 1)
|
newData.write(value: value.bitPattern.bigEndian, offset: 1)
|
||||||
data.append(newData)
|
data.append(newData)
|
||||||
case .float64(let value):
|
case .float64(let value):
|
||||||
var newData = Data(count: 9)
|
var newData = Data(count: 9)
|
||||||
newData[0] = 0xCB
|
newData[0] = FormatID.float64.rawValue
|
||||||
newData.write(value: value.bitPattern.bigEndian, offset: 1)
|
newData.write(value: value.bitPattern.bigEndian, offset: 1)
|
||||||
data.append(newData)
|
data.append(newData)
|
||||||
|
|
||||||
// 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) | 0b10100000)
|
data.append( UInt8(utf8Data.count) | FormatID.fixString.rawValue)
|
||||||
data.append(utf8Data)
|
data.append(utf8Data)
|
||||||
case .string8(let utf8Data):
|
case .string8(let utf8Data):
|
||||||
data.append(contentsOf: [0xD9, UInt8(utf8Data.count)])
|
data.append(contentsOf: [FormatID.string8.rawValue, UInt8(utf8Data.count)])
|
||||||
data.append(utf8Data)
|
data.append(utf8Data)
|
||||||
case .string16(let utf8Data):
|
case .string16(let utf8Data):
|
||||||
var prefix = Data(count: 3)
|
var prefix = Data(count: 3)
|
||||||
prefix[0] = 0xDA
|
prefix[0] = FormatID.string16.rawValue
|
||||||
prefix.write(value: UInt16(utf8Data.count).bigEndian, offset: 1)
|
prefix.write(value: UInt16(utf8Data.count).bigEndian, offset: 1)
|
||||||
data.append(prefix)
|
data.append(prefix)
|
||||||
data.append(utf8Data)
|
data.append(utf8Data)
|
||||||
case .string32(let utf8Data):
|
case .string32(let utf8Data):
|
||||||
var prefix = Data(count: 5)
|
var prefix = Data(count: 5)
|
||||||
prefix[0] = 0xDB
|
prefix[0] = FormatID.string32.rawValue
|
||||||
prefix.write(value: UInt32(utf8Data.count).bigEndian, offset: 1)
|
prefix.write(value: UInt32(utf8Data.count).bigEndian, offset: 1)
|
||||||
data.append(prefix)
|
data.append(prefix)
|
||||||
data.append(utf8Data)
|
data.append(utf8Data)
|
||||||
|
|
@ -142,13 +194,13 @@ 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) | 0b10010000)
|
data.append( UInt8(array.count) | FormatID.fixArray.rawValue)
|
||||||
for element in array {
|
for element in array {
|
||||||
element.appendTo(data: &data)
|
element.appendTo(data: &data)
|
||||||
}
|
}
|
||||||
case .array16(let array):
|
case .array16(let array):
|
||||||
var prefix = Data(count: 3)
|
var prefix = Data(count: 3)
|
||||||
prefix[0] = 0xDC
|
prefix[0] = FormatID.array16.rawValue
|
||||||
prefix.write(value: UInt16(array.count).bigEndian, offset: 1)
|
prefix.write(value: UInt16(array.count).bigEndian, offset: 1)
|
||||||
data.append(prefix)
|
data.append(prefix)
|
||||||
for element in array {
|
for element in array {
|
||||||
|
|
@ -156,7 +208,7 @@ extension Format {
|
||||||
}
|
}
|
||||||
case .array32(let array):
|
case .array32(let array):
|
||||||
var prefix = Data(count: 5)
|
var prefix = Data(count: 5)
|
||||||
prefix[0] = 0xDD
|
prefix[0] = FormatID.array32.rawValue
|
||||||
prefix.write(value: UInt32(array.count).bigEndian, offset: 1)
|
prefix.write(value: UInt32(array.count).bigEndian, offset: 1)
|
||||||
data.append(prefix)
|
data.append(prefix)
|
||||||
for element in array {
|
for element in array {
|
||||||
|
|
@ -166,14 +218,14 @@ 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) | 0b10000000)
|
data.append( UInt8(pairs.count) | FormatID.fixMap.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)
|
||||||
}
|
}
|
||||||
case .map16(let pairs):
|
case .map16(let pairs):
|
||||||
var prefix = Data(count: 3)
|
var prefix = Data(count: 3)
|
||||||
prefix[0] = 0xDE
|
prefix[0] = FormatID.map16.rawValue
|
||||||
prefix.write(value: UInt16(pairs.count).bigEndian, offset: 1)
|
prefix.write(value: UInt16(pairs.count).bigEndian, offset: 1)
|
||||||
data.append(prefix)
|
data.append(prefix)
|
||||||
for (key, value) in pairs {
|
for (key, value) in pairs {
|
||||||
|
|
@ -182,7 +234,7 @@ extension Format {
|
||||||
}
|
}
|
||||||
case .map32(let pairs):
|
case .map32(let pairs):
|
||||||
var prefix = Data(count: 5)
|
var prefix = Data(count: 5)
|
||||||
prefix[0] = 0xDE
|
prefix[0] = FormatID.map32.rawValue
|
||||||
prefix.write(value: UInt32(pairs.count).bigEndian, offset: 1)
|
prefix.write(value: UInt32(pairs.count).bigEndian, offset: 1)
|
||||||
data.append(prefix)
|
data.append(prefix)
|
||||||
for (key, value) in pairs {
|
for (key, value) in pairs {
|
||||||
|
|
@ -201,8 +253,21 @@ extension Data {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func read<T>(at offset: Int) -> T {
|
||||||
|
return withUnsafeBytes {(byteContainer: UnsafePointer<UInt8>) -> T in
|
||||||
|
byteContainer.advanced(by: offset).withMemoryRebound(to: T.self, capacity: 1) {$0.pointee}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func bigEndianInteger<T: FixedWidthInteger>(at offset: Int) -> T {
|
||||||
|
return withUnsafeBytes {(byteContainer: UnsafePointer<UInt8>) -> T in
|
||||||
|
byteContainer.advanced(by: offset).withMemoryRebound(to: T.self, capacity: 1) {T.init(bigEndian: $0.pointee)}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: encoding helpers
|
||||||
extension Format {
|
extension Format {
|
||||||
static func from(string: String) throws -> Format {
|
static func from(string: String) throws -> Format {
|
||||||
guard let data = string.data(using: .utf8) else {throw MsgPackEncodingError.stringNotConvertibleToUTF8(string)}
|
guard let data = string.data(using: .utf8) else {throw MsgPackEncodingError.stringNotConvertibleToUTF8(string)}
|
||||||
|
|
|
||||||
|
|
@ -37,3 +37,8 @@ let encodedGraph = try encoder.encode(graph)
|
||||||
for byte in encodedGraph {
|
for byte in encodedGraph {
|
||||||
print(String(byte, radix:16))
|
print(String(byte, radix:16))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let decoder = Decoder()
|
||||||
|
|
||||||
|
let int8 = try encoder.encode(Int8(-57))
|
||||||
|
try decoder.decode(Int8.self, from: int8)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue