From 6701106072b968242b54f75f6dbe54bad5263c8b Mon Sep 17 00:00:00 2001 From: Ali <> Date: Fri, 30 Jul 2021 00:04:10 +0200 Subject: [PATCH] Temp --- .../Sources/ChatController.swift | 10 +- submodules/Postbox/Sources/Coding.swift | 460 ++++++++---------- .../Utils/Decoder/AdaptedPostboxDecoder.swift | 86 +++- ...AdaptedPostboxKeyedDecodingContainer.swift | 16 +- ...aptedPostboxUnkeyedDecodingContainer.swift | 120 ++++- 5 files changed, 421 insertions(+), 271 deletions(-) diff --git a/submodules/AccountContext/Sources/ChatController.swift b/submodules/AccountContext/Sources/ChatController.swift index 2fb7014a77..393a656d7c 100644 --- a/submodules/AccountContext/Sources/ChatController.swift +++ b/submodules/AccountContext/Sources/ChatController.swift @@ -156,9 +156,9 @@ public struct ChatTextInputState: Codable, Equatable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: StringCodingKey.self) - self.inputText = ((try? container.decodeIfPresent(ChatTextInputStateText.self, forKey: "at")) ?? ChatTextInputStateText()).attributedText() - let rangeFrom = (try? container.decodeIfPresent(Int32.self, forKey: "as0")) ?? 0 - let rangeTo = (try? container.decodeIfPresent(Int32.self, forKey: "as1")) ?? 0 + self.inputText = ((try? container.decode(ChatTextInputStateText.self, forKey: "at")) ?? ChatTextInputStateText()).attributedText() + let rangeFrom = (try? container.decode(Int32.self, forKey: "as0")) ?? 0 + let rangeTo = (try? container.decode(Int32.self, forKey: "as1")) ?? 0 if rangeFrom <= rangeTo { self.selectionRange = Int(rangeFrom) ..< Int(rangeTo) } else { @@ -351,8 +351,8 @@ public struct ChatTextInputStateText: Codable, Equatable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: StringCodingKey.self) - self.text = (try? container.decodeIfPresent(String.self, forKey: "text")) ?? "" - self.attributes = (try? container.decodeIfPresent([ChatTextInputStateTextAttribute].self, forKey: "attributes")) ?? [] + self.text = (try? container.decode(String.self, forKey: "text")) ?? "" + self.attributes = (try? container.decode([ChatTextInputStateTextAttribute].self, forKey: "attributes")) ?? [] } public func encode(to encoder: Encoder) throws { diff --git a/submodules/Postbox/Sources/Coding.swift b/submodules/Postbox/Sources/Coding.swift index 565e97f6a0..cb29125b22 100644 --- a/submodules/Postbox/Sources/Coding.swift +++ b/submodules/Postbox/Sources/Coding.swift @@ -215,7 +215,7 @@ public final class ReadBuffer: MemoryBuffer { } } -private enum ValueType: Int8 { +enum ValueType: Int8 { case Int32 = 0 case Int64 = 1 case Bool = 2 @@ -258,41 +258,21 @@ public final class PostboxEncoder { self.buffer.reset() } - public func encodeKey(_ key: StaticString) { - var length: Int8 = Int8(key.utf8CodeUnitCount) - self.buffer.write(&length, offset: 0, length: 1) - self.buffer.write(key.utf8Start, offset: 0, length: Int(length)) - } - public func encodeKey(_ key: String) { let data = key.data(using: .utf8)! - data.withUnsafeBytes { (keyBytes: UnsafePointer) -> Void in - var length: Int8 = Int8(data.count) - self.buffer.write(&length, offset: 0, length: 1) - self.buffer.write(keyBytes, offset: 0, length: Int(length)) + var length: Int8 = Int8(data.count) + self.buffer.write(&length, offset: 0, length: 1) + data.withUnsafeBytes { bytes in + self.buffer.write(bytes.baseAddress!, offset: 0, length: Int(length)) } } - public func encodeNil(forKey key: StaticString) { - self.encodeKey(key) - var type: Int8 = ValueType.Nil.rawValue - self.buffer.write(&type, offset: 0, length: 1) - } - public func encodeNil(forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.Nil.rawValue self.buffer.write(&type, offset: 0, length: 1) } - public func encodeInt32(_ value: Int32, forKey key: StaticString) { - self.encodeKey(key) - var type: Int8 = ValueType.Int32.rawValue - self.buffer.write(&type, offset: 0, length: 1) - var v = value - self.buffer.write(&v, offset: 0, length: 4) - } - public func encodeInt32(_ value: Int32, forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.Int32.rawValue @@ -301,14 +281,6 @@ public final class PostboxEncoder { self.buffer.write(&v, offset: 0, length: 4) } - public func encodeInt64(_ value: Int64, forKey key: StaticString) { - self.encodeKey(key) - var type: Int8 = ValueType.Int64.rawValue - self.buffer.write(&type, offset: 0, length: 1) - var v = value - self.buffer.write(&v, offset: 0, length: 8) - } - public func encodeInt64(_ value: Int64, forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.Int64.rawValue @@ -317,14 +289,6 @@ public final class PostboxEncoder { self.buffer.write(&v, offset: 0, length: 8) } - public func encodeBool(_ value: Bool, forKey key: StaticString) { - self.encodeKey(key) - var type: Int8 = ValueType.Bool.rawValue - self.buffer.write(&type, offset: 0, length: 1) - var v: Int8 = value ? 1 : 0 - self.buffer.write(&v, offset: 0, length: 1) - } - public func encodeBool(_ value: Bool, forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.Bool.rawValue @@ -333,14 +297,6 @@ public final class PostboxEncoder { self.buffer.write(&v, offset: 0, length: 1) } - public func encodeDouble(_ value: Double, forKey key: StaticString) { - self.encodeKey(key) - var type: Int8 = ValueType.Double.rawValue - self.buffer.write(&type, offset: 0, length: 1) - var v = value - self.buffer.write(&v, offset: 0, length: 8) - } - public func encodeDouble(_ value: Double, forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.Double.rawValue @@ -349,20 +305,6 @@ public final class PostboxEncoder { self.buffer.write(&v, offset: 0, length: 8) } - public func encodeString(_ value: String, forKey key: StaticString) { - self.encodeKey(key) - var type: Int8 = ValueType.String.rawValue - self.buffer.write(&type, offset: 0, length: 1) - if let data = value.data(using: .utf8, allowLossyConversion: true) { - var length: Int32 = Int32(data.count) - self.buffer.write(&length, offset: 0, length: 4) - self.buffer.write(data) - } else { - var length: Int32 = 0 - self.buffer.write(&length, offset: 0, length: 4) - } - } - public func encodeString(_ value: String, forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.String.rawValue @@ -381,13 +323,13 @@ public final class PostboxEncoder { self.encodeObject(value, forKey: "_") } - public func encodeCodable(_ value: T, forKey key: StaticString) { + public func encodeCodable(_ value: T, forKey key: String) { if let data = try? JSONEncoder().encode(value) { self.encodeData(data, forKey: key) } } - public func encodeObject(_ value: PostboxCoding, forKey key: StaticString) { + public func encodeObject(_ value: PostboxCoding, forKey key: String) { self.encodeKey(key) var t: Int8 = ValueType.Object.rawValue self.buffer.write(&t, offset: 0, length: 1) @@ -421,7 +363,7 @@ public final class PostboxEncoder { self.buffer.write(innerEncoder.buffer.memory, offset: 0, length: Int(length)) } - public func encodeInt32Array(_ value: [Int32], forKey key: StaticString) { + public func encodeInt32Array(_ value: [Int32], forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.Int32Array.rawValue self.buffer.write(&type, offset: 0, length: 1) @@ -433,7 +375,7 @@ public final class PostboxEncoder { } } - public func encodeInt64Array(_ value: [Int64], forKey key: StaticString) { + public func encodeInt64Array(_ value: [Int64], forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.Int64Array.rawValue self.buffer.write(&type, offset: 0, length: 1) @@ -445,7 +387,7 @@ public final class PostboxEncoder { } } - public func encodeObjectArray(_ value: [T], forKey key: StaticString) { + public func encodeObjectArray(_ value: [T], forKey key: String) { self.encodeKey(key) var t: Int8 = ValueType.ObjectArray.rawValue self.buffer.write(&t, offset: 0, length: 1) @@ -465,7 +407,7 @@ public final class PostboxEncoder { } } - public func encodeObjectArrayWithEncoder(_ value: [T], forKey key: StaticString, encoder: (T, PostboxEncoder) -> Void) { + public func encodeObjectArrayWithEncoder(_ value: [T], forKey key: String, encoder: (T, PostboxEncoder) -> Void) { self.encodeKey(key) var t: Int8 = ValueType.ObjectArray.rawValue self.buffer.write(&t, offset: 0, length: 1) @@ -485,7 +427,7 @@ public final class PostboxEncoder { } } - public func encodeGenericObjectArray(_ value: [PostboxCoding], forKey key: StaticString) { + public func encodeGenericObjectArray(_ value: [PostboxCoding], forKey key: String) { self.encodeKey(key) var t: Int8 = ValueType.ObjectArray.rawValue self.buffer.write(&t, offset: 0, length: 1) @@ -505,7 +447,7 @@ public final class PostboxEncoder { } } - public func encodeStringArray(_ value: [String], forKey key: StaticString) { + public func encodeStringArray(_ value: [String], forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.StringArray.rawValue self.buffer.write(&type, offset: 0, length: 1) @@ -520,7 +462,7 @@ public final class PostboxEncoder { } } - public func encodeBytesArray(_ value: [MemoryBuffer], forKey key: StaticString) { + public func encodeBytesArray(_ value: [MemoryBuffer], forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.BytesArray.rawValue self.buffer.write(&type, offset: 0, length: 1) @@ -534,7 +476,7 @@ public final class PostboxEncoder { } } - public func encodeDataArray(_ value: [Data], forKey key: StaticString) { + public func encodeDataArray(_ value: [Data], forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.BytesArray.rawValue self.buffer.write(&type, offset: 0, length: 1) @@ -550,7 +492,7 @@ public final class PostboxEncoder { } } - public func encodeObjectDictionary(_ value: [K : V], forKey key: StaticString) where K: PostboxCoding { + public func encodeObjectDictionary(_ value: [K : V], forKey key: String) where K: PostboxCoding { self.encodeKey(key) var t: Int8 = ValueType.ObjectDictionary.rawValue self.buffer.write(&t, offset: 0, length: 1) @@ -577,7 +519,7 @@ public final class PostboxEncoder { } } - public func encodeObjectDictionary(_ value: [K : V], forKey key: StaticString, keyEncoder: (K, PostboxEncoder) -> Void) { + public func encodeObjectDictionary(_ value: [K : V], forKey key: String, keyEncoder: (K, PostboxEncoder) -> Void) { self.encodeKey(key) var t: Int8 = ValueType.ObjectDictionary.rawValue self.buffer.write(&t, offset: 0, length: 1) @@ -604,7 +546,7 @@ public final class PostboxEncoder { } } - public func encodeBytes(_ bytes: WriteBuffer, forKey key: StaticString) { + public func encodeBytes(_ bytes: WriteBuffer, forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.Bytes.rawValue self.buffer.write(&type, offset: 0, length: 1) @@ -613,7 +555,7 @@ public final class PostboxEncoder { self.buffer.write(bytes.memory, offset: 0, length: bytes.offset) } - public func encodeBytes(_ bytes: ReadBuffer, forKey key: StaticString) { + public func encodeBytes(_ bytes: ReadBuffer, forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.Bytes.rawValue self.buffer.write(&type, offset: 0, length: 1) @@ -622,7 +564,7 @@ public final class PostboxEncoder { self.buffer.write(bytes.memory, offset: 0, length: bytes.offset) } - public func encodeBytes(_ bytes: MemoryBuffer, forKey key: StaticString) { + public func encodeBytes(_ bytes: MemoryBuffer, forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.Bytes.rawValue self.buffer.write(&type, offset: 0, length: 1) @@ -631,7 +573,7 @@ public final class PostboxEncoder { self.buffer.write(bytes.memory, offset: 0, length: bytes.length) } - public func encodeData(_ data: Data, forKey key: StaticString) { + public func encodeData(_ data: Data, forKey key: String) { self.encodeKey(key) var type: Int8 = ValueType.Bytes.rawValue self.buffer.write(&type, offset: 0, length: 1) @@ -756,45 +698,13 @@ public final class PostboxDecoder { } } } - - private class func positionOnKey(_ rawBytes: UnsafeRawPointer, offset: inout Int, maxOffset: Int, length: Int, key: StaticString, valueType: ValueType) -> Bool - { - let bytes = rawBytes.assumingMemoryBound(to: Int8.self) - - let startOffset = offset - - let keyLength: Int = key.utf8CodeUnitCount - while (offset < maxOffset) { - let readKeyLength = bytes[offset] - assert(readKeyLength >= 0) - offset += 1 - offset += Int(readKeyLength) - - let readValueType = bytes[offset] - offset += 1 - - if keyLength == Int(readKeyLength) && memcmp(bytes + (offset - Int(readKeyLength) - 1), key.utf8Start, keyLength) == 0 { - if readValueType == valueType.rawValue { - return true - } else if readValueType == ValueType.Nil.rawValue { - return false - } else { - skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!) - } - } else { - skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!) - } - } - - if (startOffset != 0) { - offset = 0 - return positionOnKey(bytes, offset: &offset, maxOffset: startOffset, length: length, key: key, valueType: valueType) - } - - return false + + private class func positionOnKey(_ rawBytes: UnsafeRawPointer, offset: inout Int, maxOffset: Int, length: Int, key: String, valueType: ValueType) -> Bool { + var actualValueType: ValueType = .Nil + return positionOnKey(rawBytes, offset: &offset, maxOffset: maxOffset, length: length, key: key, valueType: valueType, actualValueType: &actualValueType, consumeKey: true) } - private class func positionOnKey(_ rawBytes: UnsafeRawPointer, offset: inout Int, maxOffset: Int, length: Int, key: String, valueType: ValueType?, consumeKey: Bool = true) -> Bool + private class func positionOnKey(_ rawBytes: UnsafeRawPointer, offset: inout Int, maxOffset: Int, length: Int, key: String, valueType: ValueType?, actualValueType: inout ValueType, consumeKey: Bool) -> Bool { let bytes = rawBytes.assumingMemoryBound(to: Int8.self) @@ -823,6 +733,7 @@ public final class PostboxDecoder { }) { if let valueType = valueType { if readValueType == valueType.rawValue { + actualValueType = valueType return true } else if readValueType == ValueType.Nil.rawValue { return false @@ -833,6 +744,7 @@ public final class PostboxDecoder { if !consumeKey { offset = keyOffset } + actualValueType = ValueType(rawValue: readValueType)! return true } } else { @@ -842,7 +754,7 @@ public final class PostboxDecoder { if (startOffset != 0) { offset = 0 - return positionOnKey(bytes, offset: &offset, maxOffset: startOffset, length: length, key: key, valueType: valueType) + return positionOnKey(bytes, offset: &offset, maxOffset: startOffset, length: length, key: key, valueType: valueType, actualValueType: &actualValueType, consumeKey: consumeKey) } return false @@ -921,7 +833,8 @@ public final class PostboxDecoder { } public func containsKey(_ key: String) -> Bool { - if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: nil, consumeKey: false) { + var actualValueType: ValueType = .Nil + if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: nil, actualValueType: &actualValueType, consumeKey: false) { return true } else { return false @@ -936,41 +849,19 @@ public final class PostboxDecoder { } } - public func decodeInt32ForKey(_ key: StaticString, orElse: Int32) -> Int32 { - if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32) { - var value: Int32 = 0 - memcpy(&value, self.buffer.memory + self.offset, 4) - self.offset += 4 - return value - } else { - return orElse - } - } - public func decodeInt32ForKey(_ key: String, orElse: Int32) -> Int32 { - if PostboxDecoder.positionOnStringKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32) { - var value: Int32 = 0 - memcpy(&value, self.buffer.memory + self.offset, 4) - self.offset += 4 - return value - } else { - return orElse - } - } - - public func decodeOptionalInt32ForKey(_ key: StaticString) -> Int32? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32) { var value: Int32 = 0 memcpy(&value, self.buffer.memory + self.offset, 4) self.offset += 4 return value } else { - return nil + return orElse } } public func decodeOptionalInt32ForKey(_ key: String) -> Int32? { - if PostboxDecoder.positionOnStringKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32) { + if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32) { var value: Int32 = 0 memcpy(&value, self.buffer.memory + self.offset, 4) self.offset += 4 @@ -980,7 +871,7 @@ public final class PostboxDecoder { } } - public func decodeInt64ForKey(_ key: StaticString, orElse: Int64) -> Int64 { + public func decodeInt64ForKey(_ key: String, orElse: Int64) -> Int64 { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int64) { var value: Int64 = 0 memcpy(&value, self.buffer.memory + self.offset, 8) @@ -991,7 +882,7 @@ public final class PostboxDecoder { } } - public func decodeOptionalInt64ForKey(_ key: StaticString) -> Int64? { + public func decodeOptionalInt64ForKey(_ key: String) -> Int64? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int64) { var value: Int64 = 0 memcpy(&value, self.buffer.memory + self.offset, 8) @@ -1002,7 +893,7 @@ public final class PostboxDecoder { } } - public func decodeBoolForKey(_ key: StaticString, orElse: Bool) -> Bool { + public func decodeBoolForKey(_ key: String, orElse: Bool) -> Bool { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Bool) { var value: Int8 = 0 memcpy(&value, self.buffer.memory + self.offset, 1) @@ -1013,7 +904,7 @@ public final class PostboxDecoder { } } - public func decodeOptionalBoolForKey(_ key: StaticString) -> Bool? { + public func decodeOptionalBoolForKey(_ key: String) -> Bool? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Bool) { var value: Int8 = 0 memcpy(&value, self.buffer.memory + self.offset, 1) @@ -1024,7 +915,7 @@ public final class PostboxDecoder { } } - public func decodeDoubleForKey(_ key: StaticString, orElse: Double) -> Double { + public func decodeDoubleForKey(_ key: String, orElse: Double) -> Double { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Double) { var value: Double = 0 memcpy(&value, self.buffer.memory + self.offset, 8) @@ -1035,7 +926,7 @@ public final class PostboxDecoder { } } - public func decodeOptionalDoubleForKey(_ key: StaticString) -> Double? { + public func decodeOptionalDoubleForKey(_ key: String) -> Double? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Double) { var value: Double = 0 memcpy(&value, self.buffer.memory + self.offset, 8) @@ -1046,7 +937,7 @@ public final class PostboxDecoder { } } - public func decodeStringForKey(_ key: StaticString, orElse: String) -> String { + public func decodeStringForKey(_ key: String, orElse: String) -> String { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .String) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1058,7 +949,7 @@ public final class PostboxDecoder { } } - public func decodeOptionalStringForKey(_ key: StaticString) -> String? { + public func decodeOptionalStringForKey(_ key: String) -> String? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .String) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1074,7 +965,7 @@ public final class PostboxDecoder { return self.decodeObjectForKey("_") } - public func decodeCodable(_ type: T.Type, forKey key: StaticString) -> T? { + public func decodeCodable(_ type: T.Type, forKey key: String) -> T? { if let data = self.decodeDataForKey(key) { return try? JSONDecoder().decode(T.self, from: data) } else { @@ -1082,7 +973,7 @@ public final class PostboxDecoder { } } - public func decodeObjectForKey(_ key: StaticString) -> PostboxCoding? { + public func decodeObjectForKey(_ key: String) -> PostboxCoding? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Object) { var typeHash: Int32 = 0 memcpy(&typeHash, self.buffer.memory + self.offset, 4) @@ -1099,8 +990,34 @@ public final class PostboxDecoder { return nil } } + + func decodeObjectDataForKey(_ key: String) -> (Data, ValueType)? { + var actualValueType: ValueType = .Nil + if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: nil, actualValueType: &actualValueType, consumeKey: true) { + if case .Object = actualValueType { + self.offset += 4 + + var length: Int32 = 0 + memcpy(&length, self.buffer.memory + self.offset, 4) + + let innerData = ReadBuffer(memory: self.buffer.memory + (self.offset + 4), length: Int(length), freeWhenDone: false).makeData() + self.offset += 4 + Int(length) + + return (innerData, actualValueType) + } else { + let initialOffset = self.offset + PostboxDecoder.skipValue(self.buffer.memory.assumingMemoryBound(to: Int8.self), offset: &self.offset, length: self.buffer.length, valueType: actualValueType) + + let data = ReadBuffer(memory: UnsafeMutableRawPointer(mutating: self.buffer.memory.advanced(by: self.offset)), length: self.offset - initialOffset, freeWhenDone: false).makeData() + + return (data, actualValueType) + } + } else { + return nil + } + } - public func decodeObjectForKey(_ key: StaticString, decoder: (PostboxDecoder) -> PostboxCoding) -> PostboxCoding? { + public func decodeObjectForKey(_ key: String, decoder: (PostboxDecoder) -> PostboxCoding) -> PostboxCoding? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Object) { var typeHash: Int32 = 0 memcpy(&typeHash, self.buffer.memory + self.offset, 4) @@ -1118,7 +1035,7 @@ public final class PostboxDecoder { } } - public func decodeAnyObjectForKey(_ key: StaticString, decoder: (PostboxDecoder) -> Any?) -> Any? { + public func decodeAnyObjectForKey(_ key: String, decoder: (PostboxDecoder) -> Any?) -> Any? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Object) { var typeHash: Int32 = 0 memcpy(&typeHash, self.buffer.memory + self.offset, 4) @@ -1136,7 +1053,7 @@ public final class PostboxDecoder { } } - public func decodeObjectForKeyThrowing(_ key: StaticString, decoder: (PostboxDecoder) throws -> Any) throws -> Any? { + public func decodeObjectForKeyThrowing(_ key: String, decoder: (PostboxDecoder) throws -> Any) throws -> Any? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Object) { var typeHash: Int32 = 0 memcpy(&typeHash, self.buffer.memory + self.offset, 4) @@ -1154,47 +1071,55 @@ public final class PostboxDecoder { } } - public func decodeInt32ArrayForKey(_ key: StaticString) -> [Int32] { + public func decodeInt32ArrayForKey(_ key: String) -> [Int32] { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32Array) { - var length: Int32 = 0 - memcpy(&length, self.buffer.memory + self.offset, 4) - var array: [Int32] = [] - array.reserveCapacity(Int(length)) - var i: Int32 = 0 - while i < length { - var element: Int32 = 0 - memcpy(&element, self.buffer.memory + (self.offset + 4 + 4 * Int(i)), 4) - array.append(element) - i += 1 - } - self.offset += 4 + Int(length) * 4 - return array + return decodeInt32ArrayRaw() } else { return [] } } + + func decodeInt32ArrayRaw() -> [Int32] { + var length: Int32 = 0 + memcpy(&length, self.buffer.memory + self.offset, 4) + var array: [Int32] = [] + array.reserveCapacity(Int(length)) + var i: Int32 = 0 + while i < length { + var element: Int32 = 0 + memcpy(&element, self.buffer.memory + (self.offset + 4 + 4 * Int(i)), 4) + array.append(element) + i += 1 + } + self.offset += 4 + Int(length) * 4 + return array + } - public func decodeInt64ArrayForKey(_ key: StaticString) -> [Int64] { + public func decodeInt64ArrayForKey(_ key: String) -> [Int64] { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int64Array) { - var length: Int32 = 0 - memcpy(&length, self.buffer.memory + self.offset, 4) - var array: [Int64] = [] - array.reserveCapacity(Int(length)) - var i: Int32 = 0 - while i < length { - var element: Int64 = 0 - memcpy(&element, self.buffer.memory + (self.offset + 4 + 8 * Int(i)), 8) - array.append(element) - i += 1 - } - self.offset += 4 + Int(length) * 8 - return array + return decodeInt64ArrayRaw() } else { return [] } } + + func decodeInt64ArrayRaw() -> [Int64] { + var length: Int32 = 0 + memcpy(&length, self.buffer.memory + self.offset, 4) + var array: [Int64] = [] + array.reserveCapacity(Int(length)) + var i: Int32 = 0 + while i < length { + var element: Int64 = 0 + memcpy(&element, self.buffer.memory + (self.offset + 4 + 8 * Int(i)), 8) + array.append(element) + i += 1 + } + self.offset += 4 + Int(length) * 8 + return array + } - public func decodeObjectArrayWithDecoderForKey(_ key: StaticString) -> [T] where T: PostboxCoding { + public func decodeObjectArrayWithDecoderForKey(_ key: String) -> [T] where T: PostboxCoding { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectArray) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1226,7 +1151,7 @@ public final class PostboxDecoder { } } - public func decodeOptionalObjectArrayWithDecoderForKey(_ key: StaticString) -> [T]? where T: PostboxCoding { + public func decodeOptionalObjectArrayWithDecoderForKey(_ key: String) -> [T]? where T: PostboxCoding { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectArray) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1258,7 +1183,7 @@ public final class PostboxDecoder { } } - public func decodeObjectArrayWithCustomDecoderForKey(_ key: StaticString, decoder: (PostboxDecoder) throws -> T) throws -> [T] { + public func decodeObjectArrayWithCustomDecoderForKey(_ key: String, decoder: (PostboxDecoder) throws -> T) throws -> [T] { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectArray) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1291,65 +1216,105 @@ public final class PostboxDecoder { } } - public func decodeStringArrayForKey(_ key: StaticString) -> [String] { + public func decodeStringArrayForKey(_ key: String) -> [String] { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .StringArray) { - var length: Int32 = 0 - memcpy(&length, self.buffer.memory + self.offset, 4) - self.offset += 4 - - var array: [String] = [] - array.reserveCapacity(Int(length)) - - var i: Int32 = 0 - while i < length { - var length: Int32 = 0 - memcpy(&length, self.buffer.memory + self.offset, 4) - let data = Data(bytes: self.buffer.memory.assumingMemoryBound(to: UInt8.self).advanced(by: self.offset + 4), count: Int(length)) - self.offset += 4 + Int(length) - if let string = String(data: data, encoding: .utf8) { - array.append(string) - } else { - assertionFailure() - array.append("") - } - - i += 1 - } - - return array + return decodeStringArrayRaw() } else { return [] } } + + public func decodeStringArrayRaw() -> [String] { + var length: Int32 = 0 + memcpy(&length, self.buffer.memory + self.offset, 4) + self.offset += 4 + + var array: [String] = [] + array.reserveCapacity(Int(length)) + + var i: Int32 = 0 + while i < length { + var length: Int32 = 0 + memcpy(&length, self.buffer.memory + self.offset, 4) + let data = Data(bytes: self.buffer.memory.assumingMemoryBound(to: UInt8.self).advanced(by: self.offset + 4), count: Int(length)) + self.offset += 4 + Int(length) + if let string = String(data: data, encoding: .utf8) { + array.append(string) + } else { + assertionFailure() + array.append("") + } + + i += 1 + } + + return array + } - public func decodeBytesArrayForKey(_ key: StaticString) -> [MemoryBuffer] { + public func decodeBytesArrayForKey(_ key: String) -> [MemoryBuffer] { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .BytesArray) { - var length: Int32 = 0 - memcpy(&length, self.buffer.memory + self.offset, 4) - self.offset += 4 - - var array: [MemoryBuffer] = [] - array.reserveCapacity(Int(length)) - - var i: Int32 = 0 - while i < length { - var length: Int32 = 0 - memcpy(&length, self.buffer.memory + self.offset, 4) - let bytes = malloc(Int(length))! - memcpy(bytes, self.buffer.memory.advanced(by: self.offset + 4), Int(length)) - array.append(MemoryBuffer(memory: bytes, capacity: Int(length), length: Int(length), freeWhenDone: true)) - self.offset += 4 + Int(length) - - i += 1 - } - - return array + return decodeBytesArrayRaw() } else { return [] } } + + func decodeBytesArrayRaw() -> [MemoryBuffer] { + var length: Int32 = 0 + memcpy(&length, self.buffer.memory + self.offset, 4) + self.offset += 4 + + var array: [MemoryBuffer] = [] + array.reserveCapacity(Int(length)) + + var i: Int32 = 0 + while i < length { + var length: Int32 = 0 + memcpy(&length, self.buffer.memory + self.offset, 4) + let bytes = malloc(Int(length))! + memcpy(bytes, self.buffer.memory.advanced(by: self.offset + 4), Int(length)) + array.append(MemoryBuffer(memory: bytes, capacity: Int(length), length: Int(length), freeWhenDone: true)) + self.offset += 4 + Int(length) + + i += 1 + } + + return array + } + + func decodeObjectDataArrayRaw() -> [Data] { + var length: Int32 = 0 + memcpy(&length, self.buffer.memory + self.offset, 4) + self.offset += 4 + + var array: [Data] = [] + array.reserveCapacity(Int(length)) + + var i: Int32 = 0 + while i < length { + var typeHash: Int32 = 0 + memcpy(&typeHash, self.buffer.memory + self.offset, 4) + self.offset += 4 + + var objectLength: Int32 = 0 + memcpy(&objectLength, self.buffer.memory + self.offset, 4) + if objectLength < 0 || objectLength > 2 * 1024 * 1024 { + preconditionFailure() + } + + let innerBuffer = ReadBuffer(memory: self.buffer.memory + (self.offset + 4), length: Int(objectLength), freeWhenDone: false) + let innerData = innerBuffer.makeData() + self.offset += 4 + Int(objectLength) + + array.append(innerData) + + i += 1 + } + + return array + } - public func decodeOptionalDataArrayForKey(_ key: StaticString) -> [Data]? { + public func decodeOptionalDataArrayForKey(_ key: String) -> [Data]? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .BytesArray) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1374,7 +1339,7 @@ public final class PostboxDecoder { } } - public func decodeObjectArrayForKey(_ key: StaticString) -> [T] where T: PostboxCoding { + public func decodeObjectArrayForKey(_ key: String) -> [T] where T: PostboxCoding { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectArray) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1417,7 +1382,7 @@ public final class PostboxDecoder { } } - public func decodeObjectArrayForKey(_ key: StaticString) -> [PostboxCoding] { + public func decodeObjectArrayForKey(_ key: String) -> [PostboxCoding] { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectArray) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1460,7 +1425,7 @@ public final class PostboxDecoder { } } - public func decodeObjectDictionaryForKey(_ key: StaticString) -> [K : V] where K: PostboxCoding, K: Hashable { + public func decodeObjectDictionaryForKey(_ key: String) -> [K : V] where K: PostboxCoding, K: Hashable { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectDictionary) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1514,7 +1479,7 @@ public final class PostboxDecoder { } } - public func decodeObjectDictionaryForKey(_ key: StaticString, keyDecoder: (PostboxDecoder) -> K) -> [K : V] where K: Hashable { + public func decodeObjectDictionaryForKey(_ key: String, keyDecoder: (PostboxDecoder) -> K) -> [K : V] where K: Hashable { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectDictionary) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1571,7 +1536,7 @@ public final class PostboxDecoder { } } - public func decodeObjectDictionaryForKey(_ key: StaticString, keyDecoder: (PostboxDecoder) -> K, valueDecoder: (PostboxDecoder) -> V) -> [K : V] where K: Hashable { + public func decodeObjectDictionaryForKey(_ key: String, keyDecoder: (PostboxDecoder) -> K, valueDecoder: (PostboxDecoder) -> V) -> [K : V] where K: Hashable { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .ObjectDictionary) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1628,7 +1593,7 @@ public final class PostboxDecoder { } } - public func decodeBytesForKeyNoCopy(_ key: StaticString) -> ReadBuffer? { + public func decodeBytesForKeyNoCopy(_ key: String) -> ReadBuffer? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Bytes) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1639,7 +1604,7 @@ public final class PostboxDecoder { } } - public func decodeBytesForKey(_ key: StaticString) -> ReadBuffer? { + public func decodeBytesForKey(_ key: String) -> ReadBuffer? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Bytes) { var length: Int32 = 0 memcpy(&length, self.buffer.memory + self.offset, 4) @@ -1652,21 +1617,6 @@ public final class PostboxDecoder { } } - public func decodeDataForKey(_ key: StaticString) -> Data? { - if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Bytes) { - var length: Int32 = 0 - memcpy(&length, self.buffer.memory + self.offset, 4) - self.offset += 4 + Int(length) - var result = Data(count: Int(length)) - result.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer) -> Void in - memcpy(bytes, self.buffer.memory.advanced(by: self.offset - Int(length)), Int(length)) - } - return result - } else { - return nil - } - } - public func decodeDataForKey(_ key: String) -> Data? { if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Bytes) { var length: Int32 = 0 diff --git a/submodules/Postbox/Sources/Utils/Decoder/AdaptedPostboxDecoder.swift b/submodules/Postbox/Sources/Utils/Decoder/AdaptedPostboxDecoder.swift index f6e72f7e13..69d2074ced 100644 --- a/submodules/Postbox/Sources/Utils/Decoder/AdaptedPostboxDecoder.swift +++ b/submodules/Postbox/Sources/Utils/Decoder/AdaptedPostboxDecoder.swift @@ -1,22 +1,73 @@ import Foundation final public class AdaptedPostboxDecoder { + enum ContentType { + case object + case int32Array + case int64Array + case objectArray + case stringArray + case dataArray + } + func decode(_ type: T.Type, from data: Data) throws -> T where T : Decodable { - let decoder = _AdaptedPostboxDecoder(data: data) + return try self.decode(type, from: data, contentType: .object) + } + + func decode(_ type: T.Type, from data: Data, contentType: ContentType) throws -> T where T : Decodable { + let decoder = _AdaptedPostboxDecoder(data: data, contentType: contentType) return try T(from: decoder) } } +extension AdaptedPostboxDecoder.ContentType { + init?(valueType: ValueType) { + switch valueType { + case .Int32: + return nil + case .Int64: + return nil + case .Bool: + return nil + case .Double: + return nil + case .String: + return nil + case .Object: + self = .object + case .Int32Array: + self = .int32Array + case .Int64Array: + self = .int64Array + case .ObjectArray: + self = .objectArray + case .ObjectDictionary: + return nil + case .Bytes: + return nil + case .Nil: + return nil + case .StringArray: + self = .stringArray + case .BytesArray: + self = .dataArray + } + } +} + final class _AdaptedPostboxDecoder { var codingPath: [CodingKey] = [] var userInfo: [CodingUserInfoKey : Any] = [:] var container: AdaptedPostboxDecodingContainer? - fileprivate var data: Data + + fileprivate let data: Data + fileprivate let contentType: AdaptedPostboxDecoder.ContentType - init(data: Data) { + init(data: Data, contentType: AdaptedPostboxDecoder.ContentType) { self.data = data + self.contentType = contentType } } @@ -35,7 +86,34 @@ extension _AdaptedPostboxDecoder: Decoder { } func unkeyedContainer() -> UnkeyedDecodingContainer { - preconditionFailure() + assertCanCreateContainer() + + let decoder = PostboxDecoder(buffer: MemoryBuffer(data: self.data)) + + var content: UnkeyedContainer.Content? + switch self.contentType { + case .object: + preconditionFailure() + case .int32Array: + content = .int32Array(decoder.decodeInt32ArrayRaw()) + case .int64Array: + content = .int64Array(decoder.decodeInt64ArrayRaw()) + case .objectArray: + content = .objectArray(decoder.decodeObjectDataArrayRaw()) + case .stringArray: + content = .stringArray(decoder.decodeStringArrayRaw()) + case .dataArray: + content = .dataArray(decoder.decodeBytesArrayRaw().map { $0.makeData() }) + } + + if let content = content { + let container = UnkeyedContainer(data: self.data, codingPath: self.codingPath, userInfo: self.userInfo, content: content) + self.container = container + + return container + } else { + preconditionFailure() + } } func singleValueContainer() -> SingleValueDecodingContainer { diff --git a/submodules/Postbox/Sources/Utils/Decoder/AdaptedPostboxKeyedDecodingContainer.swift b/submodules/Postbox/Sources/Utils/Decoder/AdaptedPostboxKeyedDecodingContainer.swift index 49a5bf6dd0..6ef1103632 100644 --- a/submodules/Postbox/Sources/Utils/Decoder/AdaptedPostboxKeyedDecodingContainer.swift +++ b/submodules/Postbox/Sources/Utils/Decoder/AdaptedPostboxKeyedDecodingContainer.swift @@ -28,7 +28,15 @@ extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol } func decode(_ type: T.Type, forKey key: Key) throws -> T where T : Decodable { - preconditionFailure() + if let (data, valueType) = self.decoder.decodeObjectDataForKey(key.stringValue) { + if let mappedType = AdaptedPostboxDecoder.ContentType(valueType: valueType) { + return try AdaptedPostboxDecoder().decode(T.self, from: data, contentType: mappedType) + } else { + throw DecodingError.typeMismatch(T.self, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: "")) + } + } else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: "")) + } } func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 { @@ -39,7 +47,7 @@ extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol } } - func decode(_ type: Int64.Type, forKey key: Key) throws -> Int32 { + func decode(_ type: Int64.Type, forKey key: Key) throws -> Int64 { if let value = self.decoder.decodeOptionalInt64ForKey(key.stringValue) { return value } else { @@ -47,7 +55,7 @@ extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol } } - func decode(_ type: Bool.Type, forKey key: Key) throws -> Int32 { + func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool { if let value = self.decoder.decodeOptionalBoolForKey(key.stringValue) { return value } else { @@ -55,7 +63,7 @@ extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol } } - func decode(_ type: String.Type, forKey key: Key) throws -> Int32 { + func decode(_ type: String.Type, forKey key: Key) throws -> String { if let value = self.decoder.decodeOptionalStringForKey(key.stringValue) { return value } else { diff --git a/submodules/Postbox/Sources/Utils/Decoder/AdaptedPostboxUnkeyedDecodingContainer.swift b/submodules/Postbox/Sources/Utils/Decoder/AdaptedPostboxUnkeyedDecodingContainer.swift index 4cf632bcab..27bdeddcfd 100644 --- a/submodules/Postbox/Sources/Utils/Decoder/AdaptedPostboxUnkeyedDecodingContainer.swift +++ b/submodules/Postbox/Sources/Utils/Decoder/AdaptedPostboxUnkeyedDecodingContainer.swift @@ -2,14 +2,128 @@ import Foundation extension _AdaptedPostboxDecoder { final class UnkeyedContainer { - var codingPath: [CodingKey] - var userInfo: [CodingUserInfoKey: Any] + enum Content { + case int32Array([Int32]) + case int64Array([Int64]) + case objectArray([Data]) + case stringArray([String]) + case dataArray([Data]) + + var count: Int { + switch self { + case let .int32Array(array): + return array.count + case let .int64Array(array): + return array.count + case let .objectArray(array): + return array.count + case let .stringArray(array): + return array.count + case let .dataArray(array): + return array.count + } + } + } + + let codingPath: [CodingKey] + let userInfo: [CodingUserInfoKey: Any] + let content: Content + + var count: Int? { + return self.content.count + } + + var isAtEnd: Bool { + return self.currentIndex >= self.content.count + } + + fileprivate var _currentIndex: Int = 0 + + var currentIndex: Int { + return self._currentIndex + } - init(data: Data, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) { + init(data: Data, codingPath: [CodingKey], userInfo: [CodingUserInfoKey: Any], content: Content) { self.codingPath = codingPath self.userInfo = userInfo + self.content = content } } } +extension _AdaptedPostboxDecoder.UnkeyedContainer: UnkeyedDecodingContainer { + func decodeNil() throws -> Bool { + preconditionFailure() + } + func decode(_ type: T.Type) throws -> T where T : Decodable { + if type == Data.self { + switch self.content { + case let .dataArray(array): + let index = self._currentIndex + self._currentIndex += 1 + return array[index] as! T + default: + throw DecodingError.typeMismatch(Data.self, DecodingError.Context(codingPath: self.codingPath, debugDescription: "")) + } + } else { + switch self.content { + case let .objectArray(array): + let index = self._currentIndex + self._currentIndex += 1 + + let data = array[index] + return try AdaptedPostboxDecoder().decode(T.self, from: data) + default: + throw DecodingError.typeMismatch(T.self, DecodingError.Context(codingPath: self.codingPath, debugDescription: "")) + } + } + } + + func decode(_ type: Int32.Type) throws -> Int32 { + switch self.content { + case let .int32Array(array): + let index = self._currentIndex + self._currentIndex += 1 + return array[index] + default: + throw DecodingError.typeMismatch(Int32.self, DecodingError.Context(codingPath: self.codingPath, debugDescription: "")) + } + } + + func decode(_ type: Int64.Type) throws -> Int64 { + switch self.content { + case let .int64Array(array): + let index = self._currentIndex + self._currentIndex += 1 + return array[index] + default: + throw DecodingError.typeMismatch(Int64.self, DecodingError.Context(codingPath: self.codingPath, debugDescription: "")) + } + } + + func decode(_ type: String.Type) throws -> String { + switch self.content { + case let .stringArray(array): + let index = self._currentIndex + self._currentIndex += 1 + return array[index] + default: + throw DecodingError.typeMismatch(String.self, DecodingError.Context(codingPath: self.codingPath, debugDescription: "")) + } + } + + func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer { + preconditionFailure() + } + + func nestedContainer(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer where NestedKey : CodingKey { + preconditionFailure() + } + + func superDecoder() throws -> Decoder { + preconditionFailure() + } +} + +extension _AdaptedPostboxDecoder.UnkeyedContainer: AdaptedPostboxDecodingContainer {}