├── .gitignore ├── LICENSE ├── Package.swift ├── README.md ├── Sources └── MessagePack │ ├── Codable │ ├── CodingKey+MessagePack.swift │ ├── Decoding │ │ ├── Decoder+Error.swift │ │ ├── Decoder.swift │ │ ├── KeyedDecodingContainer.swift │ │ ├── SingleValueDecodingContainer.swift │ │ └── UnkeyedDecodingContainer.swift │ └── Encoding │ │ ├── Encoder+Error.swift │ │ ├── Encoder.swift │ │ ├── KeyedEncodingContainer.swift │ │ ├── SingleValueEncodingContainer.swift │ │ └── UnkeyedEncodingContainer.swift │ ├── Error.swift │ ├── MessagePack+API.swift │ ├── MessagePack+Accessors.swift │ ├── MessagePack+Description.swift │ ├── MessagePack+Initializers.swift │ ├── MessagePack+Literal.swift │ ├── MessagePack.swift │ ├── MessagePackInitializable.swift │ ├── MessagePackReader.swift │ ├── MessagePackWriter.swift │ └── Timestamp.swift ├── Tests ├── Codable │ ├── KeyedDecodingContainer │ │ └── main.swift │ ├── KeyedEncodingContainer │ │ └── main.swift │ ├── MessagePackCoders │ │ └── main.swift │ ├── UnkeyedDecodingContainer │ │ └── main.swift │ └── UnkeyedEncodingContainer │ │ └── main.swift ├── Coding │ ├── Array │ │ └── main.swift │ ├── Binary │ │ └── main.swift │ ├── Bool │ │ └── main.swift │ ├── Decode │ │ └── main.swift │ ├── EncodeArray │ │ └── main.swift │ ├── Extended │ │ └── main.swift │ ├── Float │ │ └── main.swift │ ├── Init │ │ └── main.swift │ ├── InsufficientData │ │ └── main.swift │ ├── Integer │ │ └── main.swift │ ├── InvalidHeader │ │ └── main.swift │ ├── ManualHeaders │ │ └── main.swift │ ├── Map │ │ └── main.swift │ ├── Nil │ │ └── main.swift │ ├── String │ │ └── main.swift │ ├── StringEncoding │ │ └── main.swift │ └── Timestamp │ │ └── main.swift └── MessagePack │ ├── Accessors │ └── main.swift │ ├── ConvenienceInitializers │ └── main.swift │ ├── Description │ └── main.swift │ ├── Equality │ └── main.swift │ ├── HasValue │ └── main.swift │ ├── LiteralConvertible │ └── main.swift │ └── MessagePackInitializable │ └── main.swift └── run_tests /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /.swiftpm 4 | /Packages 5 | /*.xcodeproj 6 | /Package.resolved 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.9 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "MessagePack", 6 | platforms: [ 7 | .iOS(.v16), 8 | .macOS(.v13), 9 | ], 10 | products: [ 11 | .library( 12 | name: "MessagePack", 13 | targets: ["MessagePack"]), 14 | ], 15 | dependencies: [ 16 | .package(name: "Codable"), 17 | .package(name: "Stream"), 18 | .package(name: "Radix"), 19 | .package(name: "Test"), 20 | ], 21 | targets: [ 22 | .target( 23 | name: "MessagePack", 24 | dependencies: [ 25 | .product(name: "Codable", package: "codable"), 26 | .product(name: "Stream", package: "stream"), 27 | .product(name: "Hex", package: "Radix"), 28 | ], 29 | swiftSettings: swift6), 30 | ] 31 | ) 32 | 33 | let swift6: [SwiftSetting] = [ 34 | .enableUpcomingFeature("ConciseMagicFile"), 35 | .enableUpcomingFeature("ForwardTrailingClosures"), 36 | .enableUpcomingFeature("ExistentialAny"), 37 | .enableUpcomingFeature("StrictConcurrency"), 38 | .enableUpcomingFeature("ImplicitOpenExistentials"), 39 | .enableUpcomingFeature("BareSlashRegexLiterals"), 40 | ] 41 | 42 | // MARK: - tests 43 | 44 | testTarget("Codable") { test in 45 | test("KeyedDecodingContainer") 46 | test("KeyedEncodingContainer") 47 | test("MessagePackCoders") 48 | test("UnkeyedDecodingContainer") 49 | test("UnkeyedEncodingContainer") 50 | } 51 | 52 | testTarget("Coding") { test in 53 | test("Array") 54 | test("Binary") 55 | test("Bool") 56 | test("Decode") 57 | test("EncodeArray") 58 | test("Extended") 59 | test("Float") 60 | test("Init") 61 | test("InsufficientData") 62 | test("Integer") 63 | test("InvalidHeader") 64 | test("ManualHeaders") 65 | test("Map") 66 | test("Nil") 67 | test("String") 68 | test("StringEncoding") 69 | test("Timestamp") 70 | } 71 | 72 | testTarget("MessagePack") { test in 73 | test("Accessors") 74 | test("ConvenienceInitializers") 75 | test("Description") 76 | test("Equality") 77 | test("HasValue") 78 | test("LiteralConvertible") 79 | test("MessagePackInitializable") 80 | } 81 | 82 | func testTarget(_ target: String, task: ((String) -> Void) -> Void) { 83 | task { test in addTest(target: target, name: test) } 84 | } 85 | 86 | func addTest(target: String, name: String) { 87 | package.targets.append( 88 | .executableTarget( 89 | name: "Tests/\(target)/\(name)", 90 | dependencies: [ 91 | .target(name: "MessagePack"), 92 | .product(name: "Test", package: "test"), 93 | ], 94 | path: "Tests/\(target)/\(name)", 95 | swiftSettings: swift6)) 96 | } 97 | 98 | // MARK: - custom package source 99 | 100 | #if canImport(ObjectiveC) 101 | import Darwin.C 102 | #else 103 | import Glibc 104 | #endif 105 | 106 | extension Package.Dependency { 107 | enum Source: String { 108 | case local, remote, github 109 | 110 | static var `default`: Self { .github } 111 | 112 | var baseUrl: String { 113 | switch self { 114 | case .local: return "../" 115 | case .remote: return "https://swiftstack.io/" 116 | case .github: return "https://github.com/swiftstack/" 117 | } 118 | } 119 | 120 | func url(for name: String) -> String { 121 | return self == .local 122 | ? baseUrl + name.lowercased() 123 | : baseUrl + name.lowercased() + ".git" 124 | } 125 | } 126 | 127 | static func package(name: String) -> Package.Dependency { 128 | guard let pointer = getenv("SWIFTSTACK") else { 129 | return .package(name: name, source: .default) 130 | } 131 | guard let source = Source(rawValue: String(cString: pointer)) else { 132 | fatalError("Invalid source. Use local, remote or github") 133 | } 134 | return .package(name: name, source: source) 135 | } 136 | 137 | static func package(name: String, source: Source) -> Package.Dependency { 138 | return source == .local 139 | ? .package(name: name, path: source.url(for: name)) 140 | : .package(url: source.url(for: name), branch: "dev") 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MessagePack 2 | 3 | **MessagePack** is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves. 4 | 5 | ## Package.swift 6 | 7 | ```swift 8 | .package(url: "https://github.com/swiftstack/messagepack.git", .branch("dev")) 9 | ``` 10 | 11 | ## Memo 12 | 13 | ```swift 14 | public enum MessagePack { 15 | case `nil` 16 | case int(Int) 17 | case uint(UInt) 18 | case bool(Bool) 19 | case float(Float) 20 | case double(Double) 21 | case string(String) 22 | case binary([UInt8]) 23 | case array([MessagePack]) 24 | case map([MessagePack : MessagePack]) 25 | case extended(Extended) 26 | 27 | public struct Extended { 28 | public let type: Int8 29 | public let data: [UInt8] 30 | public init(type: Int8, data: [UInt8]) { 31 | self.type = type 32 | self.data = data 33 | } 34 | } 35 | } 36 | ``` 37 | 38 | ## Usage 39 | 40 | You can find this code and more in [examples](https://github.com/swiftstack/examples). 41 | 42 | ### Basic API 43 | 44 | ```swift 45 | let hey = MessagePack("hey there!") 46 | let bytes = try MessagePack.encode(hey) 47 | let original = String(try MessagePack.decode(bytes: bytes)) 48 | ``` 49 | 50 | ### Stream API 51 | 52 | ```swift 53 | let hey = MessagePack("hey there!") 54 | let stream = BufferedStream(stream: NetworkStream(socket: client)) 55 | try MessagePack.encode(hey, to: stream) 56 | try stream.flush() 57 | let original = String(try MessagePack.decode(from: stream)) 58 | ``` 59 | 60 | ### Performance optimized 61 | 62 | ```swift 63 | let output = OutputByteStream() 64 | var encoder = MessagePackWriter(output) 65 | try encoder.encode("one") 66 | try encoder.encode(2) 67 | try encoder.encode(3.0) 68 | let encoded = output.bytes 69 | 70 | var decoder = MessagePackReader(InputByteStream(encoded)) 71 | let string = try decoder.decode(String.self) 72 | let int = try decoder.decode(UInt8.self) 73 | let double = try decoder.decode(Double.self) 74 | print("decoded manually: \(string), \(int), \(double)") 75 | ``` 76 | -------------------------------------------------------------------------------- /Sources/MessagePack/Codable/CodingKey+MessagePack.swift: -------------------------------------------------------------------------------- 1 | extension CodingKey { 2 | init?(_ key: MessagePack) { 3 | switch key { 4 | case .int(let value): 5 | self.init(intValue: value) 6 | case .uint(let value) where value < Int.max: 7 | self.init(intValue: Int(value)) 8 | case .string(let value): 9 | self.init(stringValue: value) 10 | default: 11 | return nil 12 | } 13 | } 14 | } 15 | 16 | extension MessagePack { 17 | init(_ key: CodingKey) { 18 | switch key.intValue { 19 | case .some(let value): self = .int(value) 20 | case .none: self = .string(key.stringValue) 21 | } 22 | } 23 | } 24 | 25 | extension Dictionary where Key == MessagePack { 26 | subscript(_ key: CodingKey) -> Value? { 27 | return self[MessagePack(key)] 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Sources/MessagePack/Codable/Decoding/Decoder+Error.swift: -------------------------------------------------------------------------------- 1 | extension Decoder { 2 | enum Error: Swift.Error { 3 | enum ContainerType { 4 | case keyed(by: CodingKey.Type, for: CodingKey?) 5 | case unkeyed(for: CodingKey?) 6 | case singleValue 7 | } 8 | 9 | case containerTypeMismatch( 10 | requested: ContainerType, 11 | actual: Any) 12 | 13 | case typeMismatch( 14 | forKey: CodingKey?, 15 | requested: Decodable.Type, 16 | actual: Any) 17 | 18 | case keyNotFound(CodingKey) 19 | } 20 | } 21 | 22 | extension Decoder.Error { 23 | static func typeMismatch( 24 | requested: Decodable.Type, 25 | actual: Any 26 | ) -> Decoder.Error { 27 | return .typeMismatch( 28 | forKey: nil, 29 | requested: requested, 30 | actual: actual) 31 | } 32 | } 33 | 34 | extension Decoder.Error.ContainerType { 35 | static func keyed(by type: CodingKey.Type) -> Decoder.Error.ContainerType { 36 | return .keyed(by: type, for: nil) 37 | } 38 | 39 | static var unkeyed: Decoder.Error.ContainerType { 40 | return .unkeyed(for: nil) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Sources/MessagePack/Codable/Decoding/Decoder.swift: -------------------------------------------------------------------------------- 1 | typealias Decoder = MessagePack.Decoder 2 | 3 | extension MessagePack { 4 | public final class Decoder: Swift.Decoder { 5 | public var codingPath: [CodingKey] { return [] } 6 | public var userInfo: [CodingUserInfoKey: Any] { return [:] } 7 | 8 | private let value: MessagePack 9 | 10 | public init(_ value: MessagePack) { 11 | self.value = value 12 | } 13 | 14 | public func container( 15 | keyedBy type: Key.Type 16 | ) throws -> KeyedDecodingContainer { 17 | guard case .map(let dictionary) = value else { 18 | throw Error.containerTypeMismatch( 19 | requested: .keyed(by: type), 20 | actual: value) 21 | } 22 | let container = KeyedContainer(dictionary) 23 | return KeyedDecodingContainer(container) 24 | } 25 | 26 | public func unkeyedContainer() throws -> UnkeyedDecodingContainer { 27 | guard case .array(let array) = value else { 28 | throw Error.containerTypeMismatch( 29 | requested: .unkeyed, 30 | actual: value) 31 | } 32 | return UnkeyedContainer(array) 33 | } 34 | 35 | public func singleValueContainer( 36 | ) throws -> SingleValueDecodingContainer { 37 | return SingleValueContainer(value) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/MessagePack/Codable/Decoding/KeyedDecodingContainer.swift: -------------------------------------------------------------------------------- 1 | extension Decoder { 2 | struct KeyedContainer: KeyedDecodingContainerProtocol { 3 | var codingPath: [CodingKey] { return [] } 4 | 5 | var allKeys: [Key] { 6 | return dictionary.keys.compactMap(Key.init) 7 | } 8 | 9 | private let dictionary: [MessagePack: MessagePack] 10 | 11 | init(_ dictionary: [MessagePack: MessagePack]) { 12 | self.dictionary = dictionary 13 | } 14 | 15 | func contains(_ key: Key) -> Bool { 16 | return dictionary[key] != nil 17 | } 18 | 19 | @inline(__always) 20 | private func _decode( 21 | _ type: T.Type, 22 | forKey key: Key 23 | ) throws -> T where T: MessagePackInitializable & Decodable { 24 | guard let value = dictionary[key] else { 25 | throw Error.keyNotFound(key) 26 | } 27 | guard let rawValue = T(value) else { 28 | throw Error.typeMismatch( 29 | forKey: key, 30 | requested: type, 31 | actual: value) 32 | } 33 | return rawValue 34 | } 35 | 36 | @inline(__always) 37 | private func _decodeIfPresent( 38 | _ type: T.Type, 39 | forKey key: Key 40 | ) throws -> T? where T: MessagePackInitializable & Decodable { 41 | guard let value = dictionary[key] else { 42 | return nil 43 | } 44 | guard let rawValue = T(value) else { 45 | if case .nil = value { 46 | return nil 47 | } 48 | throw Error.typeMismatch( 49 | forKey: key, 50 | requested: type, 51 | actual: value) 52 | } 53 | return rawValue 54 | } 55 | 56 | func decodeNil(forKey key: Key) throws -> Bool { 57 | if let value = dictionary[key], case .nil = value { 58 | return true 59 | } 60 | return false 61 | } 62 | 63 | func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool { 64 | return try _decode(type, forKey: key) 65 | } 66 | 67 | func decode(_ type: Int.Type, forKey key: Key) throws -> Int { 68 | return try _decode(type, forKey: key) 69 | } 70 | 71 | func decode(_ type: Int8.Type, forKey key: Key) throws -> Int8 { 72 | return try _decode(type, forKey: key) 73 | } 74 | 75 | func decode(_ type: Int16.Type, forKey key: Key) throws -> Int16 { 76 | return try _decode(type, forKey: key) 77 | } 78 | 79 | func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 { 80 | return try _decode(type, forKey: key) 81 | } 82 | 83 | func decode(_ type: Int64.Type, forKey key: Key) throws -> Int64 { 84 | return try _decode(type, forKey: key) 85 | } 86 | 87 | func decode(_ type: UInt.Type, forKey key: Key) throws -> UInt { 88 | return try _decode(type, forKey: key) 89 | } 90 | 91 | func decode(_ type: UInt8.Type, forKey key: Key) throws -> UInt8 { 92 | return try _decode(type, forKey: key) 93 | } 94 | 95 | func decode(_ type: UInt16.Type, forKey key: Key) throws -> UInt16 { 96 | return try _decode(type, forKey: key) 97 | } 98 | 99 | func decode(_ type: UInt32.Type, forKey key: Key) throws -> UInt32 { 100 | return try _decode(type, forKey: key) 101 | } 102 | 103 | func decode(_ type: UInt64.Type, forKey key: Key) throws -> UInt64 { 104 | return try _decode(type, forKey: key) 105 | } 106 | 107 | func decode(_ type: Float.Type, forKey key: Key) throws -> Float { 108 | return try _decode(type, forKey: key) 109 | } 110 | 111 | func decode(_ type: Double.Type, forKey key: Key) throws -> Double { 112 | return try _decode(type, forKey: key) 113 | } 114 | 115 | func decode(_ type: String.Type, forKey key: Key) throws -> String { 116 | return try _decode(type, forKey: key) 117 | } 118 | 119 | func decode(_ type: T.Type, forKey key: Key) throws -> T { 120 | guard let value = dictionary[key] else { 121 | throw Error.keyNotFound(key) 122 | } 123 | let decoder = Decoder(value) 124 | return try T(from: decoder) 125 | } 126 | 127 | func decodeIfPresent( 128 | _ type: Bool.Type, 129 | forKey key: Key 130 | ) throws -> Bool? { 131 | return try _decodeIfPresent(type, forKey: key) 132 | } 133 | 134 | func decodeIfPresent( 135 | _ type: Int.Type, 136 | forKey key: Key 137 | ) throws -> Int? { 138 | return try _decodeIfPresent(type, forKey: key) 139 | } 140 | 141 | func decodeIfPresent( 142 | _ type: Int8.Type, 143 | forKey key: Key 144 | ) throws -> Int8? { 145 | return try _decodeIfPresent(type, forKey: key) 146 | } 147 | 148 | func decodeIfPresent( 149 | _ type: Int16.Type, 150 | forKey key: Key 151 | ) throws -> Int16? { 152 | return try _decodeIfPresent(type, forKey: key) 153 | } 154 | 155 | func decodeIfPresent( 156 | _ type: Int32.Type, 157 | forKey key: Key 158 | ) throws -> Int32? { 159 | return try _decodeIfPresent(type, forKey: key) 160 | } 161 | 162 | func decodeIfPresent( 163 | _ type: Int64.Type, 164 | forKey key: Key 165 | ) throws -> Int64? { 166 | return try _decodeIfPresent(type, forKey: key) 167 | } 168 | 169 | func decodeIfPresent( 170 | _ type: UInt.Type, 171 | forKey key: Key 172 | ) throws -> UInt? { 173 | return try _decodeIfPresent(type, forKey: key) 174 | } 175 | 176 | func decodeIfPresent( 177 | _ type: UInt8.Type, 178 | forKey key: Key 179 | ) throws -> UInt8? { 180 | return try _decodeIfPresent(type, forKey: key) 181 | } 182 | 183 | func decodeIfPresent( 184 | _ type: UInt16.Type, 185 | forKey key: Key 186 | ) throws -> UInt16? { 187 | return try _decodeIfPresent(type, forKey: key) 188 | } 189 | 190 | func decodeIfPresent( 191 | _ type: UInt32.Type, 192 | forKey key: Key 193 | ) throws -> UInt32? { 194 | return try _decodeIfPresent(type, forKey: key) 195 | } 196 | 197 | func decodeIfPresent( 198 | _ type: UInt64.Type, 199 | forKey key: Key 200 | ) throws -> UInt64? { 201 | return try _decodeIfPresent(type, forKey: key) 202 | } 203 | 204 | func decodeIfPresent( 205 | _ type: Float.Type, 206 | forKey key: Key 207 | ) throws -> Float? { 208 | return try _decodeIfPresent(type, forKey: key) 209 | } 210 | 211 | func decodeIfPresent( 212 | _ type: Double.Type, 213 | forKey key: Key 214 | ) throws -> Double? { 215 | return try _decodeIfPresent(type, forKey: key) 216 | } 217 | 218 | func decodeIfPresent( 219 | _ type: String.Type, 220 | forKey key: Key 221 | ) throws -> String? { 222 | return try _decodeIfPresent(type, forKey: key) 223 | } 224 | 225 | func decodeIfPresent( 226 | _ type: T.Type, 227 | forKey key: Key 228 | ) throws -> T? where T: Decodable { 229 | guard let value = dictionary[key] else { 230 | return nil 231 | } 232 | let decoder = Decoder(value) 233 | return try T(from: decoder) 234 | } 235 | 236 | func nestedContainer( 237 | keyedBy type: NestedKey.Type, 238 | forKey key: Key 239 | ) throws -> KeyedDecodingContainer { 240 | guard let container = dictionary[key] else { 241 | throw Error.keyNotFound(key) 242 | } 243 | guard case .map(let dictionary) = container else { 244 | throw Error.containerTypeMismatch( 245 | requested: .keyed(by: type, for: key), 246 | actual: container) 247 | } 248 | let keyedContainer = KeyedContainer(dictionary) 249 | return KeyedDecodingContainer(keyedContainer) 250 | } 251 | 252 | func nestedUnkeyedContainer( 253 | forKey key: Key 254 | ) throws -> UnkeyedDecodingContainer { 255 | guard let container = dictionary[key] else { 256 | throw Error.keyNotFound(key) 257 | } 258 | guard case .array(let array) = container else { 259 | throw Error.containerTypeMismatch( 260 | requested: .unkeyed(for: key), 261 | actual: container) 262 | } 263 | return UnkeyedContainer(array) 264 | } 265 | 266 | func superDecoder() throws -> Swift.Decoder { 267 | return Decoder(.map(dictionary)) 268 | } 269 | 270 | func superDecoder(forKey key: Key) throws -> Swift.Decoder { 271 | guard let container = dictionary[key] else { 272 | throw Error.keyNotFound(key) 273 | } 274 | return Decoder(container) 275 | } 276 | } 277 | } 278 | -------------------------------------------------------------------------------- /Sources/MessagePack/Codable/Decoding/SingleValueDecodingContainer.swift: -------------------------------------------------------------------------------- 1 | extension Decoder { 2 | struct SingleValueContainer: SingleValueDecodingContainer { 3 | var codingPath: [CodingKey] { return [] } 4 | 5 | private var value: MessagePack 6 | 7 | init(_ value: MessagePack) { 8 | self.value = value 9 | } 10 | 11 | @inline(__always) 12 | private func inlinedDecode( 13 | _ type: T.Type 14 | ) throws -> T where T: MessagePackInitializable & Decodable { 15 | guard let value = T(self.value) else { 16 | throw Error.typeMismatch(requested: type, actual: self.value) 17 | } 18 | return value 19 | } 20 | 21 | func decodeNil() -> Bool { 22 | guard case .nil = value else { 23 | return false 24 | } 25 | return true 26 | } 27 | 28 | func decode(_ type: Bool.Type) throws -> Bool { 29 | return try inlinedDecode(type) 30 | } 31 | 32 | func decode(_ type: Int.Type) throws -> Int { 33 | return try inlinedDecode(type) 34 | } 35 | 36 | func decode(_ type: Int8.Type) throws -> Int8 { 37 | return try inlinedDecode(type) 38 | } 39 | 40 | func decode(_ type: Int16.Type) throws -> Int16 { 41 | return try inlinedDecode(type) 42 | } 43 | 44 | func decode(_ type: Int32.Type) throws -> Int32 { 45 | return try inlinedDecode(type) 46 | } 47 | 48 | func decode(_ type: Int64.Type) throws -> Int64 { 49 | return try inlinedDecode(type) 50 | } 51 | 52 | func decode(_ type: UInt.Type) throws -> UInt { 53 | return try inlinedDecode(type) 54 | } 55 | 56 | func decode(_ type: UInt8.Type) throws -> UInt8 { 57 | return try inlinedDecode(type) 58 | } 59 | 60 | func decode(_ type: UInt16.Type) throws -> UInt16 { 61 | return try inlinedDecode(type) 62 | } 63 | 64 | func decode(_ type: UInt32.Type) throws -> UInt32 { 65 | return try inlinedDecode(type) 66 | } 67 | 68 | func decode(_ type: UInt64.Type) throws -> UInt64 { 69 | return try inlinedDecode(type) 70 | } 71 | 72 | func decode(_ type: Float.Type) throws -> Float { 73 | return try inlinedDecode(type) 74 | } 75 | 76 | func decode(_ type: Double.Type) throws -> Double { 77 | return try inlinedDecode(type) 78 | } 79 | 80 | func decode(_ type: String.Type) throws -> String { 81 | return try inlinedDecode(type) 82 | } 83 | 84 | func decode(_ type: T.Type) throws -> T where T: Decodable { 85 | let decoder = Decoder(value) 86 | return try T(from: decoder) 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Sources/MessagePack/Codable/Decoding/UnkeyedDecodingContainer.swift: -------------------------------------------------------------------------------- 1 | extension Decoder { 2 | final class UnkeyedContainer: 3 | UnkeyedDecodingContainer, 4 | SingleValueDecodingContainer 5 | { 6 | var codingPath: [CodingKey] { return [] } 7 | 8 | var currentIndex: Int 9 | private let array: [MessagePack] 10 | 11 | init(_ array: [MessagePack]) { 12 | self.array = array 13 | self.currentIndex = 0 14 | } 15 | 16 | var count: Int? { 17 | return array.count 18 | } 19 | 20 | var isAtEnd: Bool { 21 | return currentIndex == array.count 22 | } 23 | 24 | @inline(__always) 25 | private func _decode( 26 | _ type: T.Type 27 | ) throws -> T where T: MessagePackInitializable & Decodable { 28 | let value = array[currentIndex] 29 | guard let rawValue = T(value) else { 30 | throw Error.typeMismatch(requested: type, actual: value) 31 | } 32 | currentIndex += 1 33 | return rawValue 34 | } 35 | 36 | @inline(__always) 37 | private func _decodeIfPresent( 38 | _ type: T.Type 39 | ) throws -> T? where T: MessagePackInitializable & Decodable { 40 | let value = array[currentIndex] 41 | guard let rawValue = T(value) else { 42 | if case .nil = value { 43 | currentIndex += 1 44 | return nil 45 | } 46 | throw Error.typeMismatch(requested: type, actual: value) 47 | } 48 | currentIndex += 1 49 | return rawValue 50 | } 51 | 52 | func decodeNil() -> Bool { 53 | defer { currentIndex += 1 } 54 | guard case .nil = array[currentIndex] else { 55 | return false 56 | } 57 | return true 58 | } 59 | 60 | func decode(_ type: Int.Type) throws -> Int { 61 | return try _decode(type) 62 | } 63 | 64 | func decode(_ type: Int8.Type) throws -> Int8 { 65 | return try _decode(type) 66 | } 67 | 68 | func decode(_ type: Int16.Type) throws -> Int16 { 69 | return try _decode(type) 70 | } 71 | 72 | func decode(_ type: Int32.Type) throws -> Int32 { 73 | return try _decode(type) 74 | } 75 | 76 | func decode(_ type: Int64.Type) throws -> Int64 { 77 | return try _decode(type) 78 | } 79 | 80 | func decode(_ type: UInt.Type) throws -> UInt { 81 | return try _decode(type) 82 | } 83 | 84 | func decode(_ type: UInt8.Type) throws -> UInt8 { 85 | return try _decode(type) 86 | } 87 | 88 | func decode(_ type: UInt16.Type) throws -> UInt16 { 89 | return try _decode(type) 90 | } 91 | 92 | func decode(_ type: UInt32.Type) throws -> UInt32 { 93 | return try _decode(type) 94 | } 95 | 96 | func decode(_ type: UInt64.Type) throws -> UInt64 { 97 | return try _decode(type) 98 | } 99 | 100 | func decode(_ type: Float.Type) throws -> Float { 101 | return try _decode(type) 102 | } 103 | 104 | func decode(_ type: Double.Type) throws -> Double { 105 | return try _decode(type) 106 | } 107 | 108 | func decode(_ type: String.Type) throws -> String { 109 | return try _decode(type) 110 | } 111 | 112 | func decode(_ type: T.Type) throws -> T { 113 | let decoder = Decoder(array[currentIndex]) 114 | let value = try T(from: decoder) 115 | currentIndex += 1 116 | return value 117 | } 118 | 119 | func decodeIfPresent(_ type: Bool.Type) throws -> Bool? { 120 | return try _decodeIfPresent(type) 121 | } 122 | 123 | func decodeIfPresent(_ type: Int.Type) throws -> Int? { 124 | return try _decodeIfPresent(type) 125 | } 126 | 127 | func decodeIfPresent(_ type: Int8.Type) throws -> Int8? { 128 | return try _decodeIfPresent(type) 129 | } 130 | 131 | func decodeIfPresent(_ type: Int16.Type) throws -> Int16? { 132 | return try _decodeIfPresent(type) 133 | } 134 | 135 | func decodeIfPresent(_ type: Int32.Type) throws -> Int32? { 136 | return try _decodeIfPresent(type) 137 | } 138 | 139 | func decodeIfPresent(_ type: Int64.Type) throws -> Int64? { 140 | return try _decodeIfPresent(type) 141 | } 142 | 143 | func decodeIfPresent(_ type: UInt.Type) throws -> UInt? { 144 | return try _decodeIfPresent(type) 145 | } 146 | 147 | func decodeIfPresent(_ type: UInt8.Type) throws -> UInt8? { 148 | return try _decodeIfPresent(type) 149 | } 150 | 151 | func decodeIfPresent(_ type: UInt16.Type) throws -> UInt16? { 152 | return try _decodeIfPresent(type) 153 | } 154 | 155 | func decodeIfPresent(_ type: UInt32.Type) throws -> UInt32? { 156 | return try _decodeIfPresent(type) 157 | } 158 | 159 | func decodeIfPresent(_ type: UInt64.Type) throws -> UInt64? { 160 | return try _decodeIfPresent(type) 161 | } 162 | 163 | func decodeIfPresent(_ type: Float.Type) throws -> Float? { 164 | return try _decodeIfPresent(type) 165 | } 166 | 167 | func decodeIfPresent(_ type: Double.Type) throws -> Double? { 168 | return try _decodeIfPresent(type) 169 | } 170 | 171 | func decodeIfPresent(_ type: String.Type) throws -> String? { 172 | return try _decodeIfPresent(type) 173 | } 174 | 175 | func decodeIfPresent(_ type: T.Type) throws -> T? { 176 | let decoder = Decoder(array[currentIndex]) 177 | let value = try T(from: decoder) 178 | currentIndex += 1 179 | return value 180 | } 181 | 182 | func nestedContainer( 183 | keyedBy type: NestedKey.Type 184 | ) throws -> KeyedDecodingContainer { 185 | let value = array[currentIndex] 186 | guard case .map(let dictionary) = value else { 187 | throw Error.containerTypeMismatch( 188 | requested: .keyed(by: type), 189 | actual: value) 190 | } 191 | currentIndex += 1 192 | let container = KeyedContainer(dictionary) 193 | return KeyedDecodingContainer(container) 194 | } 195 | 196 | func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer { 197 | let value = array[currentIndex] 198 | guard case .array(let array) = value else { 199 | throw Error.containerTypeMismatch( 200 | requested: .unkeyed, 201 | actual: value) 202 | } 203 | currentIndex += 1 204 | return UnkeyedContainer(array) 205 | } 206 | 207 | func superDecoder() throws -> Swift.Decoder { 208 | return self 209 | } 210 | } 211 | } 212 | 213 | extension Decoder.UnkeyedContainer: Swift.Decoder { 214 | var userInfo: [CodingUserInfoKey: Any] { return [:] } 215 | 216 | func container( 217 | keyedBy type: Key.Type 218 | ) throws -> KeyedDecodingContainer { 219 | // can't convert unkeyed to keyed 220 | throw Decoder.Error.containerTypeMismatch( 221 | requested: .keyed(by: type), 222 | actual: self) 223 | } 224 | 225 | func unkeyedContainer() throws -> UnkeyedDecodingContainer { 226 | return self 227 | } 228 | 229 | func singleValueContainer() throws -> SingleValueDecodingContainer { 230 | return self 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /Sources/MessagePack/Codable/Encoding/Encoder+Error.swift: -------------------------------------------------------------------------------- 1 | extension Encoder { 2 | public enum Error: Swift.Error { 3 | public enum ContainerType { 4 | case keyed(by: CodingKey.Type, for: CodingKey?) 5 | case unkeyed(for: CodingKey?) 6 | case singleValue 7 | } 8 | 9 | case containerTypeMismatch( 10 | requested: ContainerType, 11 | actual: Any) 12 | } 13 | } 14 | 15 | // MARK: Convenience 16 | 17 | extension Encoder.Error.ContainerType { 18 | static func keyed(by type: CodingKey.Type) -> Encoder.Error.ContainerType { 19 | return .keyed(by: type, for: nil) 20 | } 21 | 22 | static var unkeyed: Encoder.Error.ContainerType { 23 | return .unkeyed(for: nil) 24 | } 25 | } 26 | 27 | // FIXME: ha-ha gotcha! 28 | import struct Codable.EncodingError 29 | import struct Codable.KeyedEncodingError 30 | 31 | extension EncodingError { 32 | // return EncodingError(.containerTypeMismatch) 33 | // vs 34 | // return EncodingError(Error.containerTypeMismatch) 35 | init(_ error: Encoder.Error) { 36 | self.init(error as Swift.Error) 37 | } 38 | } 39 | 40 | extension KeyedEncodingError { 41 | // return KeyedEncodingError(.containerTypeMismatch) 42 | // vs 43 | // return KeyedEncodingError(Error.containerTypeMismatch) 44 | init(_ error: Encoder.Error) { 45 | self.init(error as Swift.Error) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Sources/MessagePack/Codable/Encoding/Encoder.swift: -------------------------------------------------------------------------------- 1 | import Codable 2 | 3 | typealias Encoder = MessagePack.Encoder 4 | 5 | extension MessagePack { 6 | public final class Encoder: Swift.Encoder { 7 | public var codingPath: [CodingKey] { return [] } 8 | public var userInfo: [CodingUserInfoKey: Any] { return [:] } 9 | 10 | public init() {} 11 | 12 | enum Container { 13 | case raw(MessagePack) 14 | case keyed(TypeErasedContainer) 15 | case unkeyed(UnkeyedContainer) 16 | case singleValue(SingleValueContainer) 17 | case superEncoder(Encoder) 18 | 19 | var rawValue: MessagePack { 20 | switch self { 21 | case .raw(let value): return value 22 | case .keyed(let container): return container.value 23 | case .unkeyed(let container): return container.value 24 | case .singleValue(let container): return container.value 25 | case .superEncoder(let container): return container.value 26 | } 27 | } 28 | } 29 | 30 | private var container: Container? 31 | 32 | public var value: MessagePack { 33 | switch container { 34 | case .some(let container): return container.rawValue 35 | case .none: return .nil 36 | } 37 | } 38 | 39 | public func container( 40 | keyedBy type: Key.Type 41 | ) -> KeyedEncodingContainer { 42 | let container: TypeErasedContainer 43 | switch self.container { 44 | case .some(let existing): 45 | guard case .keyed(let keyedContainer) = existing else { 46 | return KeyedEncodingContainer( 47 | KeyedEncodingError(.containerTypeMismatch( 48 | requested: .keyed(by: type), 49 | actual: existing))) 50 | } 51 | container = keyedContainer 52 | case .none: 53 | container = TypeErasedContainer() 54 | self.container = .keyed(container) 55 | } 56 | let keyedContainer = KeyedContainer( 57 | encoder: self, container: container) 58 | return KeyedEncodingContainer(keyedContainer) 59 | } 60 | 61 | public func unkeyedContainer() -> UnkeyedEncodingContainer { 62 | switch self.container { 63 | case .some(.unkeyed(let container)): 64 | return container 65 | case .some(let container): 66 | return EncodingError(.containerTypeMismatch( 67 | requested: .unkeyed, 68 | actual: container)) 69 | default: 70 | let container = UnkeyedContainer(self) 71 | self.container = .unkeyed(container) 72 | return container 73 | } 74 | } 75 | 76 | public func singleValueContainer() -> SingleValueEncodingContainer { 77 | switch self.container { 78 | // FIXME: this is a hack for initial [Swift.Encodable] 79 | // implementation before conditional conforamce was introduced 80 | // TODO: investigate current behavior, change to .single (or not) 81 | // and remove SingleValueEncodingContainer from UnkeyedContainer 82 | case .some(.unkeyed(let container)): 83 | return container 84 | case .some(let container): 85 | return EncodingError(.containerTypeMismatch( 86 | requested: .singleValue, 87 | actual: container)) 88 | default: 89 | let container = SingleValueContainer() 90 | self.container = .singleValue(container) 91 | return container 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Sources/MessagePack/Codable/Encoding/KeyedEncodingContainer.swift: -------------------------------------------------------------------------------- 1 | extension Encoder { 2 | // shared between different keyed 3 | // containers, e.g. super encoder 4 | final class TypeErasedContainer { 5 | var values: [MessagePack: Container] = [:] 6 | 7 | var value: MessagePack { 8 | return .map(values.mapValues { $0.rawValue }) 9 | } 10 | } 11 | } 12 | 13 | extension Encoder { 14 | final class KeyedContainer: KeyedEncodingContainerProtocol { 15 | var codingPath: [CodingKey] { return [] } 16 | 17 | let encoder: Encoder 18 | let container: TypeErasedContainer 19 | 20 | init(encoder: Encoder, container: TypeErasedContainer) { 21 | self.encoder = encoder 22 | self.container = container 23 | } 24 | 25 | func encodeNil(forKey key: Key) throws { 26 | container.values[.init(key)] = .raw(.nil) 27 | } 28 | 29 | func encode(_ value: Bool, forKey key: Key) throws { 30 | container.values[.init(key)] = .raw(.bool(value)) 31 | } 32 | 33 | func encode(_ value: Int, forKey key: Key) throws { 34 | container.values[.init(key)] = .raw(.int(value)) 35 | } 36 | 37 | func encode(_ value: Int8, forKey key: Key) throws { 38 | container.values[.init(key)] = .raw(.int(Int(value))) 39 | } 40 | 41 | func encode(_ value: Int16, forKey key: Key) throws { 42 | container.values[.init(key)] = .raw(.int(Int(value))) 43 | } 44 | 45 | func encode(_ value: Int32, forKey key: Key) throws { 46 | container.values[.init(key)] = .raw(.int(Int(value))) 47 | } 48 | 49 | func encode(_ value: Int64, forKey key: Key) throws { 50 | container.values[.init(key)] = .raw(.int(Int(value))) 51 | } 52 | 53 | func encode(_ value: UInt, forKey key: Key) throws { 54 | container.values[.init(key)] = .raw(.uint(UInt(value))) 55 | } 56 | 57 | func encode(_ value: UInt8, forKey key: Key) throws { 58 | container.values[.init(key)] = .raw(.uint(UInt(value))) 59 | } 60 | 61 | func encode(_ value: UInt16, forKey key: Key) throws { 62 | container.values[.init(key)] = .raw(.uint(UInt(value))) 63 | } 64 | 65 | func encode(_ value: UInt32, forKey key: Key) throws { 66 | container.values[.init(key)] = .raw(.uint(UInt(value))) 67 | } 68 | 69 | func encode(_ value: UInt64, forKey key: Key) throws { 70 | container.values[.init(key)] = .raw(.uint(UInt(value))) 71 | } 72 | 73 | func encode(_ value: Float, forKey key: Key) throws { 74 | container.values[.init(key)] = .raw(.float(value)) 75 | } 76 | 77 | func encode(_ value: Double, forKey key: Key) throws { 78 | container.values[.init(key)] = .raw(.double(value)) 79 | } 80 | 81 | func encode(_ value: String, forKey key: Key) throws { 82 | container.values[.init(key)] = .raw(.string(value)) 83 | } 84 | 85 | func encode(_ value: T, forKey key: Key) throws { 86 | let encoder = Encoder() 87 | try value.encode(to: encoder) 88 | container.values[.init(key)] = .raw(encoder.value) 89 | } 90 | 91 | func nestedContainer( 92 | keyedBy keyType: NestedKey.Type, 93 | forKey key: Key 94 | ) -> KeyedEncodingContainer { 95 | let container = TypeErasedContainer() 96 | let keyedContainer = KeyedContainer( 97 | encoder: encoder, 98 | container: container) 99 | self.container.values[.init(key)] = .keyed(container) 100 | return KeyedEncodingContainer(keyedContainer) 101 | } 102 | 103 | func nestedUnkeyedContainer( 104 | forKey key: Key 105 | ) -> UnkeyedEncodingContainer { 106 | let container = UnkeyedContainer(encoder) 107 | self.container.values[.init(key)] = .unkeyed(container) 108 | return container 109 | } 110 | 111 | func superEncoder() -> Swift.Encoder { 112 | return encoder 113 | } 114 | 115 | func superEncoder(forKey key: Key) -> Swift.Encoder { 116 | // TODO: test 117 | let encoder = Encoder() 118 | container.values[.init(key)] = .superEncoder(encoder) 119 | return encoder 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Sources/MessagePack/Codable/Encoding/SingleValueEncodingContainer.swift: -------------------------------------------------------------------------------- 1 | extension MessagePack.Encoder { 2 | final class SingleValueContainer: SingleValueEncodingContainer { 3 | var codingPath: [CodingKey] { return [] } 4 | 5 | var value: MessagePack = .nil 6 | 7 | func encodeNil() throws { 8 | self.value = .nil 9 | } 10 | 11 | func encode(_ value: Bool) throws { 12 | self.value = .bool(value) 13 | } 14 | 15 | func encode(_ value: Int) throws { 16 | self.value = .int(value) 17 | } 18 | 19 | func encode(_ value: Int8) throws { 20 | self.value = .int(Int(value)) 21 | } 22 | 23 | func encode(_ value: Int16) throws { 24 | self.value = .int(Int(value)) 25 | } 26 | 27 | func encode(_ value: Int32) throws { 28 | self.value = .int(Int(value)) 29 | } 30 | 31 | func encode(_ value: Int64) throws { 32 | self.value = .int(Int(value)) 33 | } 34 | 35 | func encode(_ value: UInt) throws { 36 | self.value = .uint(value) 37 | } 38 | 39 | func encode(_ value: UInt8) throws { 40 | self.value = .uint(UInt(value)) 41 | } 42 | 43 | func encode(_ value: UInt16) throws { 44 | self.value = .uint(UInt(value)) 45 | } 46 | 47 | func encode(_ value: UInt32) throws { 48 | self.value = .uint(UInt(value)) 49 | } 50 | 51 | func encode(_ value: UInt64) throws { 52 | self.value = .uint(UInt(value)) 53 | } 54 | 55 | func encode(_ value: Float) throws { 56 | self.value = .float(value) 57 | } 58 | 59 | func encode(_ value: Double) throws { 60 | self.value = .double(value) 61 | } 62 | 63 | func encode(_ value: String) throws { 64 | self.value = .string(value) 65 | } 66 | 67 | func encode(_ value: T) throws where T: Encodable { 68 | let encoder = Encoder() 69 | try value.encode(to: encoder) 70 | self.value = encoder.value 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Sources/MessagePack/Codable/Encoding/UnkeyedEncodingContainer.swift: -------------------------------------------------------------------------------- 1 | extension Encoder { 2 | final class UnkeyedContainer: 3 | UnkeyedEncodingContainer, 4 | SingleValueEncodingContainer 5 | { 6 | var codingPath: [CodingKey] { return [] } 7 | 8 | let encoder: Encoder 9 | var values: [Container] 10 | 11 | var value: MessagePack { 12 | var values = [MessagePack]() 13 | for value in self.values { 14 | values.append(value.rawValue) 15 | } 16 | return .array(values) 17 | } 18 | 19 | var count: Int { 20 | return values.count 21 | } 22 | 23 | init(_ encoder: Encoder) { 24 | self.encoder = encoder 25 | self.values = [] 26 | } 27 | 28 | func encodeNil() throws { 29 | values.append(.nil) 30 | } 31 | 32 | func encode(_ value: Int) throws { 33 | values.append(.int(value)) 34 | } 35 | 36 | func encode(_ value: Int8) throws { 37 | values.append(.int(Int(value))) 38 | } 39 | 40 | func encode(_ value: Int16) throws { 41 | values.append(.int(Int(value))) 42 | } 43 | 44 | func encode(_ value: Int32) throws { 45 | values.append(.int(Int(value))) 46 | } 47 | 48 | func encode(_ value: Int64) throws { 49 | values.append(.int(Int(value))) 50 | } 51 | 52 | func encode(_ value: UInt) throws { 53 | values.append(.uint(value)) 54 | } 55 | 56 | func encode(_ value: UInt8) throws { 57 | values.append(.uint(UInt(value))) 58 | } 59 | 60 | func encode(_ value: UInt16) throws { 61 | values.append(.uint(UInt(value))) 62 | } 63 | 64 | func encode(_ value: UInt32) throws { 65 | values.append(.uint(UInt(value))) 66 | } 67 | 68 | func encode(_ value: UInt64) throws { 69 | values.append(.uint(UInt(value))) 70 | } 71 | 72 | func encode(_ value: Float) throws { 73 | values.append(.float(value)) 74 | } 75 | 76 | func encode(_ value: Double) throws { 77 | values.append(.double(value)) 78 | } 79 | 80 | func encode(_ value: String) throws { 81 | values.append(.string(value)) 82 | } 83 | 84 | func encode(_ value: T) throws where T: Encodable { 85 | let encoder = Encoder() 86 | try value.encode(to: encoder) 87 | values.append(encoder.value) 88 | } 89 | 90 | func nestedContainer( 91 | keyedBy keyType: NestedKey.Type 92 | ) -> KeyedEncodingContainer { 93 | let container = TypeErasedContainer() 94 | let keyedContainer = KeyedContainer( 95 | encoder: encoder, container: container) 96 | values.append(.keyed(container)) 97 | return KeyedEncodingContainer(keyedContainer) 98 | } 99 | 100 | func nestedUnkeyedContainer() -> UnkeyedEncodingContainer { 101 | let container = UnkeyedContainer(encoder) 102 | values.append(.unkeyed(container)) 103 | return container 104 | } 105 | 106 | func superEncoder() -> Swift.Encoder { 107 | return encoder 108 | } 109 | } 110 | } 111 | 112 | extension Array where Element == MessagePack.Encoder.Container { 113 | mutating func append(_ rawValue: MessagePack) { 114 | self.append(.raw(rawValue)) 115 | } 116 | 117 | mutating func append(_ container: Encoder.TypeErasedContainer) { 118 | self.append(.keyed(container)) 119 | } 120 | 121 | mutating func append(_ container: Encoder.UnkeyedContainer) { 122 | self.append(.unkeyed(container)) 123 | } 124 | 125 | mutating func append(_ container: Encoder.SingleValueContainer) { 126 | self.append(.singleValue(container)) 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /Sources/MessagePack/Error.swift: -------------------------------------------------------------------------------- 1 | extension MessagePack { 2 | public enum Error: Swift.Error { 3 | case invalidData 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Sources/MessagePack/MessagePack+API.swift: -------------------------------------------------------------------------------- 1 | import Stream 2 | 3 | // MARK: Generic <-> Stream 4 | 5 | extension MessagePack { 6 | public static func decode( 7 | _ type: Model.Type, 8 | from stream: StreamReader 9 | ) async throws -> Model { 10 | let messagepack = try await MessagePack.decode(from: stream) 11 | let decoder = Decoder(messagepack) 12 | return try Model(from: decoder) 13 | } 14 | 15 | public static func encode( 16 | _ value: Model, 17 | to stream: StreamWriter 18 | ) async throws { 19 | let encoder = Encoder() 20 | try value.encode(to: encoder) 21 | try await MessagePack.encode(encoder.value, to: stream) 22 | } 23 | } 24 | 25 | // MARK: Codable <-> Stream 26 | 27 | extension MessagePack { 28 | public static func decode( 29 | decodable type: Decodable.Type, 30 | from stream: StreamReader 31 | ) async throws -> Decodable { 32 | let messagepack = try await MessagePack.decode(from: stream) 33 | let decoder = Decoder(messagepack) 34 | return try type.init(from: decoder) 35 | } 36 | 37 | public static func encode( 38 | encodable value: Encodable, 39 | to stream: StreamWriter 40 | ) async throws { 41 | let encoder = Encoder() 42 | try value.encode(to: encoder) 43 | try await MessagePack.encode(encoder.value, to: stream) 44 | } 45 | } 46 | 47 | // MARK: Codable <-> [UInt8] 48 | 49 | extension MessagePack { 50 | public static func encode( 51 | _ value: T 52 | ) async throws -> [UInt8] { 53 | let stream = OutputByteStream() 54 | try await encode(value, to: stream) 55 | return stream.bytes 56 | } 57 | 58 | public static func decode( 59 | _ type: T.Type, 60 | from json: [UInt8] 61 | ) async throws -> T { 62 | return try await decode(type, from: InputByteStream(json)) 63 | } 64 | 65 | public static func encode( 66 | encodable value: Encodable 67 | ) async throws -> [UInt8] { 68 | let stream = OutputByteStream() 69 | try await encode(encodable: value, to: stream) 70 | return stream.bytes 71 | } 72 | 73 | public static func decode( 74 | decodable type: Decodable.Type, 75 | from json: [UInt8] 76 | ) async throws -> Decodable { 77 | return try await decode(decodable: type, from: InputByteStream(json)) 78 | } 79 | } 80 | 81 | // MARK: MessagePack <-> Stream 82 | 83 | extension MessagePack { 84 | public static func encode( 85 | _ object: MessagePack, 86 | to stream: StreamWriter 87 | ) async throws { 88 | var writer = MessagePackWriter(stream) 89 | try await writer.encode(object) 90 | } 91 | 92 | public static func decode( 93 | from stream: StreamReader 94 | ) async throws -> MessagePack { 95 | var reader = MessagePackReader(stream) 96 | return try await reader.decode() 97 | } 98 | } 99 | 100 | // MARK: MessagePack <-> [UInt8] 101 | 102 | extension MessagePack { 103 | public static func encode(_ object: MessagePack) async throws -> [UInt8] { 104 | let stream = OutputByteStream() 105 | var writer = MessagePackWriter(stream) 106 | try await writer.encode(object) 107 | return stream.bytes 108 | } 109 | 110 | public static func decode(bytes: [UInt8]) async throws -> MessagePack { 111 | var reader = MessagePackReader(InputByteStream(bytes)) 112 | return try await reader.decode() 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Sources/MessagePack/MessagePack+Accessors.swift: -------------------------------------------------------------------------------- 1 | import Stream 2 | 3 | extension MessagePack { 4 | 5 | // MARK: check type 6 | 7 | public var isBoolean: Bool { 8 | switch self { 9 | case .bool: return true 10 | default: return false 11 | } 12 | } 13 | 14 | public var isString: Bool { 15 | switch self { 16 | case .string: return true 17 | default: return false 18 | } 19 | } 20 | 21 | public var isFloat: Bool { 22 | switch self { 23 | case .float: return true 24 | default: return false 25 | } 26 | } 27 | 28 | public var isDouble: Bool { 29 | switch self { 30 | case .double: return true 31 | default: return false 32 | } 33 | } 34 | 35 | public var isInteger: Bool { 36 | switch self { 37 | case .int: return true 38 | case .uint: return true 39 | default: return false 40 | } 41 | } 42 | 43 | public var isSigned: Bool { 44 | switch self { 45 | case .int: return true 46 | default: return false 47 | } 48 | } 49 | 50 | public var isUnsigned: Bool { 51 | switch self { 52 | case .uint: return true 53 | default: return false 54 | } 55 | } 56 | 57 | public var isBinary: Bool { 58 | switch self { 59 | case .binary: return true 60 | default: return false 61 | } 62 | } 63 | 64 | public var isArray: Bool { 65 | switch self { 66 | case .array: return true 67 | default: return false 68 | } 69 | } 70 | 71 | public var isDictionary: Bool { 72 | switch self { 73 | case .map: return true 74 | default: return false 75 | } 76 | } 77 | 78 | public var isExtended: Bool { 79 | switch self { 80 | case .extended: return true 81 | default: return false 82 | } 83 | } 84 | 85 | // MARK: unwrap value 86 | 87 | public var booleanValue: Bool? { 88 | switch self { 89 | case let .bool(value): return value 90 | default: return nil 91 | } 92 | } 93 | 94 | public var stringValue: String? { 95 | switch self { 96 | case let .string(value): return value 97 | default: return nil 98 | } 99 | } 100 | 101 | public var floatValue: Float? { 102 | switch self { 103 | case let .float(value): return value 104 | default: return nil 105 | } 106 | } 107 | 108 | public var doubleValue: Double? { 109 | switch self { 110 | case let .double(value): return value 111 | default: return nil 112 | } 113 | } 114 | 115 | public var integerValue: Int? { 116 | switch self { 117 | case let .int(value): return value 118 | case let .uint(value) where value <= UInt(Int.max): return Int(value) 119 | default: return nil 120 | } 121 | } 122 | 123 | public var unsignedValue: UInt? { 124 | switch self { 125 | case let .int(value) where value >= 0: return UInt(value) 126 | case let .uint(value): return value 127 | default: return nil 128 | } 129 | } 130 | 131 | public var binaryValue: [UInt8]? { 132 | switch self { 133 | case let .binary(value): return value 134 | default: return nil 135 | } 136 | } 137 | 138 | public var arrayValue: [MessagePack]? { 139 | switch self { 140 | case let .array(value): return value 141 | default: return nil 142 | } 143 | } 144 | 145 | public var dictionaryValue: [MessagePack: MessagePack]? { 146 | switch self { 147 | case let .map(value): return value 148 | default: return nil 149 | } 150 | } 151 | 152 | public var extendedValue: MessagePack.Extended? { 153 | switch self { 154 | case let .extended(value): return value 155 | default: return nil 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /Sources/MessagePack/MessagePack+Description.swift: -------------------------------------------------------------------------------- 1 | import Hex 2 | 3 | extension MessagePack: CustomStringConvertible { 4 | public var description: String { 5 | switch self { 6 | case .`nil`: return ".nil" 7 | case let .int(value): return ".int(\(value))" 8 | case let .uint(value): return ".uint(\(value))" 9 | case let .bool(value): return ".bool(\(value))" 10 | case let .float(value): return ".float(\(value))" 11 | case let .double(value): return ".double(\(value))" 12 | case let .string(value): return ".string(\"\(value)\")" 13 | case let .binary(value): return ".binary(\(value.hex))" 14 | case let .array(value): return ".array(\(value))" 15 | case let .map(value): return ".map(\(value))" 16 | case let .extended(value): return ".extended(\(value))" 17 | } 18 | } 19 | } 20 | 21 | extension MessagePack.Extended: CustomStringConvertible { 22 | public var description: String { 23 | return "{\(type), \(data.hex)}" 24 | } 25 | } 26 | 27 | extension Array where Iterator.Element == UInt8 { 28 | fileprivate var hex: String { 29 | return String(encodingToHex: self) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/MessagePack/MessagePack+Initializers.swift: -------------------------------------------------------------------------------- 1 | extension MessagePack { 2 | public init() { 3 | self = .`nil` 4 | } 5 | 6 | public init(_ value: Bool) { 7 | self = .bool(value) 8 | } 9 | 10 | public init(_ value: String) { 11 | self = .string(value) 12 | } 13 | 14 | public init(_ value: Float) { 15 | self = .float(value) 16 | } 17 | 18 | public init(_ value: Double) { 19 | self = .double(value) 20 | } 21 | 22 | public init(_ value: Int) { 23 | self = .int(value) 24 | } 25 | 26 | public init(_ value: Int8) { 27 | self = .int(Int(value)) 28 | } 29 | 30 | public init(_ value: Int16) { 31 | self = .int(Int(value)) 32 | } 33 | 34 | public init(_ value: Int32) { 35 | self = .int(Int(value)) 36 | } 37 | 38 | public init(_ value: Int64) { 39 | self = .int(Int(value)) 40 | } 41 | 42 | public init(_ value: UInt) { 43 | self = .uint(value) 44 | } 45 | 46 | public init(_ value: UInt8) { 47 | self = .uint(UInt(value)) 48 | } 49 | 50 | public init(_ value: UInt16) { 51 | self = .uint(UInt(value)) 52 | } 53 | 54 | public init(_ value: UInt32) { 55 | self = .uint(UInt(value)) 56 | } 57 | 58 | public init(_ value: UInt64) { 59 | self = .uint(UInt(value)) 60 | } 61 | 62 | public init(_ value: [MessagePack]) { 63 | self = .array(value) 64 | } 65 | 66 | public init(_ value: [MessagePack: MessagePack]) { 67 | self = .map(value) 68 | } 69 | 70 | public init(_ value: [UInt8]) { 71 | self = .binary(value) 72 | } 73 | 74 | public init(_ value: MessagePack.Extended) { 75 | self = .extended(value) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Sources/MessagePack/MessagePack+Literal.swift: -------------------------------------------------------------------------------- 1 | extension MessagePack: ExpressibleByNilLiteral { 2 | public init(nilLiteral: ()) { 3 | self = .nil 4 | } 5 | } 6 | 7 | extension MessagePack: ExpressibleByBooleanLiteral { 8 | public init(booleanLiteral value: Bool) { 9 | self = .bool(value) 10 | } 11 | } 12 | 13 | extension MessagePack: ExpressibleByIntegerLiteral { 14 | public init(integerLiteral value: Int) { 15 | switch value { 16 | case 0...: self = .uint(UInt(value)) 17 | default: self = .int(value) 18 | } 19 | } 20 | } 21 | 22 | extension MessagePack: ExpressibleByFloatLiteral { 23 | public init(floatLiteral value: Double) { 24 | self = .double(value) 25 | } 26 | } 27 | 28 | extension MessagePack: ExpressibleByStringLiteral { 29 | public init(stringLiteral value: String) { 30 | self = .string(value) 31 | } 32 | } 33 | 34 | extension MessagePack: ExpressibleByUnicodeScalarLiteral { 35 | public init(unicodeScalarLiteral value: String) { 36 | self = .string(value) 37 | } 38 | } 39 | 40 | extension MessagePack: ExpressibleByExtendedGraphemeClusterLiteral { 41 | public init(extendedGraphemeClusterLiteral value: String) { 42 | self = .string(value) 43 | } 44 | } 45 | 46 | extension MessagePack: ExpressibleByArrayLiteral { 47 | public init(arrayLiteral elements: MessagePack...) { 48 | self = .array(elements) 49 | } 50 | } 51 | 52 | extension MessagePack: ExpressibleByDictionaryLiteral { 53 | public init(dictionaryLiteral elements: (MessagePack, MessagePack)...) { 54 | self = .map([MessagePack: MessagePack](uniqueKeysWithValues: elements)) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Sources/MessagePack/MessagePack.swift: -------------------------------------------------------------------------------- 1 | public enum MessagePack: Equatable, Hashable { 2 | case `nil` 3 | case int(Int) 4 | case uint(UInt) 5 | case bool(Bool) 6 | case float(Float) 7 | case double(Double) 8 | case string(String) 9 | case binary([UInt8]) 10 | case array([MessagePack]) 11 | case map([MessagePack: MessagePack]) 12 | case extended(Extended) 13 | 14 | public struct Extended: Equatable, Hashable { 15 | public var type: Int8 16 | public var data: [UInt8] 17 | 18 | public init(type: Int8, data: [UInt8]) { 19 | self.type = type 20 | self.data = data 21 | } 22 | } 23 | } 24 | 25 | extension MessagePack { 26 | public var hasValue: Bool { 27 | switch self { 28 | case .nil: return false 29 | default: return true 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Sources/MessagePack/MessagePackInitializable.swift: -------------------------------------------------------------------------------- 1 | public protocol MessagePackInitializable { 2 | init?(_ value: MessagePack) 3 | } 4 | 5 | extension MessagePackInitializable { 6 | public init?(_ optional: MessagePack?) { 7 | guard case let .some(value) = optional else { 8 | return nil 9 | } 10 | self.init(value) 11 | } 12 | } 13 | 14 | extension Array where Element: MessagePackInitializable { 15 | public init?(_ optional: MessagePack?) { 16 | guard case let .some(value) = optional else { 17 | return nil 18 | } 19 | self.init(value) 20 | } 21 | } 22 | 23 | extension Array where Element: MessagePackInitializable { 24 | public init?(_ value: MessagePack) { 25 | guard let items = value.arrayValue else { 26 | return nil 27 | } 28 | 29 | var result = [Element]() 30 | for item in items { 31 | guard let value = Element(item) else { 32 | return nil 33 | } 34 | result.append(value) 35 | } 36 | self = result 37 | } 38 | } 39 | 40 | // Deprecated 41 | 42 | extension Bool: MessagePackInitializable { 43 | @available(*, deprecated, message: "use .booleanValue") 44 | public init?(_ value: MessagePack) { 45 | guard case let .bool(value) = value else { 46 | return nil 47 | } 48 | self.init(value) 49 | } 50 | } 51 | 52 | extension String: MessagePackInitializable { 53 | @available(*, deprecated, message: "use .stringValue") 54 | public init?(_ value: MessagePack) { 55 | guard case let .string(string) = value else { 56 | return nil 57 | } 58 | self.init(string) 59 | } 60 | } 61 | 62 | extension Float: MessagePackInitializable { 63 | @available(*, deprecated, message: "use .floatValue") 64 | public init?(_ value: MessagePack) { 65 | switch value { 66 | case let .float(value): self.init(value) 67 | default: return nil 68 | } 69 | } 70 | } 71 | 72 | extension Double: MessagePackInitializable { 73 | @available(*, deprecated, message: "use .doubleValue") 74 | public init?(_ value: MessagePack) { 75 | switch value { 76 | case let .double(value): self.init(value) 77 | default: return nil 78 | } 79 | } 80 | } 81 | 82 | extension Int: MessagePackInitializable { 83 | @available(*, deprecated, message: "use .integerValue") 84 | public init?(_ value: MessagePack) { 85 | switch value { 86 | case let .int(value): self.init(value) 87 | case let .uint(value) where value <= UInt(Int.max): self.init(value) 88 | default: return nil 89 | } 90 | } 91 | } 92 | 93 | extension Int8: MessagePackInitializable { 94 | @available(*, deprecated, message: "use .integerValue") 95 | public init?(_ value: MessagePack) { 96 | switch value { 97 | case let .int(value) where value <= Int(Int8.max): self.init(value) 98 | case let .uint(value) where value <= UInt(Int8.max): self.init(value) 99 | default: return nil 100 | } 101 | } 102 | } 103 | 104 | extension Int16: MessagePackInitializable { 105 | @available(*, deprecated, message: "use .integerValue") 106 | public init?(_ value: MessagePack) { 107 | switch value { 108 | case let .int(value) where value <= Int(Int16.max): self.init(value) 109 | case let .uint(value) where value <= UInt(Int16.max): self.init(value) 110 | default: return nil 111 | } 112 | } 113 | } 114 | 115 | extension Int32: MessagePackInitializable { 116 | @available(*, deprecated, message: "use .integerValue") 117 | public init?(_ value: MessagePack) { 118 | switch value { 119 | case let .int(value) where value <= Int(Int32.max): self.init(value) 120 | case let .uint(value) where value <= UInt(Int32.max): self.init(value) 121 | default: return nil 122 | } 123 | } 124 | } 125 | 126 | extension Int64: MessagePackInitializable { 127 | @available(*, deprecated, message: "use .integerValue") 128 | public init?(_ value: MessagePack) { 129 | switch value { 130 | case let .int(value): 131 | self.init(value) 132 | case let .uint(value) where UInt64(value) <= UInt64(Int64.max): 133 | self.init(value) 134 | default: return nil 135 | } 136 | } 137 | } 138 | 139 | extension UInt: MessagePackInitializable { 140 | @available(*, deprecated, message: "use .unsignedValue") 141 | public init?(_ value: MessagePack) { 142 | switch value { 143 | case let .int(value) where value >= 0: self.init(value) 144 | case let .uint(value): self.init(value) 145 | default: return nil 146 | } 147 | } 148 | } 149 | 150 | extension UInt8: MessagePackInitializable { 151 | @available(*, deprecated, message: "use .unsignedValue") 152 | public init?(_ value: MessagePack) { 153 | switch value { 154 | case let .int(value) where value >= 0 && UInt(value) <= UInt(UInt8.max): 155 | self.init(value) 156 | case let .uint(value) where value <= UInt(UInt8.max): 157 | self.init(value) 158 | default: return nil 159 | } 160 | } 161 | } 162 | 163 | extension UInt16: MessagePackInitializable { 164 | @available(*, deprecated, message: "use .unsignedValue") 165 | public init?(_ value: MessagePack) { 166 | switch value { 167 | case let .int(value) 168 | where value >= 0 && UInt(value) <= UInt(UInt16.max): 169 | self.init(value) 170 | case let .uint(value) 171 | where value <= UInt(UInt16.max): 172 | self.init(value) 173 | default: return nil 174 | } 175 | } 176 | } 177 | 178 | extension UInt32: MessagePackInitializable { 179 | @available(*, deprecated, message: "use .unsignedValue") 180 | public init?(_ value: MessagePack) { 181 | switch value { 182 | case let .int(value) 183 | where value >= 0 && UInt(value) <= UInt(UInt32.max): 184 | self.init(value) 185 | case let .uint(value) 186 | where value <= UInt(UInt32.max): 187 | self.init(value) 188 | default: return nil 189 | } 190 | } 191 | } 192 | 193 | extension UInt64: MessagePackInitializable { 194 | @available(*, deprecated, message: "use .unsignedValue") 195 | public init?(_ value: MessagePack) { 196 | switch value { 197 | case let .int(value) where value >= 0: self.init(value) 198 | case let .uint(value): self.init(value) 199 | default: return nil 200 | } 201 | } 202 | } 203 | 204 | extension MessagePack.Extended: MessagePackInitializable { 205 | @available(*, deprecated, message: "use .extendedValue") 206 | public init?(_ value: MessagePack) { 207 | guard case let .extended(data) = value else { 208 | return nil 209 | } 210 | self = data 211 | } 212 | } 213 | 214 | extension Array where Element == UInt8 { 215 | @available(*, deprecated, message: "use .binaryValue") 216 | public init?(_ value: MessagePack) { 217 | guard case let .binary(data) = value else { 218 | return nil 219 | } 220 | self = data 221 | } 222 | } 223 | 224 | extension Array where Element == MessagePack { 225 | @available(*, deprecated, message: "use .arrayValue") 226 | public init?(_ value: MessagePack) { 227 | guard case let .array(items) = value else { 228 | return nil 229 | } 230 | self = items 231 | } 232 | } 233 | 234 | extension Dictionary where Key == MessagePack, Value == MessagePack { 235 | @available(*, deprecated, message: "use .dictionaryValue") 236 | public init?(_ value: MessagePack) { 237 | guard case let .map(items) = value else { 238 | return nil 239 | } 240 | self = items 241 | } 242 | } 243 | 244 | // MARK: Optionals 245 | 246 | extension Array where Element == MessagePack { 247 | @available(*, deprecated, message: "use .arrayValue") 248 | public init?(_ optional: MessagePack?) { 249 | guard case let .some(value) = optional else { 250 | return nil 251 | } 252 | self.init(value) 253 | } 254 | } 255 | 256 | extension Dictionary where Key == MessagePack, Value == MessagePack { 257 | @available(*, deprecated, message: "use .dictionaryValue") 258 | public init?(_ optional: MessagePack?) { 259 | guard case let .some(value) = optional else { 260 | return nil 261 | } 262 | self.init(value) 263 | } 264 | } 265 | -------------------------------------------------------------------------------- /Sources/MessagePack/MessagePackReader.swift: -------------------------------------------------------------------------------- 1 | import Stream 2 | 3 | public struct MessagePackReader { 4 | var stream: StreamReader 5 | 6 | typealias Error = MessagePack.Error 7 | 8 | public init(_ stream: StreamReader) { 9 | self.stream = stream 10 | } 11 | 12 | mutating 13 | func read(_ type: T.Type) async throws -> T { 14 | return try await stream.read(type) 15 | } 16 | 17 | mutating func read(count: Int) async throws -> [UInt8] { 18 | return try await stream.read(count: count) 19 | } 20 | } 21 | 22 | extension MessagePackReader { 23 | mutating func readCode() async throws -> UInt8 { 24 | return try await read(UInt8.self) 25 | } 26 | } 27 | 28 | extension MessagePackReader { 29 | mutating func readInt(code: UInt8) async throws -> Int { 30 | switch code { 31 | case 0xd0: return Int(try await read(Int8.self)) 32 | case 0xd1: return Int(try await read(Int16.self)) 33 | case 0xd2: return Int(try await read(Int32.self)) 34 | case 0xd3: return Int(try await read(Int64.self)) 35 | case 0xe0...0xff: return Int(Int8(numericCast(code) - 0x100)) 36 | default: throw Error.invalidData 37 | } 38 | } 39 | 40 | mutating func readUInt(code: UInt8) async throws -> UInt { 41 | switch code { 42 | case 0x00...0x7f: return UInt(code) 43 | case 0xcc: return UInt(try await read(UInt8.self)) 44 | case 0xcd: return UInt(try await read(UInt16.self)) 45 | case 0xce: return UInt(try await read(UInt32.self)) 46 | case 0xcf: return UInt(try await read(UInt64.self)) 47 | default: throw Error.invalidData 48 | } 49 | } 50 | 51 | mutating func readBool(code: UInt8) async throws -> Bool { 52 | switch code { 53 | case 0xc2: return false 54 | case 0xc3: return true 55 | default: throw Error.invalidData 56 | } 57 | } 58 | 59 | mutating func readFloat() async throws -> Float { 60 | let bytes = try await read(UInt32.self) 61 | return Float(bitPattern: bytes) 62 | } 63 | 64 | mutating func readDouble() async throws -> Double { 65 | let bytes = try await read(UInt64.self) 66 | return Double(bitPattern: bytes) 67 | } 68 | 69 | mutating func readString(code: UInt8) async throws -> String { 70 | let count = try await readStringHeader(code: code) 71 | let bytes = try await read(count: count) 72 | return String(decoding: bytes, as: UTF8.self) 73 | } 74 | 75 | mutating func readArray(code: UInt8)async throws -> [MessagePack] { 76 | let count = try await readArrayHeader(code: code) 77 | var array = [MessagePack]() 78 | 79 | array.reserveCapacity(count) 80 | for _ in 0.. [MessagePack: MessagePack] { 90 | let count = try await readMapHeader(code: code) 91 | var dictionary = [MessagePack: MessagePack]() 92 | 93 | for _ in 0.. [UInt8] { 103 | let count = try await readBinaryHeader(code: code) 104 | return [UInt8](try await read(count: count)) 105 | } 106 | 107 | mutating func readExtended( 108 | code: UInt8 109 | ) async throws -> MessagePack.Extended { 110 | let count = try await readExtendedHeader(code: code) 111 | 112 | let type = try await read(Int8.self) 113 | let data = [UInt8](try await read(count: count)) 114 | 115 | return MessagePack.Extended(type: type, data: data) 116 | } 117 | } 118 | 119 | extension MessagePackReader { 120 | public mutating func decode() async throws -> MessagePack { 121 | let code = try await readCode() 122 | switch code { 123 | // positive fixint 124 | case 0x00...0x7f: return .uint(try await readUInt(code: code)) 125 | // fixmap 126 | case 0x80...0x8f: return .map(try await readMap(code: code)) 127 | // fixarray: 8 bit lenght 128 | case 0x90...0x9f: return .array(try await readArray(code: code)) 129 | // fixstr: 8 bit length 130 | case 0xa0...0xbf: return .string(try await readString(code: code)) 131 | // nil 132 | case 0xc0: return .`nil` 133 | // bool 134 | case 0xc2...0xc3: return .bool(try await readBool(code: code)) 135 | // bin: 8,16,32 bit length 136 | case 0xc4...0xc6: return .binary(try await readBinary(code: code)) 137 | // ext 8,16,32 bit length 138 | case 0xc7...0xc9: return .extended(try await readExtended(code: code)) 139 | // float 32 140 | case 0xca: return .float(try await readFloat()) 141 | // float 64 142 | case 0xcb: return .double(try await readDouble()) 143 | // uint 8,16,32,64 144 | case 0xcc...0xcf: return .uint(try await readUInt(code: code)) 145 | // int 8,16,32,64 146 | case 0xd0...0xd3: return .int(try await readInt(code: code)) 147 | // fixext 1,2,4,8,16 bytes length 148 | case 0xd4...0xd8: return .extended(try await readExtended(code: code)) 149 | // str: 8,16,32 bit length 150 | case 0xd9...0xdb: return .string(try await readString(code: code)) 151 | // array: 16,32 bit length 152 | case 0xdc...0xdd: return .array(try await readArray(code: code)) 153 | // map: 16,32 bit length 154 | case 0xde...0xdf: return .map(try await readMap(code: code)) 155 | // negative fixint 156 | case 0xe0...0xff: return .int(try await readInt(code: code)) 157 | 158 | default: throw Error.invalidData 159 | } 160 | } 161 | 162 | public mutating func decodeArrayItemsCount() async throws -> Int { 163 | let code = try await readCode() 164 | return try await readArrayHeader(code: code) 165 | } 166 | 167 | public mutating func decodeMapItemsCount() async throws -> Int { 168 | let code = try await readCode() 169 | return try await readMapHeader(code: code) 170 | } 171 | 172 | public mutating func decode(_ type: Int.Type) async throws -> Int { 173 | let code = try await readCode() 174 | // positive integers encoded as unsigned 175 | // since they're used more often, 176 | // we try to decode and convert it first 177 | if let unsigned = try? await readUInt(code: code), 178 | unsigned <= UInt(Int.max) { 179 | return Int(unsigned) 180 | } 181 | return try await readInt(code: code) 182 | } 183 | 184 | public mutating func decode(_ type: UInt.Type) async throws -> UInt { 185 | let code = try await readCode() 186 | return try await readUInt(code: code) 187 | } 188 | 189 | public mutating func decode(_ type: Bool.Type) async throws -> Bool { 190 | let code = try await readCode() 191 | return try await readBool(code: code) 192 | } 193 | 194 | public mutating func decode(_ type: Float.Type) async throws -> Float { 195 | switch try await readCode() { 196 | case 0xca: return try await readFloat() 197 | default: throw Error.invalidData 198 | } 199 | } 200 | 201 | public mutating func decode(_ type: Double.Type) async throws -> Double { 202 | switch try await readCode() { 203 | case 0xcb: return try await readDouble() 204 | default: throw Error.invalidData 205 | } 206 | } 207 | 208 | public mutating func decode(_ type: String.Type) async throws -> String { 209 | let code = try await readCode() 210 | switch code { 211 | case 0xa0...0xbf: fallthrough 212 | case 0xd9...0xdb: return try await readString(code: code) 213 | default: throw Error.invalidData 214 | } 215 | } 216 | 217 | public mutating func decode(_ type: UInt8.Type) async throws -> UInt8 { 218 | let code = try await readCode() 219 | switch code { 220 | case 0x00...0x7f: return code 221 | case 0xcc: return try await read(UInt8.self) 222 | default: throw Error.invalidData 223 | } 224 | } 225 | 226 | public mutating func decode(_ type: UInt16.Type) async throws -> UInt16 { 227 | switch try await readCode() { 228 | case 0xcd: return try await read(UInt16.self) 229 | default: throw Error.invalidData 230 | } 231 | } 232 | 233 | public mutating func decode(_ type: UInt32.Type) async throws -> UInt32 { 234 | switch try await readCode() { 235 | case 0xce: return try await read(UInt32.self) 236 | default: throw Error.invalidData 237 | } 238 | } 239 | 240 | public mutating func decode(_ type: UInt64.Type) async throws -> UInt64 { 241 | switch try await readCode() { 242 | case 0xcf: return try await read(UInt64.self) 243 | default: throw Error.invalidData 244 | } 245 | } 246 | 247 | public mutating func decode(_ type: Int8.Type) async throws -> Int8 { 248 | let code = try await readCode() 249 | switch code { 250 | case 0xe0...0xff: return Int8(numericCast(code) - 0x100) 251 | case 0xd0: return try await read(Int8.self) 252 | default: throw Error.invalidData 253 | } 254 | } 255 | 256 | public mutating func decode(_ type: Int16.Type) async throws -> Int16 { 257 | switch try await readCode() { 258 | case 0xd1: return try await read(Int16.self) 259 | default: throw Error.invalidData 260 | } 261 | } 262 | 263 | public mutating func decode(_ type: Int32.Type) async throws -> Int32 { 264 | switch try await readCode() { 265 | case 0xd2: return try await read(Int32.self) 266 | default: throw Error.invalidData 267 | } 268 | } 269 | 270 | public mutating func decode(_ type: Int64.Type) async throws -> Int64 { 271 | switch try await readCode() { 272 | case 0xd3: return try await read(Int64.self) 273 | default: throw Error.invalidData 274 | } 275 | } 276 | 277 | public mutating func decode(_ type: [UInt8].Type) async throws -> [UInt8] { 278 | let code = try await readCode() 279 | switch code { 280 | case 0xc4...0xc6: return try await readBinary(code: code) 281 | default: throw Error.invalidData 282 | } 283 | } 284 | 285 | public mutating func decode( 286 | _ type: [MessagePack].Type 287 | ) async throws -> [MessagePack] { 288 | let code = try await readCode() 289 | switch code { 290 | case 0x90...0x9f: fallthrough 291 | case 0xdc...0xdd: return try await readArray(code: code) 292 | default: throw Error.invalidData 293 | } 294 | } 295 | 296 | public mutating func decode( 297 | _ type: [MessagePack: MessagePack].Type 298 | ) async throws -> [MessagePack: MessagePack] { 299 | let code = try await readCode() 300 | switch code { 301 | case 0x80...0x8f: fallthrough 302 | case 0xde...0xdf: return try await readMap(code: code) 303 | default: throw Error.invalidData 304 | } 305 | } 306 | 307 | public mutating func decode( 308 | _ type: MessagePack.Extended.Type 309 | ) async throws -> MessagePack.Extended { 310 | let code = try await readCode() 311 | switch code { 312 | case 0xc7...0xc9: fallthrough 313 | case 0xd4...0xd8: return try await readExtended(code: code) 314 | default: throw Error.invalidData 315 | } 316 | } 317 | } 318 | 319 | // Headers 320 | 321 | extension MessagePackReader { 322 | mutating func readStringHeader(code: UInt8) async throws -> Int { 323 | switch code { 324 | case 0xa0...0xbf: return Int(code - 0xa0) 325 | case 0xd9: return Int(try await read(UInt8.self)) 326 | case 0xda: return Int(try await read(UInt16.self)) 327 | case 0xdb: return Int(try await read(UInt32.self)) 328 | default: throw Error.invalidData 329 | } 330 | } 331 | 332 | mutating func readArrayHeader(code: UInt8) async throws -> Int { 333 | switch code { 334 | case 0x90...0x9f: return Int(code - 0x90) 335 | case 0xdc: return Int(try await read(UInt16.self)) 336 | case 0xdd: return Int(try await read(UInt32.self)) 337 | default: throw Error.invalidData 338 | } 339 | } 340 | 341 | mutating func readMapHeader(code: UInt8) async throws -> Int { 342 | switch code { 343 | case 0x80...0x8f: return Int(code - 0x80) 344 | case 0xde: return Int(try await read(UInt16.self)) 345 | case 0xdf: return Int(try await read(UInt32.self)) 346 | default: throw Error.invalidData 347 | } 348 | } 349 | 350 | mutating func readBinaryHeader(code: UInt8) async throws -> Int { 351 | switch code { 352 | case 0xc4: return Int(try await read(UInt8.self)) 353 | case 0xc5: return Int(try await read(UInt16.self)) 354 | case 0xc6: return Int(try await read(UInt32.self)) 355 | default: throw Error.invalidData 356 | } 357 | } 358 | 359 | mutating func readExtendedHeader(code: UInt8) async throws -> Int { 360 | switch code { 361 | case 0xd4: return 1 362 | case 0xd5: return 2 363 | case 0xd6: return 4 364 | case 0xd7: return 8 365 | case 0xd8: return 16 366 | case 0xc7: return Int(try await read(UInt8.self)) 367 | case 0xc8: return Int(try await read(UInt16.self)) 368 | case 0xc9: return Int(try await read(UInt32.self)) 369 | default: throw Error.invalidData 370 | } 371 | } 372 | } 373 | -------------------------------------------------------------------------------- /Sources/MessagePack/MessagePackWriter.swift: -------------------------------------------------------------------------------- 1 | import Stream 2 | 3 | public struct MessagePackWriter { 4 | public var stream: StreamWriter 5 | 6 | typealias Error = MessagePack.Error 7 | 8 | public init(_ stream: StreamWriter) { 9 | self.stream = stream 10 | } 11 | 12 | mutating func write(_ value: T) async throws { 13 | try await stream.write(value) 14 | } 15 | 16 | mutating func write(_ bytes: [UInt8]) async throws { 17 | try await stream.write(bytes) 18 | } 19 | } 20 | 21 | extension MessagePackWriter { 22 | mutating func write(code value: UInt8) async throws { 23 | try await write(value) 24 | } 25 | } 26 | 27 | // Encode 28 | 29 | extension MessagePackWriter { 30 | public mutating func encode(_ value: MessagePack) async throws { 31 | switch value { 32 | case .`nil`: try await encodeNil() 33 | case let .int(value): try await encode(Int64(value)) 34 | case let .uint(value): try await encode(UInt64(value)) 35 | case let .bool(value): try await encode(value) 36 | case let .string(value): try await encode(value) 37 | case let .float(value): try await encode(value) 38 | case let .double(value): try await encode(value) 39 | case let .array(value): try await encode(value) 40 | case let .map(value): try await encode(value) 41 | case let .binary(value): try await encode(value) 42 | case let .extended(value): try await encode(value) 43 | } 44 | } 45 | } 46 | 47 | extension MessagePackWriter { 48 | public mutating func encode(_ array: [MessagePack]) async throws { 49 | try await writeArrayHeader(count: array.count) 50 | for item in array { 51 | try await encode(item) 52 | } 53 | } 54 | 55 | public mutating func encode( 56 | _ map: [MessagePack: MessagePack] 57 | ) async throws { 58 | try await writeMapHeader(count: map.count) 59 | for (key, value) in map { 60 | try await encode(key) 61 | try await encode(value) 62 | } 63 | } 64 | 65 | public mutating func encodeArrayItemsCount(_ itemsCount: Int) async throws { 66 | try await writeArrayHeader(count: itemsCount) 67 | } 68 | 69 | public mutating func encodeMapItemsCount(_ itemsCount: Int) async throws { 70 | try await writeMapHeader(count: itemsCount) 71 | } 72 | 73 | public mutating func encodeNil() async throws { 74 | try await write(UInt8(0xc0)) 75 | } 76 | 77 | public mutating func encode(_ value: Int) async throws { 78 | try await encode(Int64(value)) 79 | } 80 | 81 | public mutating func encode(_ value: UInt) async throws { 82 | try await encode(UInt64(value)) 83 | } 84 | 85 | public mutating func encode(_ value: Bool) async throws { 86 | try await write(UInt8(value ? 0xc3 : 0xc2)) 87 | } 88 | 89 | public mutating func encode(_ value: Float) async throws { 90 | try await write(code: 0xca) 91 | try await write(value.bitPattern) 92 | } 93 | 94 | public mutating func encode(_ value: Double) async throws { 95 | try await write(code: 0xcb) 96 | try await write(value.bitPattern) 97 | } 98 | 99 | public mutating func encode(_ value: String) async throws { 100 | let utf8 = Array(value.utf8) 101 | try await writeStringHeader(count: utf8.count) 102 | try await write(utf8) 103 | } 104 | 105 | public mutating func encode(_ binary: [UInt8]) async throws { 106 | try await writeBinaryHeader(count: binary.count) 107 | try await write(binary) 108 | } 109 | 110 | public mutating func encode(_ extended: MessagePack.Extended) async throws { 111 | try await writeExtendedHeader( 112 | type: extended.type, 113 | count: extended.data.count) 114 | try await write(extended.data) 115 | } 116 | 117 | public mutating func encode(_ value: Int8) async throws { 118 | switch value { 119 | case value where value >= 0: 120 | try await encode(UInt8(bitPattern: value)) 121 | case value where value >= -0x20: 122 | try await write(code: 0xe0 + 0x1f & UInt8(bitPattern: value)) 123 | default: 124 | try await write(code: 0xd0) 125 | try await write(value) 126 | } 127 | } 128 | 129 | public mutating func encode(_ value: Int16) async throws { 130 | switch value { 131 | case let value where value >= 0: 132 | try await encode(UInt16(bitPattern: value)) 133 | case let value where value >= -0x7f: 134 | try await encode(Int8(truncatingIfNeeded: value)) 135 | default: 136 | try await write(code: 0xd1) 137 | try await write(value) 138 | } 139 | } 140 | 141 | public mutating func encode(_ value: Int32) async throws { 142 | switch value { 143 | case let value where value >= 0: 144 | try await encode(UInt32(bitPattern: value)) 145 | case let value where value >= -0x7fff: 146 | try await encode(Int16(truncatingIfNeeded: value)) 147 | default: 148 | try await write(code: 0xd2) 149 | try await write(value) 150 | } 151 | } 152 | 153 | public mutating func encode(_ value: Int64) async throws { 154 | switch value { 155 | case let value where value >= 0: 156 | try await encode(UInt64(bitPattern: value)) 157 | case let value where value >= -0x7fff_ffff: 158 | try await encode(Int32(truncatingIfNeeded: value)) 159 | default: 160 | try await write(code: 0xd3) 161 | try await write(value) 162 | } 163 | } 164 | 165 | public mutating func encode(_ value: UInt8) async throws { 166 | switch value { 167 | case let value where value <= 0x7f: 168 | try await write(UInt8(value)) 169 | default: 170 | try await write(code: 0xcc) 171 | try await write(value) 172 | } 173 | } 174 | 175 | public mutating func encode(_ value: UInt16) async throws { 176 | switch value { 177 | case let value where value <= 0xff: 178 | try await encode(UInt8(truncatingIfNeeded: value)) 179 | default: 180 | try await write(code: 0xcd) 181 | try await write(value) 182 | } 183 | } 184 | 185 | public mutating func encode(_ value: UInt32) async throws { 186 | switch value { 187 | case let value where value <= 0xffff: 188 | try await encode(UInt16(truncatingIfNeeded: value)) 189 | default: 190 | try await write(code: 0xce) 191 | try await write(value) 192 | } 193 | } 194 | 195 | public mutating func encode(_ value: UInt64) async throws { 196 | switch value { 197 | case let value where value <= 0xffff_ffff: 198 | try await encode(UInt32(truncatingIfNeeded: value)) 199 | default: 200 | try await write(code: 0xcf) 201 | try await write(value) 202 | } 203 | } 204 | 205 | public mutating func encode(array: [Bool]) async throws { 206 | try await writeArrayHeader(count: array.count) 207 | for item in array { try await encode(item) } 208 | } 209 | 210 | public mutating func encode(array: [Float]) async throws { 211 | try await writeArrayHeader(count: array.count) 212 | for item in array { try await encode(item) } 213 | } 214 | 215 | public mutating func encode(array: [Double]) async throws { 216 | try await writeArrayHeader(count: array.count) 217 | for item in array { try await encode(item) } 218 | } 219 | 220 | public mutating func encode(array: [String]) async throws { 221 | try await writeArrayHeader(count: array.count) 222 | for item in array { try await encode(item) } 223 | } 224 | 225 | public mutating func encode(array: [Int]) async throws { 226 | try await writeArrayHeader(count: array.count) 227 | for item in array { try await encode(item) } 228 | } 229 | 230 | public mutating func encode(array: [UInt]) async throws { 231 | try await writeArrayHeader(count: array.count) 232 | for item in array { try await encode(item) } 233 | } 234 | 235 | public mutating func encode(array: [Int8]) async throws { 236 | try await writeArrayHeader(count: array.count) 237 | for item in array { try await encode(item) } 238 | } 239 | 240 | public mutating func encode(array: [UInt8]) async throws { 241 | try await writeArrayHeader(count: array.count) 242 | for item in array { try await encode(item) } 243 | } 244 | 245 | public mutating func encode(array: [Int16]) async throws { 246 | try await writeArrayHeader(count: array.count) 247 | for item in array { try await encode(item) } 248 | } 249 | 250 | public mutating func encode(array: [UInt16]) async throws { 251 | try await writeArrayHeader(count: array.count) 252 | for item in array { try await encode(item) } 253 | } 254 | 255 | public mutating func encode(array: [Int32]) async throws { 256 | try await writeArrayHeader(count: array.count) 257 | for item in array { try await encode(item) } 258 | } 259 | 260 | public mutating func encode(array: [UInt32]) async throws { 261 | try await writeArrayHeader(count: array.count) 262 | for item in array { try await encode(item) } 263 | } 264 | 265 | public mutating func encode(array: [Int64]) async throws { 266 | try await writeArrayHeader(count: array.count) 267 | for item in array { try await encode(item) } 268 | } 269 | 270 | public mutating func encode(array: [UInt64]) async throws { 271 | try await writeArrayHeader(count: array.count) 272 | for item in array { try await encode(item) } 273 | } 274 | } 275 | 276 | // Headers 277 | 278 | extension MessagePackWriter { 279 | mutating func writeStringHeader(count: Int) async throws { 280 | switch count { 281 | case let count where count <= 0x19: 282 | try await write(code: 0xa0 | UInt8(count)) 283 | case let count where count <= 0xff: 284 | try await write(code: 0xd9) 285 | try await write(UInt8(count)) 286 | case let count where count <= 0xffff: 287 | try await write(code: 0xda) 288 | try await write(UInt16(count)) 289 | default: 290 | try await write(code: 0xdb) 291 | try await write(UInt32(count)) 292 | } 293 | } 294 | 295 | mutating func writeArrayHeader(count: Int) async throws { 296 | switch count { 297 | case let count where count <= 0xf: 298 | try await write(code: 0x90 | UInt8(count)) 299 | case let count where count <= 0xffff: 300 | try await write(code: 0xdc) 301 | try await write(UInt16(count)) 302 | default: 303 | try await write(code: 0xdd) 304 | try await write(UInt32(count)) 305 | } 306 | } 307 | 308 | mutating func writeMapHeader(count: Int) async throws { 309 | switch count { 310 | case let count where count <= 0xf: 311 | try await write(code: 0x80 | UInt8(count)) 312 | case let count where count <= 0xffff: 313 | try await write(code: 0xde) 314 | try await write(UInt16(count)) 315 | default: 316 | try await write(code: 0xdf) 317 | try await write(UInt32(count)) 318 | } 319 | } 320 | 321 | mutating func writeBinaryHeader(count: Int) async throws { 322 | switch count { 323 | case let count where count <= 0xff: 324 | try await write(code: 0xc4) 325 | try await write(UInt8(count)) 326 | case let count where count <= 0xffff: 327 | try await write(code: 0xc5) 328 | try await write(UInt16(count)) 329 | default: 330 | try await write(code: 0xc6) 331 | try await write(UInt32(count)) 332 | } 333 | } 334 | 335 | mutating func writeExtendedHeader(type: Int8, count: Int) async throws { 336 | let type = UInt8(bitPattern: type) 337 | switch count { 338 | case 1: 339 | try await write(code: 0xd4) 340 | case 2: 341 | try await write(code: 0xd5) 342 | case 4: 343 | try await write(code: 0xd6) 344 | case 8: 345 | try await write(code: 0xd7) 346 | case 16: 347 | try await write(code: 0xd8) 348 | case let count where count <= 0xff: 349 | try await write(code: 0xc7) 350 | try await write(UInt8(count)) 351 | case let count where count <= 0xffff: 352 | try await write(code: 0xc8) 353 | try await write(UInt16(count)) 354 | default: 355 | try await write(code: 0xc9) 356 | try await write(UInt32(count)) 357 | } 358 | try await write(type) 359 | } 360 | } 361 | -------------------------------------------------------------------------------- /Sources/MessagePack/Timestamp.swift: -------------------------------------------------------------------------------- 1 | import struct Foundation.Date 2 | 3 | public struct Timestamp: Equatable { 4 | public var seconds: Int 5 | public var nanoseconds: Int 6 | 7 | public init(seconds: Int, nanoseconds: Int) { 8 | self.seconds = seconds 9 | self.nanoseconds = nanoseconds 10 | } 11 | } 12 | 13 | extension MessagePackReader { 14 | public mutating func decode( 15 | _ type: Timestamp.Type 16 | ) async throws -> Timestamp { 17 | let `extension` = try await decode(MessagePack.Extended.self) 18 | guard `extension`.type == -1 else { 19 | throw Error.invalidData 20 | } 21 | 22 | let data = `extension`.data 23 | 24 | var seconds = 0 25 | var nanoseconds = 0 26 | 27 | switch data.count { 28 | case 4: 29 | // 32 bit 30 | seconds |= Int(data[0]) << 24 31 | seconds |= Int(data[1]) << 16 32 | seconds |= Int(data[2]) << 8 33 | seconds |= Int(data[3]) << 0 34 | case 8: 35 | // 30 bit, drop last 2 bit 36 | nanoseconds |= Int(data[0]) << 22 37 | nanoseconds |= Int(data[1]) << 14 38 | nanoseconds |= Int(data[2]) << 6 39 | nanoseconds |= Int(data[3]) >> 2 40 | // 34 bit 41 | seconds |= Int(data[3] & 0b0000_0011) << 32 42 | seconds |= Int(data[4]) << 24 43 | seconds |= Int(data[5]) << 16 44 | seconds |= Int(data[6]) << 8 45 | seconds |= Int(data[7]) << 0 46 | case 12: 47 | // 32 bit 48 | nanoseconds |= Int(data[0]) << 24 49 | nanoseconds |= Int(data[1]) << 16 50 | nanoseconds |= Int(data[2]) << 8 51 | nanoseconds |= Int(data[3]) << 0 52 | // 64 bit 53 | seconds |= Int(data[4]) << 56 54 | seconds |= Int(data[5]) << 48 55 | seconds |= Int(data[6]) << 40 56 | seconds |= Int(data[7]) << 32 57 | seconds |= Int(data[8]) << 24 58 | seconds |= Int(data[9]) << 16 59 | seconds |= Int(data[10]) << 8 60 | seconds |= Int(data[11]) << 0 61 | default: 62 | throw Error.invalidData 63 | } 64 | 65 | return Timestamp(seconds: seconds, nanoseconds: nanoseconds) 66 | } 67 | 68 | public mutating func decode( 69 | _ type: Date.Type 70 | ) async throws -> Date { 71 | let timestamp = try await decode(Timestamp.self) 72 | let timeInterval = Double(timestamp.seconds) + 73 | Double(timestamp.nanoseconds) / 1_000_000_000 74 | return Date(timeIntervalSince1970: timeInterval) 75 | } 76 | } 77 | 78 | extension MessagePackWriter { 79 | public mutating func encode(_ timestamp: Timestamp) async throws { 80 | var `extension` = MessagePack.Extended(type: -1, data: []) 81 | 82 | if timestamp.seconds >> 34 == 0 { 83 | if timestamp.nanoseconds == 0 && timestamp.seconds <= UInt32.max { 84 | var data = [UInt8](repeating: 0, count: 4) 85 | data[0] = UInt8(truncatingIfNeeded: timestamp.seconds >> 24) 86 | data[1] = UInt8(truncatingIfNeeded: timestamp.seconds >> 16) 87 | data[2] = UInt8(truncatingIfNeeded: timestamp.seconds >> 8) 88 | data[3] = UInt8(truncatingIfNeeded: timestamp.seconds >> 0) 89 | `extension`.data = data 90 | } else { 91 | guard timestamp.nanoseconds & ~0x3fff_ffff == 0, 92 | timestamp.seconds & ~0x0003_ffff_ffff == 0 else { 93 | throw Error.invalidData 94 | } 95 | var data = [UInt8](repeating: 0, count: 8) 96 | 97 | data[0] = UInt8(truncatingIfNeeded: timestamp.nanoseconds >> 22) 98 | data[1] = UInt8(truncatingIfNeeded: timestamp.nanoseconds >> 14) 99 | data[2] = UInt8(truncatingIfNeeded: timestamp.nanoseconds >> 6) 100 | data[3] = UInt8(truncatingIfNeeded: timestamp.nanoseconds << 2) 101 | 102 | data[3] |= UInt8(truncatingIfNeeded: timestamp.seconds >> 32) 103 | data[4] = UInt8(truncatingIfNeeded: timestamp.seconds >> 24) 104 | data[5] = UInt8(truncatingIfNeeded: timestamp.seconds >> 16) 105 | data[6] = UInt8(truncatingIfNeeded: timestamp.seconds >> 8) 106 | data[7] = UInt8(truncatingIfNeeded: timestamp.seconds >> 0) 107 | 108 | `extension`.data = data 109 | } 110 | } else { 111 | guard timestamp.nanoseconds <= UInt32.max else { 112 | throw Error.invalidData 113 | } 114 | var data = [UInt8](repeating: 0, count: 12) 115 | 116 | data[0] = UInt8(truncatingIfNeeded: timestamp.nanoseconds >> 24) 117 | data[1] = UInt8(truncatingIfNeeded: timestamp.nanoseconds >> 16) 118 | data[2] = UInt8(truncatingIfNeeded: timestamp.nanoseconds >> 8) 119 | data[3] = UInt8(truncatingIfNeeded: timestamp.nanoseconds >> 0) 120 | 121 | data[4] = UInt8(truncatingIfNeeded: timestamp.seconds >> 56) 122 | data[5] = UInt8(truncatingIfNeeded: timestamp.seconds >> 48) 123 | data[6] = UInt8(truncatingIfNeeded: timestamp.seconds >> 40) 124 | data[7] = UInt8(truncatingIfNeeded: timestamp.seconds >> 32) 125 | data[8] = UInt8(truncatingIfNeeded: timestamp.seconds >> 24) 126 | data[9] = UInt8(truncatingIfNeeded: timestamp.seconds >> 16) 127 | data[10] = UInt8(truncatingIfNeeded: timestamp.seconds >> 8) 128 | data[11] = UInt8(truncatingIfNeeded: timestamp.seconds >> 0) 129 | 130 | `extension`.data = data 131 | } 132 | try await encode(`extension`) 133 | } 134 | 135 | public mutating func encode(_ date: Date) async throws { 136 | let timeInterval = date.timeIntervalSince1970 137 | let seconds = Int(timeInterval) 138 | let nanoseconds = Int( 139 | timeInterval.truncatingRemainder(dividingBy: 1) * 1_000_000_000) 140 | try await encode(Timestamp(seconds: seconds, nanoseconds: nanoseconds)) 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Tests/Codable/KeyedDecodingContainer/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | @testable import MessagePack 3 | 4 | test("KeyedContainer") { 5 | let encoded: MessagePack = .map([ 6 | .string("nil"): .nil, 7 | .string("int"): .int(-1), 8 | .string("int8"): .int(-2), 9 | .string("int16"): .int(-3), 10 | .string("int32"): .int(-4), 11 | .string("int64"): .int(-5), 12 | .string("uint"): .uint(1), 13 | .string("uint8"): .uint(2), 14 | .string("uint16"): .uint(3), 15 | .string("uint32"): .uint(4), 16 | .string("uint64"): .uint(5), 17 | .int(42): .bool(true), 18 | .string("float"): .float(3.14), 19 | .string("double"): .double(3.14), 20 | .string("string"): .string("hi"), 21 | .string("array"): .array([.int(1), .int(2)]), 22 | .string("map"): .map([.int(1): .int(2)]), 23 | ]) 24 | 25 | enum Keys: CodingKey { 26 | case `nil` 27 | case bool 28 | case int, int8, int16, int32, int64 29 | case uint, uint8, uint16, uint32, uint64 30 | case float, double 31 | case string 32 | case array 33 | case map 34 | case extended 35 | 36 | var intValue: Int? { 37 | guard case .bool = self else { 38 | return nil 39 | } 40 | return 42 41 | } 42 | } 43 | 44 | let decoder = Decoder(encoded) 45 | let container = try decoder.container(keyedBy: Keys.self) 46 | 47 | expect(try container.decodeNil(forKey: .nil) == true) 48 | expect(try container.decode(Int.self, forKey: .int) == -1) 49 | expect(try container.decode(Int8.self, forKey: .int8) == -2) 50 | expect(try container.decode(Int16.self, forKey: .int16) == -3) 51 | expect(try container.decode(Int32.self, forKey: .int32) == -4) 52 | expect(try container.decode(Int64.self, forKey: .int64) == -5) 53 | expect(try container.decode(UInt.self, forKey: .uint) == 1) 54 | expect(try container.decode(UInt8.self, forKey: .uint8) == 2) 55 | expect(try container.decode(UInt16.self, forKey: .uint16) == 3) 56 | expect(try container.decode(UInt32.self, forKey: .uint32) == 4) 57 | expect(try container.decode(UInt64.self, forKey: .uint64) == 5) 58 | expect(try container.decode(Bool.self, forKey: .bool) == true) 59 | expect(try container.decode(Float.self, forKey: .float) == 3.14) 60 | expect(try container.decode(Double.self, forKey: .double) == 3.14) 61 | expect(try container.decode(String.self, forKey: .string) == "hi") 62 | expect(try container.decode([Int].self, forKey: .array) == [1, 2]) 63 | expect(try container.decode([Int: Int].self, forKey: .map) == [1: 2]) 64 | } 65 | 66 | test("NestedKeyedContainer") { 67 | let encoded: MessagePack = .map([ 68 | .string("one"): .int(1), 69 | .string("nested"): .map([ 70 | .string("two"): .int(2) 71 | ]), 72 | .string("three"): .int(3) 73 | ]) 74 | 75 | enum One: CodingKey { 76 | case one 77 | case nested 78 | case three 79 | } 80 | 81 | enum Two: CodingKey { 82 | case two 83 | } 84 | 85 | let decoder = Decoder(encoded) 86 | let container = try decoder.container(keyedBy: One.self) 87 | expect(try container.decode(Int.self, forKey: .one) == 1) 88 | 89 | let nested = try container.nestedContainer( 90 | keyedBy: Two.self, forKey: .nested) 91 | expect(try nested.decode(Int.self, forKey: .two) == 2) 92 | 93 | expect(try container.decode(Int.self, forKey: .three) == 3) 94 | } 95 | 96 | test("NestedUnkeyedContainer") { 97 | let encoded: MessagePack = .map([ 98 | .string("one"): .int(1), 99 | .string("nested"): .array([.int(2)]), 100 | .string("three"): .int(3) 101 | ]) 102 | 103 | enum One: CodingKey { 104 | case one 105 | case nested 106 | case three 107 | } 108 | 109 | enum Two: CodingKey { 110 | case two 111 | } 112 | 113 | let decoder = Decoder(encoded) 114 | let container = try decoder.container(keyedBy: One.self) 115 | expect(try container.decode(Int.self, forKey: .one) == 1) 116 | 117 | var nested = try container.nestedUnkeyedContainer(forKey: .nested) 118 | expect(try nested.decode(Int.self) == 2) 119 | 120 | expect(try container.decode(Int.self, forKey: .three) == 3) 121 | } 122 | 123 | await run() 124 | -------------------------------------------------------------------------------- /Tests/Codable/KeyedEncodingContainer/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | @testable import MessagePack 3 | 4 | test("KeyedContainer") { 5 | let expected: MessagePack = .map([ 6 | .string("nil"): .nil, 7 | .string("int"): .int(-1), 8 | .string("int8"): .int(-2), 9 | .string("int16"): .int(-3), 10 | .string("int32"): .int(-4), 11 | .string("int64"): .int(-5), 12 | .string("uint"): .uint(1), 13 | .string("uint8"): .uint(2), 14 | .string("uint16"): .uint(3), 15 | .string("uint32"): .uint(4), 16 | .string("uint64"): .uint(5), 17 | .int(42): .bool(true), 18 | .string("float"): .float(3.14), 19 | .string("double"): .double(3.14), 20 | .string("string"): .string("hello"), 21 | .string("array"): .array([.int(1), .int(2)]), 22 | .string("map"): .map([.int(1): .int(2)]), 23 | ]) 24 | 25 | enum Keys: CodingKey { 26 | case `nil` 27 | case bool 28 | case int, int8, int16, int32, int64 29 | case uint, uint8, uint16, uint32, uint64 30 | case float, double 31 | case string 32 | case array 33 | case map 34 | case extended 35 | 36 | var intValue: Int? { 37 | guard case .bool = self else { 38 | return nil 39 | } 40 | return 42 41 | } 42 | } 43 | 44 | let encoder = Encoder() 45 | var container = encoder.container(keyedBy: Keys.self) 46 | 47 | try container.encodeNil(forKey: .nil) 48 | try container.encode(Int(-1), forKey: .int) 49 | try container.encode(Int8(-2), forKey: .int8) 50 | try container.encode(Int16(-3), forKey: .int16) 51 | try container.encode(Int32(-4), forKey: .int32) 52 | try container.encode(Int64(-5), forKey: .int64) 53 | try container.encode(UInt(1), forKey: .uint) 54 | try container.encode(UInt8(2), forKey: .uint8) 55 | try container.encode(UInt16(3), forKey: .uint16) 56 | try container.encode(UInt32(4), forKey: .uint32) 57 | try container.encode(UInt64(5), forKey: .uint64) 58 | try container.encode(true, forKey: .bool) 59 | try container.encode(Float(3.14), forKey: .float) 60 | try container.encode(Double(3.14), forKey: .double) 61 | try container.encode("hello", forKey: .string) 62 | try container.encode([1, 2], forKey: .array) 63 | try container.encode([1: 2], forKey: .map) 64 | 65 | expect(encoder.value == expected) 66 | } 67 | 68 | test("NestedKeyedContainer") { 69 | let expected: MessagePack = .map([ 70 | .string("one"): .int(1), 71 | .string("nested"): .map([ 72 | .string("two"): .int(2) 73 | ]), 74 | .string("three"): .int(3) 75 | ]) 76 | 77 | enum One: CodingKey { 78 | case one 79 | case nested 80 | case three 81 | } 82 | 83 | enum Two: CodingKey { 84 | case two 85 | } 86 | 87 | let encoder = Encoder() 88 | var container = encoder.container(keyedBy: One.self) 89 | try container.encode(1, forKey: .one) 90 | 91 | var nested = container.nestedContainer( 92 | keyedBy: Two.self, forKey: .nested) 93 | try nested.encode(2, forKey: .two) 94 | 95 | try container.encode(3, forKey: .three) 96 | 97 | expect(encoder.value == expected) 98 | } 99 | 100 | test("NestedUnkeyedContainer") { 101 | let expected: MessagePack = .map([ 102 | .string("one"): .int(1), 103 | .string("nested"): .array([.int(2)]), 104 | .string("three"): .int(3) 105 | ]) 106 | 107 | enum One: CodingKey { 108 | case one 109 | case nested 110 | case three 111 | } 112 | 113 | enum Two: CodingKey { 114 | case two 115 | } 116 | 117 | let encoder = Encoder() 118 | var container = encoder.container(keyedBy: One.self) 119 | try container.encode(1, forKey: .one) 120 | 121 | var nested = container.nestedUnkeyedContainer(forKey: .nested) 122 | try nested.encode(2) 123 | 124 | try container.encode(3, forKey: .three) 125 | 126 | expect(encoder.value == expected) 127 | } 128 | 129 | await run() 130 | -------------------------------------------------------------------------------- /Tests/Codable/MessagePackCoders/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | @testable import MessagePack 3 | 4 | test("Encodable") { 5 | struct Model: Encodable { 6 | let int: Int 7 | let string: String 8 | let array: [Int] 9 | } 10 | let expected: MessagePack = .map([ 11 | .string("int"): .int(42), 12 | .string("string"): .string("hello"), 13 | .string("array"): .array([.int(1), .int(2)]) 14 | ]) 15 | 16 | let model = Model(int: 42, string: "hello", array: [1, 2]) 17 | let encoder = Encoder() 18 | try model.encode(to: encoder) 19 | expect(encoder.value == expected) 20 | } 21 | 22 | test("Decodable") { 23 | struct Model: Decodable { 24 | let int: Int 25 | let string: String 26 | let array: [Int] 27 | } 28 | let encoded: MessagePack = .map([ 29 | .string("int"): .int(42), 30 | .string("string"): .string("hello"), 31 | .string("array"): .array([.int(1), .int(2)]) 32 | ]) 33 | 34 | let decoder = Decoder(encoded) 35 | let decoded = try Model(from: decoder) 36 | 37 | expect(decoded.int == 42) 38 | expect(decoded.string == "hello") 39 | expect(decoded.array == [1, 2]) 40 | } 41 | 42 | await run() 43 | -------------------------------------------------------------------------------- /Tests/Codable/UnkeyedDecodingContainer/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | @testable import MessagePack 3 | 4 | test("UnkeyedContainer") { 5 | let encoded: MessagePack = .array([ 6 | MessagePack.`nil`, 7 | MessagePack.int(-1), 8 | MessagePack.int(-2), 9 | MessagePack.int(-3), 10 | MessagePack.int(-4), 11 | MessagePack.int(-5), 12 | MessagePack.uint(1), 13 | MessagePack.uint(2), 14 | MessagePack.uint(3), 15 | MessagePack.uint(4), 16 | MessagePack.uint(5), 17 | MessagePack.bool(true), 18 | MessagePack.float(3.14), 19 | MessagePack.double(3.14), 20 | MessagePack.string("hello"), 21 | MessagePack.array([.int(1), .int(2)]), 22 | MessagePack.map([.int(1): .int(2)]) 23 | ]) 24 | 25 | let decoder = Decoder(encoded) 26 | var container = try decoder.unkeyedContainer() 27 | 28 | expect(try container.decodeNil() == true) 29 | expect(try container.decode(Int.self) == -1) 30 | expect(try container.decode(Int8.self) == -2) 31 | expect(try container.decode(Int16.self) == -3) 32 | expect(try container.decode(Int32.self) == -4) 33 | expect(try container.decode(Int64.self) == -5) 34 | expect(try container.decode(UInt.self) == 1) 35 | expect(try container.decode(UInt8.self) == 2) 36 | expect(try container.decode(UInt16.self) == 3) 37 | expect(try container.decode(UInt32.self) == 4) 38 | expect(try container.decode(UInt64.self) == 5) 39 | expect(try container.decode(Bool.self) == true) 40 | expect(try container.decode(Float.self) == 3.14) 41 | expect(try container.decode(Double.self) == 3.14) 42 | expect(try container.decode(String.self) == "hello") 43 | expect(try container.decode([Int].self) == [1, 2]) 44 | expect(try container.decode([Int: Int].self) == [1: 2]) 45 | } 46 | 47 | test("NestedKeyedContainer") { 48 | let encoded: MessagePack = .array([ 49 | .int(1), 50 | .map([ 51 | .string("nested"): .int(2) 52 | ]), 53 | .int(3) 54 | ]) 55 | 56 | enum One: CodingKey { 57 | case nested 58 | } 59 | 60 | let decoder = Decoder(encoded) 61 | var container = try decoder.unkeyedContainer() 62 | expect(try container.decode(Int.self) == 1) 63 | 64 | let nested = try container.nestedContainer(keyedBy: One.self) 65 | expect(try nested.decode(Int.self, forKey: .nested) == 2) 66 | 67 | expect(try container.decode(Int.self) == 3) 68 | } 69 | 70 | test("NestedUnkeyedContainer") { 71 | let encoded: MessagePack = .array([ 72 | .int(1), 73 | .array([.int(2)]), 74 | .int(3) 75 | ]) 76 | 77 | let decoder = Decoder(encoded) 78 | var container = try decoder.unkeyedContainer() 79 | expect(try container.decode(Int.self) == 1) 80 | 81 | var nested = try container.nestedUnkeyedContainer() 82 | expect(try nested.decode(Int.self) == 2) 83 | 84 | expect(try container.decode(Int.self) == 3) 85 | } 86 | 87 | await run() 88 | -------------------------------------------------------------------------------- /Tests/Codable/UnkeyedEncodingContainer/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | @testable import MessagePack 3 | 4 | test("UnkeyedContainer") { 5 | let expected: MessagePack = .array([ 6 | MessagePack.`nil`, 7 | MessagePack.int(-1), 8 | MessagePack.int(-2), 9 | MessagePack.int(-3), 10 | MessagePack.int(-4), 11 | MessagePack.int(-5), 12 | MessagePack.uint(1), 13 | MessagePack.uint(2), 14 | MessagePack.uint(3), 15 | MessagePack.uint(4), 16 | MessagePack.uint(5), 17 | MessagePack.bool(true), 18 | MessagePack.float(3.14), 19 | MessagePack.double(3.14), 20 | MessagePack.string("hello"), 21 | MessagePack.array([.int(1), .int(2)]), 22 | MessagePack.map([.int(1): .int(2)]) 23 | ]) 24 | 25 | let encoder = Encoder() 26 | var container = encoder.unkeyedContainer() 27 | 28 | try container.encodeNil() 29 | try container.encode(Int(-1)) 30 | try container.encode(Int8(-2)) 31 | try container.encode(Int16(-3)) 32 | try container.encode(Int32(-4)) 33 | try container.encode(Int64(-5)) 34 | try container.encode(UInt(1)) 35 | try container.encode(UInt8(2)) 36 | try container.encode(UInt16(3)) 37 | try container.encode(UInt32(4)) 38 | try container.encode(UInt64(5)) 39 | try container.encode(true) 40 | try container.encode(Float(3.14)) 41 | try container.encode(Double(3.14)) 42 | try container.encode("hello") 43 | try container.encode([1, 2]) 44 | try container.encode([1: 2]) 45 | 46 | expect(encoder.value == expected) 47 | } 48 | 49 | test("NestedKeyedContainer") { 50 | let expected: MessagePack = .array([ 51 | .int(1), 52 | .map([ 53 | .string("nested"): .int(2) 54 | ]), 55 | .int(3) 56 | ]) 57 | 58 | enum One: CodingKey { 59 | case nested 60 | } 61 | 62 | let encoder = Encoder() 63 | var container = encoder.unkeyedContainer() 64 | try container.encode(1) 65 | 66 | var nested = container.nestedContainer(keyedBy: One.self) 67 | try nested.encode(2, forKey: .nested) 68 | 69 | try container.encode(3) 70 | 71 | expect(encoder.value == expected) 72 | } 73 | 74 | test("NestedUnkeyedContainer") { 75 | let expected: MessagePack = .array([ 76 | .int(1), 77 | .array([.int(2)]), 78 | .int(3) 79 | ]) 80 | 81 | let encoder = Encoder() 82 | var container = encoder.unkeyedContainer() 83 | try container.encode(1) 84 | 85 | var nested = container.nestedUnkeyedContainer() 86 | try nested.encode(2) 87 | 88 | try container.encode(3) 89 | 90 | expect(encoder.value == expected) 91 | } 92 | 93 | await run() 94 | -------------------------------------------------------------------------------- /Tests/Coding/Array/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | import MessagePack 3 | 4 | test("EncodeFixArray") { 5 | let expected: [UInt8] = [0x93, 0x01, 0x02, 0x03] 6 | let encoded = try await MessagePack.encode( 7 | .array([.int(1), .int(2), .int(3)])) 8 | expect(encoded == expected) 9 | } 10 | 11 | test("DecodeFixarray") { 12 | let expected = MessagePack.array([.uint(1), .uint(2), .uint(3)]) 13 | let decoded = try await MessagePack.decode(bytes: [0x93, 0x01, 0x02, 0x03]) 14 | expect(decoded == expected) 15 | } 16 | 17 | test("EncodeArray16") { 18 | let expected = 19 | [0xdc, 0xff, 0xff] + [UInt8](repeating: 0xc0, count: Int(UInt16.max)) 20 | let encoded = try await MessagePack.encode( 21 | .array([MessagePack](repeating: nil, count: Int(UInt16.max)))) 22 | expect(encoded == expected) 23 | } 24 | 25 | test("DecodeArray16") { 26 | let expected = MessagePack.array( 27 | [MessagePack](repeating: nil, count: Int(UInt16.max))) 28 | let decoded = try await MessagePack.decode( 29 | bytes: [0xdc, 0xff, 0xff] 30 | + [UInt8](repeating: 0xc0, count: Int(UInt16.max))) 31 | expect(decoded == expected) 32 | } 33 | 34 | test("EncodeArray32") { 35 | let expected = 36 | [0xdd, 0x00, 0x01, 0x00, 0x00] + 37 | [UInt8](repeating: 0xc0, count: Int(UInt16.max)+1) 38 | let encoded = try await MessagePack.encode( 39 | .array([MessagePack](repeating: nil, count: Int(UInt16.max)+1))) 40 | expect(encoded == expected) 41 | } 42 | 43 | test("DecodeArray32") { 44 | let expected = MessagePack.array( 45 | [MessagePack](repeating: nil, count: Int(UInt16.max)+1)) 46 | let decoded = try await MessagePack.decode( 47 | bytes: [0xdd, 0x00, 0x01, 0x00, 0x00] + 48 | [UInt8](repeating: 0xc0, count: Int(UInt16.max)+1)) 49 | expect(decoded == expected) 50 | } 51 | 52 | test("EmptyArray") { 53 | let arrayArray: [[UInt8]] = [ 54 | [0x90], 55 | [0xdc, 0x00, 0x00], 56 | [0xdd, 0x00, 0x00, 0x00, 0x00] 57 | ] 58 | for bytes in arrayArray { 59 | let object = try await MessagePack.decode(bytes: bytes) 60 | expect(object.arrayValue == []) 61 | } 62 | } 63 | 64 | test("FixArraySize") { 65 | let items = [MessagePack](repeating: .int(1), count: 15) 66 | let bytes = try await MessagePack.encode(.array(items)) 67 | expect(bytes.count == 16) 68 | } 69 | 70 | await run() 71 | -------------------------------------------------------------------------------- /Tests/Coding/Binary/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | import MessagePack 3 | 4 | test("EncodeBin8") { 5 | let raw = [UInt8](repeating: 0x45, count: Int(UInt8.max)) 6 | let expected = [0xc4, 0xff] + raw 7 | let encoded = try await MessagePack.encode(.binary(raw)) 8 | expect(encoded == expected) 9 | } 10 | 11 | test("DecodeBin8") { 12 | let raw = [UInt8](repeating: 0x45, count: Int(UInt8.max)) 13 | let expected = MessagePack.binary(raw) 14 | let decoded = try await MessagePack.decode(bytes: [0xc4, 0xff] + raw) 15 | expect(decoded == expected) 16 | } 17 | 18 | test("EncodeBin16") { 19 | let raw = [UInt8](repeating: 0x45, count: Int(UInt16.max)) 20 | let expected = [0xc5, 0xff, 0xff] + raw 21 | let encoded = try await MessagePack.encode(.binary(raw)) 22 | expect(encoded == expected) 23 | } 24 | 25 | test("DecodeBin16") { 26 | let raw = [UInt8](repeating: 0x45, count: Int(UInt16.max)) 27 | let expected = MessagePack.binary(raw) 28 | let decoded = try await MessagePack.decode(bytes: [0xc5, 0xff, 0xff] + raw) 29 | expect(decoded == expected) 30 | } 31 | 32 | test("EncodeBin32") { 33 | let raw = [UInt8](repeating: 0x45, count: Int(UInt16.max)+1) 34 | let expected = [0xc6, 0x00, 0x01, 0x00, 0x00] + raw 35 | let encoded = try await MessagePack.encode(.binary(raw)) 36 | expect(encoded == expected) 37 | } 38 | 39 | test("DecodeBin32") { 40 | let raw = [UInt8](repeating: 0x45, count: Int(UInt16.max)+1) 41 | let expected = MessagePack.binary(raw) 42 | let decoded = try await MessagePack 43 | .decode(bytes: [0xc6, 0x00, 0x01, 0x00, 0x00] + raw) 44 | expect(decoded == expected) 45 | } 46 | 47 | test("EmptyBinary") { 48 | let binArray: [[UInt8]] = [ 49 | [0xc4, 0x00], 50 | [0xc5, 0x00, 0x00], 51 | [0xc6, 0x00, 0x00, 0x00, 0x00] 52 | ] 53 | for bytes in binArray { 54 | let object = try await MessagePack.decode(bytes: bytes) 55 | expect(object.binaryValue == []) 56 | } 57 | } 58 | 59 | await run() 60 | -------------------------------------------------------------------------------- /Tests/Coding/Bool/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | import MessagePack 3 | 4 | test("EncodeBoolFalse") { 5 | let expected: [UInt8] = [0xc2] 6 | let encoded = try await MessagePack.encode(.bool(false)) 7 | expect(encoded == expected) 8 | } 9 | 10 | test("DecodeBoolFalse") { 11 | let expected = MessagePack.bool(false) 12 | let decoded = try await MessagePack.decode(bytes: [0xc2]) 13 | expect(decoded == expected) 14 | } 15 | 16 | test("EncodeBoolTrue") { 17 | let expected: [UInt8] = [0xc3] 18 | let encoded = try await MessagePack.encode(.bool(true)) 19 | expect(encoded == expected) 20 | } 21 | 22 | test("DecodeBoolTrue") { 23 | let expected = MessagePack.bool(true) 24 | let decoded = try await MessagePack.decode(bytes: [0xc3]) 25 | expect(decoded == expected) 26 | } 27 | 28 | await run() 29 | -------------------------------------------------------------------------------- /Tests/Coding/Decode/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | import Stream 3 | import MessagePack 4 | 5 | test("Bool") { 6 | let expected = true 7 | let encoded = try await MessagePack.encode(.bool(expected)) 8 | var reader = MessagePackReader(InputByteStream(encoded)) 9 | let decoded = try await reader.decode(Bool.self) 10 | expect(decoded == expected) 11 | } 12 | 13 | test("Float") { 14 | let expected = Float(1.618) 15 | let encoded = try await MessagePack.encode(.float(expected)) 16 | var reader = MessagePackReader(InputByteStream(encoded)) 17 | let decoded = try await reader.decode(Float.self) 18 | expect(decoded == expected) 19 | } 20 | 21 | test("Double") { 22 | let expected = Double(1.618) 23 | let encoded = try await MessagePack.encode(.double(expected)) 24 | var reader = MessagePackReader(InputByteStream(encoded)) 25 | let decoded = try await reader.decode(Double.self) 26 | expect(decoded == expected) 27 | } 28 | 29 | test("String") { 30 | let expected = "Hello, World!" 31 | let encoded = try await MessagePack.encode(.string(expected)) 32 | var reader = MessagePackReader(InputByteStream(encoded)) 33 | let decoded = try await reader.decode(String.self) 34 | expect(decoded == expected) 35 | } 36 | 37 | test("Int") { 38 | let expected = Int.min 39 | let encoded = try await MessagePack.encode(.int(expected)) 40 | var reader = MessagePackReader(InputByteStream(encoded)) 41 | let decoded = try await reader.decode(Int.self) 42 | expect(decoded == expected) 43 | } 44 | 45 | test("UInt") { 46 | let expected = UInt.max 47 | let encoded = try await MessagePack.encode(.uint(expected)) 48 | var reader = MessagePackReader(InputByteStream(encoded)) 49 | let decoded = try await reader.decode(UInt.self) 50 | expect(decoded == expected) 51 | } 52 | 53 | test("UIntToInt") { 54 | let expected: UInt = 1 55 | let encoded = try await MessagePack.encode(.uint(expected)) 56 | var reader = MessagePackReader(InputByteStream(encoded)) 57 | let decoded = try await reader.decode(Int.self) 58 | expect(UInt(decoded) == expected) 59 | } 60 | 61 | test("UIntMaxToInt") { 62 | let expected = UInt.max 63 | let encoded = try await MessagePack.encode(.uint(expected)) 64 | var reader = MessagePackReader(InputByteStream(encoded)) 65 | await expect(throws: MessagePack.Error.invalidData) { 66 | try await reader.decode(Int.self) 67 | } 68 | } 69 | 70 | test("Binary") { 71 | let expected: [UInt8] = [0x01, 0x02, 0x03] 72 | let encoded = try await MessagePack.encode(.binary(expected)) 73 | var reader = MessagePackReader(InputByteStream(encoded)) 74 | let decoded = try await reader.decode([UInt8].self) 75 | expect(decoded == expected) 76 | } 77 | 78 | test("Array") { 79 | let expected: [MessagePack] = [.string("Hello"), .string("World")] 80 | let encoded = try await MessagePack.encode(.array(expected)) 81 | var reader = MessagePackReader(InputByteStream(encoded)) 82 | let decoded = try await reader.decode([MessagePack].self) 83 | expect(decoded == expected) 84 | } 85 | 86 | test("Map") { 87 | typealias Map = [MessagePack: MessagePack] 88 | let expected: Map = [.string("Hello"): .string("World")] 89 | let encoded = try await MessagePack.encode(.map(expected)) 90 | var reader = MessagePackReader(InputByteStream(encoded)) 91 | let decoded = try await reader.decode(Map.self) 92 | expect(decoded == expected) 93 | } 94 | 95 | test("Extended") { 96 | let expected = MessagePack.Extended( 97 | type: 1, data: [0x01, 0x02, 0x03]) 98 | let encoded = try await MessagePack.encode(.extended(expected)) 99 | var reader = MessagePackReader(InputByteStream(encoded)) 100 | let decoded = try await reader.decode(MessagePack.Extended.self) 101 | expect(decoded == expected) 102 | } 103 | 104 | await run() 105 | -------------------------------------------------------------------------------- /Tests/Coding/EncodeArray/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | import Stream 3 | import MessagePack 4 | 5 | test("EncodeBoolArray") { 6 | let booleans: [Bool] = [true, false] 7 | let expected: [UInt8] = [0x92, 0xc3, 0xc2] 8 | 9 | let stream = OutputByteStream() 10 | var writer = MessagePackWriter(stream) 11 | try await writer.encode(array: booleans) 12 | 13 | expect(stream.bytes == expected) 14 | } 15 | 16 | test("EncodeUIntArray") { 17 | let bytes: [UInt] = [0x01, 0x02, 0x03] 18 | let expected: [UInt8] = [0x93, 0x01, 0x02, 0x03] 19 | 20 | let stream = OutputByteStream() 21 | var writer = MessagePackWriter(stream) 22 | try await writer.encode(array: bytes) 23 | 24 | expect(stream.bytes == expected) 25 | } 26 | 27 | test("EncodeUInt8Array") { 28 | let bytes: [UInt8] = [0x01, 0x02, 0x03] 29 | let expected: [UInt8] = [0x93, 0x01, 0x02, 0x03] 30 | 31 | let stream = OutputByteStream() 32 | var writer = MessagePackWriter(stream) 33 | try await writer.encode(array: bytes) 34 | 35 | expect(stream.bytes == expected) 36 | } 37 | 38 | test("EncodeUInt16Array") { 39 | let bytes: [UInt16] = [0x01, 0x02, 0x03] 40 | let expected: [UInt8] = [0x93, 0x01, 0x02, 0x03] 41 | 42 | let stream = OutputByteStream() 43 | var writer = MessagePackWriter(stream) 44 | try await writer.encode(array: bytes) 45 | 46 | expect(stream.bytes == expected) 47 | } 48 | 49 | test("EncodeUInt32Array") { 50 | let bytes: [UInt32] = [0x01, 0x02, 0x03] 51 | let expected: [UInt8] = [0x93, 0x01, 0x02, 0x03] 52 | 53 | let stream = OutputByteStream() 54 | var writer = MessagePackWriter(stream) 55 | try await writer.encode(array: bytes) 56 | 57 | expect(stream.bytes == expected) 58 | } 59 | 60 | test("EncodeUInt64Array") { 61 | let bytes: [UInt64] = [0x01, 0x02, 0x03] 62 | let expected: [UInt8] = [0x93, 0x01, 0x02, 0x03] 63 | 64 | let stream = OutputByteStream() 65 | var writer = MessagePackWriter(stream) 66 | try await writer.encode(array: bytes) 67 | 68 | expect(stream.bytes == expected) 69 | } 70 | 71 | test("EncodeIntArray") { 72 | let bytes: [Int] = [0x01, 0x02, 0x03] 73 | let expected: [UInt8] = [0x93, 0x01, 0x02, 0x03] 74 | 75 | let stream = OutputByteStream() 76 | var writer = MessagePackWriter(stream) 77 | try await writer.encode(array: bytes) 78 | 79 | expect(stream.bytes == expected) 80 | } 81 | 82 | test("EncodeInt8Array") { 83 | let bytes: [Int8] = [0x01, 0x02, 0x03] 84 | let expected: [UInt8] = [0x93, 0x01, 0x02, 0x03] 85 | 86 | let stream = OutputByteStream() 87 | var writer = MessagePackWriter(stream) 88 | try await writer.encode(array: bytes) 89 | 90 | expect(stream.bytes == expected) 91 | } 92 | 93 | test("EncodeInt16Array") { 94 | let bytes: [Int16] = [0x01, 0x02, 0x03] 95 | let expected: [UInt8] = [0x93, 0x01, 0x02, 0x03] 96 | 97 | let stream = OutputByteStream() 98 | var writer = MessagePackWriter(stream) 99 | try await writer.encode(array: bytes) 100 | 101 | expect(stream.bytes == expected) 102 | } 103 | 104 | test("EncodeInt32Array") { 105 | let bytes: [Int32] = [0x01, 0x02, 0x03] 106 | let expected: [UInt8] = [0x93, 0x01, 0x02, 0x03] 107 | 108 | let stream = OutputByteStream() 109 | var writer = MessagePackWriter(stream) 110 | try await writer.encode(array: bytes) 111 | 112 | expect(stream.bytes == expected) 113 | } 114 | 115 | test("EncodeInt64Array") { 116 | let bytes: [Int64] = [0x01, 0x02, 0x03] 117 | let expected: [UInt8] = [0x93, 0x01, 0x02, 0x03] 118 | 119 | let stream = OutputByteStream() 120 | var writer = MessagePackWriter(stream) 121 | try await writer.encode(array: bytes) 122 | 123 | expect(stream.bytes == expected) 124 | } 125 | 126 | await run() 127 | -------------------------------------------------------------------------------- /Tests/Coding/Extended/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | import MessagePack 3 | 4 | test("EncodeFixExt1") { 5 | let raw = [UInt8](repeating: 0x45, count: 1) 6 | let expected: [UInt8] = [0xd4, 0x01] + raw 7 | let encoded = try await MessagePack.encode(.extended( 8 | MessagePack.Extended(type: 1, data: raw))) 9 | expect(encoded == expected) 10 | } 11 | 12 | test("DecodeFixExt1") { 13 | let raw = [UInt8](repeating: 0x45, count: 1) 14 | let expected = MessagePack.extended( 15 | MessagePack.Extended(type: 1, data: raw)) 16 | let decoded = try await MessagePack.decode(bytes: [0xd4, 0x01] + raw) 17 | expect(decoded == expected) 18 | } 19 | 20 | test("EncodeFixExt2") { 21 | let raw = [UInt8](repeating: 0x45, count: 2) 22 | let expected: [UInt8] = [0xd5, 0x01] + raw 23 | let encoded = try await MessagePack.encode(.extended( 24 | MessagePack.Extended(type: 1, data: raw))) 25 | expect(encoded == expected) 26 | } 27 | 28 | test("DecodeFixExt2") { 29 | let raw = [UInt8](repeating: 0x45, count: 2) 30 | let expected = MessagePack.extended( 31 | MessagePack.Extended(type: 1, data: raw)) 32 | let decoded = try await MessagePack.decode(bytes: [0xd5, 0x01] + raw) 33 | expect(decoded == expected) 34 | } 35 | 36 | test("EncodeFixExt4") { 37 | let raw = [UInt8](repeating: 0x45, count: 4) 38 | let expected: [UInt8] = [0xd6, 0x01] + raw 39 | let encoded = try await MessagePack.encode(.extended( 40 | MessagePack.Extended(type: 1, data: raw))) 41 | expect(encoded == expected) 42 | } 43 | 44 | test("DecodeFixExt4") { 45 | let raw = [UInt8](repeating: 0x45, count: 4) 46 | let expected = MessagePack.extended( 47 | MessagePack.Extended(type: 1, data: raw)) 48 | let decoded = try await MessagePack.decode(bytes: [0xd6, 0x01] + raw) 49 | expect(decoded == expected) 50 | } 51 | 52 | test("EncodeFixExt8") { 53 | let raw = [UInt8](repeating: 0x45, count: 8) 54 | let expected: [UInt8] = [0xd7, 0x01] + raw 55 | let encoded = try await MessagePack.encode(.extended( 56 | MessagePack.Extended(type: 1, data: raw))) 57 | expect(encoded == expected) 58 | } 59 | 60 | test("DecodeFixExt8") { 61 | let raw = [UInt8](repeating: 0x45, count: 8) 62 | let expected = MessagePack.extended( 63 | MessagePack.Extended(type: 1, data: raw)) 64 | let decoded = try await MessagePack.decode(bytes: [0xd7, 0x01] + raw) 65 | expect(decoded == expected) 66 | } 67 | 68 | test("EncodeFixExt16") { 69 | let raw = [UInt8](repeating: 0x45, count: 16) 70 | let expected: [UInt8] = [0xd8, 0x01] + raw 71 | let encoded = try await MessagePack.encode(.extended( 72 | MessagePack.Extended(type: 1, data: raw))) 73 | expect(encoded == expected) 74 | } 75 | 76 | test("DecodeFixExt16") { 77 | let raw = [UInt8](repeating: 0x45, count: 16) 78 | let expected = MessagePack.extended( 79 | MessagePack.Extended(type: 1, data: raw)) 80 | let decoded = try await MessagePack.decode(bytes: [0xd8, 0x01] + raw) 81 | expect(decoded == expected) 82 | } 83 | 84 | test("EncodeExt8") { 85 | let raw = [UInt8](repeating: 0x45, count: Int(UInt8.max)) 86 | let expected: [UInt8] = [0xc7, 0xff, 0x01] + raw 87 | let encoded = try await MessagePack.encode(.extended( 88 | MessagePack.Extended(type: 1, data: raw))) 89 | expect(encoded == expected) 90 | } 91 | 92 | test("DecodeExt8") { 93 | let raw = [UInt8](repeating: 0x45, count: Int(UInt8.max)) 94 | let expected = MessagePack.extended( 95 | MessagePack.Extended(type: 1, data: raw)) 96 | let decoded = try await MessagePack.decode( 97 | bytes: [0xc7, 0xff, 0x01] + raw) 98 | expect(decoded == expected) 99 | } 100 | 101 | test("EncodeExt16") { 102 | let raw = [UInt8](repeating: 0x45, count: Int(UInt16.max)) 103 | let expected: [UInt8] = [0xc8, 0xff, 0xff, 0x01] + raw 104 | let encoded = try await MessagePack.encode(.extended( 105 | MessagePack.Extended(type: 1, data: raw))) 106 | expect(encoded == expected) 107 | } 108 | 109 | test("DecodeExt16") { 110 | let raw = [UInt8](repeating: 0x45, count: Int(UInt16.max)) 111 | let expected = MessagePack.extended( 112 | MessagePack.Extended(type: 1, data: raw)) 113 | let decoded = try await MessagePack.decode( 114 | bytes: [0xc8, 0xff, 0xff, 0x01] + raw) 115 | expect(decoded == expected) 116 | } 117 | 118 | test("EncodeExt32") { 119 | let raw = [UInt8](repeating: 0x45, count: Int(UInt16.max)+1) 120 | let expected: [UInt8] = [0xc9, 0x00, 0x01, 0x00, 0x00, 0x01] + raw 121 | let encoded = try await MessagePack.encode(.extended( 122 | MessagePack.Extended(type: 1, data: raw))) 123 | expect(encoded == expected) 124 | } 125 | 126 | test("DecodeExt32") { 127 | let raw = [UInt8](repeating: 0x45, count: Int(UInt16.max)+1) 128 | let expected = MessagePack.extended( 129 | MessagePack.Extended(type: 1, data: raw)) 130 | let decoded = try await MessagePack.decode( 131 | bytes: [0xc9, 0x00, 0x01, 0x00, 0x00, 0x01] + raw) 132 | expect(decoded == expected) 133 | } 134 | 135 | await run() 136 | -------------------------------------------------------------------------------- /Tests/Coding/Float/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | import MessagePack 3 | 4 | test("EncodeFloat") { 5 | let expected: [UInt8] = [0xca, 0x3f, 0xcf, 0x1a, 0xa0] 6 | let encoded = try await MessagePack.encode(.float(1.618)) 7 | expect(encoded == expected) 8 | } 9 | 10 | test("DecodeFloat") { 11 | let expected = MessagePack.float(1.618) 12 | let encoded: [UInt8] = [0xca, 0x3f, 0xcf, 0x1a, 0xa0] 13 | let decoded = try await MessagePack.decode(bytes: encoded) 14 | expect(decoded == expected) 15 | } 16 | 17 | test("EncodeDouble") { 18 | let expected: [UInt8] = [ 19 | 0xcb, 0x3f, 0xf9, 0xe3, 0x53, 0xf7, 0xce, 0xd9, 0x17 20 | ] 21 | let encoded = try await MessagePack.encode(.double(1.618)) 22 | expect(encoded == expected) 23 | } 24 | 25 | test("DecodeDouble") { 26 | let expected = MessagePack.double(1.618) 27 | let encoded: [UInt8] = [ 28 | 0xcb, 0x3f, 0xf9, 0xe3, 0x53, 0xf7, 0xce, 0xd9, 0x17 29 | ] 30 | let decoded = try await MessagePack.decode(bytes: encoded) 31 | expect(decoded == expected) 32 | } 33 | 34 | await run() 35 | -------------------------------------------------------------------------------- /Tests/Coding/Init/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | import Stream 3 | import MessagePack 4 | 5 | test("ByteStream") { 6 | let expected: MessagePack = [1, 2, 3] 7 | let bytes: [UInt8] = [0x93, 0x01, 0x02, 0x03] 8 | var reader = MessagePackReader(InputByteStream(bytes)) 9 | let decoded = try await reader.decode() as MessagePack 10 | expect(decoded == expected) 11 | } 12 | 13 | await run() 14 | -------------------------------------------------------------------------------- /Tests/Coding/InsufficientData/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | import Stream 3 | import MessagePack 4 | 5 | test("InvalidData") { 6 | let bytes: [UInt8] = [0xc1] 7 | await expect(throws: MessagePack.Error.invalidData) { 8 | try await MessagePack.decode(bytes: bytes) 9 | } 10 | } 11 | 12 | test("IntegerInsufficientData") { 13 | let testCollection: [[UInt8]] = [ 14 | [0xd0], [0xd1], [0xd2], [0xd3], 15 | [0xcc], [0xcd], [0xde], [0xdf] 16 | ] 17 | for bytes in testCollection { 18 | await expect(throws: StreamError.insufficientData) { 19 | try await MessagePack.decode(bytes: bytes) 20 | } 21 | } 22 | } 23 | 24 | test("FloatInsufficientData") { 25 | let testCollection: [[UInt8]] = [ 26 | [0xca], [0xcb] 27 | ] 28 | for bytes in testCollection { 29 | await expect(throws: StreamError.insufficientData) { 30 | try await MessagePack.decode(bytes: bytes) 31 | } 32 | } 33 | } 34 | 35 | test("StringInsufficientData") { 36 | let testCollection: [[UInt8]] = [ 37 | // fixstr 38 | [0xa1], [0xa2], [0xa3], [0xa4], [0xa5], [0xa6], [0xa7], 39 | [0xa8], [0xa9], [0xaa], [0xab], [0xac], [0xad], [0xae], [0xaf], 40 | [0xb0], [0xb1], [0xb2], [0xb3], [0xb4], [0xb5], [0xb6], [0xb7], 41 | [0xb8], [0xb9], [0xba], [0xbb], [0xbc], [0xbd], [0xbe], [0xbf], 42 | // str 8,16,32 43 | [0xd9, 0x01], 44 | [0xda, 0x00, 0x01], 45 | [0xdb, 0x00, 0x00, 0x00, 0x01] 46 | ] 47 | for bytes in testCollection { 48 | await expect(throws: StreamError.insufficientData) { 49 | try await MessagePack.decode(bytes: bytes) 50 | } 51 | } 52 | } 53 | 54 | test("ArrayInsufficientData") { 55 | let testCollection: [[UInt8]] = [ 56 | // fixarr 57 | [0x91], [0x92], [0x93], [0x94], [0x95], [0x96], [0x97], 58 | [0x98], [0x99], [0x9a], [0x9b], [0x9c], [0x9d], [0x9e], [0x9f], 59 | // arr 16,32 60 | [0xdc, 0x00, 0x01], 61 | [0xdd, 0x00, 0x00, 0x00, 0x01] 62 | ] 63 | for bytes in testCollection { 64 | await expect(throws: StreamError.insufficientData) { 65 | try await MessagePack.decode(bytes: bytes) 66 | } 67 | } 68 | } 69 | 70 | test("MapInsufficientData") { 71 | let testCollection: [[UInt8]] = [ 72 | // no data 73 | [0x81], [0x82], [0x83], [0x84], [0x85], [0x86], [0x87], 74 | [0x88], [0x89], [0x8a], [0x8b], [0x8c], [0x8d], [0x8e], [0x8f], 75 | // no size, no data 76 | [0xde, 0x00, 0x01], 77 | [0xdf, 0x00, 0x00, 0x00, 0x01] 78 | ] 79 | for bytes in testCollection { 80 | await expect(throws: StreamError.insufficientData) { 81 | try await MessagePack.decode(bytes: bytes) 82 | } 83 | } 84 | } 85 | 86 | test("BinaryInsufficientData") { 87 | let testCollection: [[UInt8]] = [ 88 | // no size, no data 89 | [0xc4], [0xc5], [0xc6], 90 | // no data 91 | [0xc4, 0x01], 92 | [0xc5, 0x00, 0x01], 93 | [0xc6, 0x00, 0x00, 0x00, 0x01] 94 | ] 95 | for bytes in testCollection { 96 | await expect(throws: StreamError.insufficientData) { 97 | try await MessagePack.decode(bytes: bytes) 98 | } 99 | } 100 | } 101 | 102 | test("ExtendedInsufficientData") { 103 | let testCollection: [[UInt8]] = [ 104 | // no ext type, no data 105 | [0xd4], [0xd5], [0xd6], [0xd7], [0xd8], 106 | // no ext type, no size, no data 107 | [0xc7], [0xc8], [0xc9], 108 | // no data 109 | [0xc7, 0x01], 110 | [0xc8, 0x00, 0x01], 111 | [0xc9, 0x00, 0x00, 0x00, 0x01] 112 | ] 113 | for bytes in testCollection { 114 | await expect(throws: StreamError.insufficientData) { 115 | try await MessagePack.decode(bytes: bytes) 116 | } 117 | } 118 | } 119 | 120 | await run() 121 | -------------------------------------------------------------------------------- /Tests/Coding/Integer/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | import MessagePack 3 | 4 | test("EncodeNegativeIntToFixInt") { 5 | let expected: [UInt8] = [0xff] 6 | let encoded = try await MessagePack.encode(.int(-1)) 7 | expect(encoded == expected) 8 | } 9 | 10 | test("EncodePositiveIntToFixInt") { 11 | let expected: [UInt8] = [0x01] 12 | let encoded = try await MessagePack.encode(.uint(1)) 13 | expect(encoded == expected) 14 | } 15 | 16 | test("EncodeInt") { 17 | let expected: [UInt8] = MemoryLayout.size == MemoryLayout.size ? 18 | [0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]: 19 | [0xd2, 0x80, 0x00, 0x00, 0x00] 20 | 21 | let encoded = try await MessagePack.encode(.int(Int.min)) 22 | expect(encoded == expected) 23 | } 24 | 25 | test("EncodeUInt") { 26 | let expected: [UInt8] = MemoryLayout.size == MemoryLayout.size ? 27 | [0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]: 28 | [0xce, 0xff, 0xff, 0xff, 0xff] 29 | 30 | let encoded = try await MessagePack.encode(.uint(UInt.max)) 31 | expect(encoded == expected) 32 | } 33 | 34 | test("DecodeNegativeFixInt") { 35 | let expected = MessagePack.int(-1) 36 | let decoded = try await MessagePack.decode(bytes: [0xff]) 37 | expect(decoded == expected) 38 | guard case .int = decoded else { 39 | fail("decoded value is not type of .int") 40 | return 41 | } 42 | } 43 | 44 | test("DecodePositiveFixInt") { 45 | let expected = MessagePack.uint(1) 46 | let decoded = try await MessagePack.decode(bytes: [0x01]) 47 | expect(decoded == expected) 48 | guard case .uint = decoded else { 49 | fail("decoded value is not type of .uint") 50 | return 51 | } 52 | } 53 | 54 | test("DecodeNegativeInt8") { 55 | let expected = MessagePack(Int8.min) 56 | let decoded = try await MessagePack.decode(bytes: [0xd0, 0x80]) 57 | expect(decoded == expected) 58 | guard case .int = decoded else { 59 | fail("decoded value is not type of .int") 60 | return 61 | } 62 | } 63 | 64 | test("DecodeNegativeInt16") { 65 | let expected = MessagePack(Int16.min) 66 | let decoded = try await MessagePack.decode(bytes: [0xd1, 0x80, 0x00]) 67 | expect(decoded == expected) 68 | guard case .int = decoded else { 69 | fail("decoded value is not type of .int") 70 | return 71 | } 72 | } 73 | 74 | test("DecodeNegativeInt32") { 75 | let expected = MessagePack(Int32.min) 76 | let decoded = try await MessagePack.decode( 77 | bytes: [0xd2, 0x80, 0x00, 0x00, 0x00]) 78 | expect(decoded == expected) 79 | guard case .int = decoded else { 80 | fail("decoded value is not type of .int") 81 | return 82 | } 83 | } 84 | 85 | test("DecodeNegativeInt64") { 86 | let expected = MessagePack(Int64.min) 87 | let decoded = try await MessagePack.decode( 88 | bytes: [0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) 89 | expect(decoded == expected) 90 | guard case .int = decoded else { 91 | fail("decoded value is not type of .int") 92 | return 93 | } 94 | } 95 | 96 | test("DecodeUInt8") { 97 | let expected = MessagePack(UInt8.max) 98 | let decoded = try await MessagePack.decode(bytes: [0xcc, 0xff]) 99 | expect(decoded == expected) 100 | guard case .uint = decoded else { 101 | fail("decoded value is not type of .uint") 102 | return 103 | } 104 | } 105 | 106 | test("DecodeUInt16") { 107 | let expected = MessagePack(UInt16.max) 108 | let decoded = try await MessagePack.decode(bytes: [0xcd, 0xff, 0xff]) 109 | expect(decoded == expected) 110 | guard case .uint = decoded else { 111 | fail("decoded value is not type of .uint") 112 | return 113 | } 114 | } 115 | 116 | test("DecodeUInt32") { 117 | let expected = MessagePack(UInt32.max) 118 | let decoded = try await MessagePack.decode( 119 | bytes: [0xce, 0xff, 0xff, 0xff, 0xff]) 120 | expect(decoded == expected) 121 | guard case .uint = decoded else { 122 | fail("decoded value is not type of .uint") 123 | return 124 | } 125 | } 126 | 127 | test("DecodeUInt64") { 128 | let expected = MessagePack(UInt64.max) 129 | let decoded = try await MessagePack.decode( 130 | bytes: [0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]) 131 | expect(decoded == expected) 132 | guard case .uint = decoded else { 133 | fail("decoded value is not type of .uint") 134 | return 135 | } 136 | } 137 | 138 | await run() 139 | -------------------------------------------------------------------------------- /Tests/Coding/InvalidHeader/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | import Stream 3 | @testable import MessagePack 4 | 5 | test("StringHeader") { 6 | let header: [UInt8] = [0xff] 7 | var reader = MessagePackReader(InputByteStream(header)) 8 | await expect(throws: MessagePack.Error.invalidData) { 9 | try await reader.readStringHeader(code: reader.readCode()) 10 | } 11 | } 12 | 13 | test("ArrayHeader") { 14 | let header: [UInt8] = [0xff] 15 | var reader = MessagePackReader(InputByteStream(header)) 16 | await expect(throws: MessagePack.Error.invalidData) { 17 | try await reader.readArrayHeader(code: reader.readCode()) 18 | } 19 | } 20 | 21 | test("MapHeader") { 22 | let header: [UInt8] = [0xff] 23 | var reader = MessagePackReader(InputByteStream(header)) 24 | await expect(throws: MessagePack.Error.invalidData) { 25 | try await reader.readMapHeader(code: reader.readCode()) 26 | } 27 | } 28 | 29 | test("BinaryHeader") { 30 | let header: [UInt8] = [0xff] 31 | var reader = MessagePackReader(InputByteStream(header)) 32 | await expect(throws: MessagePack.Error.invalidData) { 33 | try await reader.readBinaryHeader(code: reader.readCode()) 34 | } 35 | } 36 | 37 | test("ExtendedHeader") { 38 | let header: [UInt8] = [0xff] 39 | var reader = MessagePackReader(InputByteStream(header)) 40 | await expect(throws: MessagePack.Error.invalidData) { 41 | try await reader.readExtendedHeader(code: reader.readCode()) 42 | } 43 | } 44 | 45 | await run() 46 | -------------------------------------------------------------------------------- /Tests/Coding/ManualHeaders/main.swift: -------------------------------------------------------------------------------- 1 | import Test 2 | import Stream 3 | import MessagePack 4 | 5 | test("EncodeArray") { 6 | let expected = try await MessagePack.encode( 7 | .array(["one", "two", "three"])) 8 | let stream = OutputByteStream() 9 | var writer = MessagePackWriter(stream) 10 | let items = ["one", "two", "three"] 11 | try await writer.encodeArrayItemsCount(items.count) 12 | for item in items { 13 | try await writer.encode(item) 14 | } 15 | expect(stream.bytes == expected) 16 | } 17 | 18 | test("DecodeArray") { 19 | let expected = ["one", "two", "three"] 20 | let encoded = try await MessagePack.encode( 21 | .array(["one", "two", "three"])) 22 | var reader = MessagePackReader(InputByteStream(encoded)) 23 | var result = [String]() 24 | let itemsCount = try await reader.decodeArrayItemsCount() 25 | for _ in 0.. [MessagePack: MessagePack] { 5 | var map: [MessagePack: MessagePack] = [:] 6 | for i in 0.. [UInt8] { 16 | var bytes: [UInt8] = [] 17 | for i in 0..