This commit is contained in:
Ali 2021-07-30 01:33:11 +02:00
parent 6701106072
commit 15d1ba7193
7 changed files with 175 additions and 104 deletions

View File

@ -174,18 +174,6 @@ public struct ChatTextInputState: Codable, Equatable {
try container.encode(Int32(self.selectionRange.lowerBound), forKey: "as0") try container.encode(Int32(self.selectionRange.lowerBound), forKey: "as0")
try container.encode(Int32(self.selectionRange.upperBound), forKey: "as1") try container.encode(Int32(self.selectionRange.upperBound), forKey: "as1")
} }
/*public init(decoder: PostboxDecoder) {
self.inputText = ((decoder.decodeObjectForKey("at", decoder: { ChatTextInputStateText(decoder: $0) }) as? ChatTextInputStateText) ?? ChatTextInputStateText()).attributedText()
self.selectionRange = Int(decoder.decodeInt32ForKey("as0", orElse: 0)) ..< Int(decoder.decodeInt32ForKey("as1", orElse: 0))
}*/
/*public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObject(ChatTextInputStateText(attributedText: self.inputText), forKey: "at")
encoder.encodeInt32(Int32(self.selectionRange.lowerBound), forKey: "as0")
encoder.encodeInt32(Int32(self.selectionRange.upperBound), forKey: "as1")
}*/
} }
public enum ChatTextInputStateTextAttributeType: Codable, Equatable { public enum ChatTextInputStateTextAttributeType: Codable, Equatable {
@ -198,7 +186,7 @@ public enum ChatTextInputStateTextAttributeType: Codable, Equatable {
public init(from decoder: Decoder) throws { public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self) let container = try decoder.container(keyedBy: StringCodingKey.self)
switch (try? container.decodeIfPresent(Int32.self, forKey: "t")) ?? 0 { switch (try? container.decode(Int32.self, forKey: "t")) ?? 0 {
case 0: case 0:
self = .bold self = .bold
case 1: case 1:
@ -234,41 +222,6 @@ public enum ChatTextInputStateTextAttributeType: Codable, Equatable {
try container.encode(url, forKey: "url") try container.encode(url, forKey: "url")
} }
} }
/*public init(decoder: PostboxDecoder) {
switch decoder.decodeInt32ForKey("t", orElse: 0) {
case 0:
self = .bold
case 1:
self = .italic
case 2:
self = .monospace
case 3:
self = .textMention(EnginePeer.Id(decoder.decodeInt64ForKey("peerId", orElse: 0)))
case 4:
self = .textUrl(decoder.decodeStringForKey("url", orElse: ""))
default:
assertionFailure()
self = .bold
}
}
public func encode(_ encoder: PostboxEncoder) {
switch self {
case .bold:
encoder.encodeInt32(0, forKey: "t")
case .italic:
encoder.encodeInt32(1, forKey: "t")
case .monospace:
encoder.encodeInt32(2, forKey: "t")
case let .textMention(id):
encoder.encodeInt32(3, forKey: "t")
encoder.encodeInt64(id.toInt64(), forKey: "peerId")
case let .textUrl(url):
encoder.encodeInt32(4, forKey: "t")
encoder.encodeString(url, forKey: "url")
}
}*/
} }
public struct ChatTextInputStateTextAttribute: Codable, Equatable { public struct ChatTextInputStateTextAttribute: Codable, Equatable {
@ -283,8 +236,8 @@ public struct ChatTextInputStateTextAttribute: Codable, Equatable {
public init(from decoder: Decoder) throws { public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self) let container = try decoder.container(keyedBy: StringCodingKey.self)
self.type = try container.decode(ChatTextInputStateTextAttributeType.self, forKey: "type") self.type = try container.decode(ChatTextInputStateTextAttributeType.self, forKey: "type")
let rangeFrom = (try? container.decodeIfPresent(Int32.self, forKey: "range0")) ?? 0 let rangeFrom = (try? container.decode(Int32.self, forKey: "range0")) ?? 0
let rangeTo = (try? container.decodeIfPresent(Int32.self, forKey: "range1")) ?? 0 let rangeTo = (try? container.decode(Int32.self, forKey: "range1")) ?? 0
self.range = Int(rangeFrom) ..< Int(rangeTo) self.range = Int(rangeFrom) ..< Int(rangeTo)
} }
@ -298,17 +251,6 @@ public struct ChatTextInputStateTextAttribute: Codable, Equatable {
try container.encode(Int32(self.range.upperBound), forKey: "range1") try container.encode(Int32(self.range.upperBound), forKey: "range1")
} }
/*public init(decoder: PostboxDecoder) {
self.type = decoder.decodeObjectForKey("type", decoder: { ChatTextInputStateTextAttributeType(decoder: $0) }) as! ChatTextInputStateTextAttributeType
self.range = Int(decoder.decodeInt32ForKey("range0", orElse: 0)) ..< Int(decoder.decodeInt32ForKey("range1", orElse: 0))
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObject(self.type, forKey: "type")
encoder.encodeInt32(Int32(self.range.lowerBound), forKey: "range0")
encoder.encodeInt32(Int32(self.range.upperBound), forKey: "range1")
}*/
public static func ==(lhs: ChatTextInputStateTextAttribute, rhs: ChatTextInputStateTextAttribute) -> Bool { public static func ==(lhs: ChatTextInputStateTextAttribute, rhs: ChatTextInputStateTextAttribute) -> Bool {
return lhs.type == rhs.type && lhs.range == rhs.range return lhs.type == rhs.type && lhs.range == rhs.range
} }
@ -361,16 +303,6 @@ public struct ChatTextInputStateText: Codable, Equatable {
try container.encode(self.attributes, forKey: "attributes") try container.encode(self.attributes, forKey: "attributes")
} }
/*public init(decoder: PostboxDecoder) {
self.text = decoder.decodeStringForKey("text", orElse: "")
self.attributes = decoder.decodeObjectArrayWithDecoderForKey("attributes")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeString(self.text, forKey: "text")
encoder.encodeObjectArray(self.attributes, forKey: "attributes")
}*/
static public func ==(lhs: ChatTextInputStateText, rhs: ChatTextInputStateText) -> Bool { static public func ==(lhs: ChatTextInputStateText, rhs: ChatTextInputStateText) -> Bool {
return lhs.text == rhs.text && lhs.attributes == rhs.attributes return lhs.text == rhs.text && lhs.attributes == rhs.attributes
} }
@ -419,7 +351,7 @@ public final class ChatEmbeddedInterfaceState: PeerChatListEmbeddedInterfaceStat
public init(from decoder: Decoder) throws { public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self) let container = try decoder.container(keyedBy: StringCodingKey.self)
self.timestamp = (try? container.decode(Int32.self, forKey: "d")) ?? 0 self.timestamp = (try? container.decode(Int32.self, forKey: "d")) ?? 0
self.text = ((try? container.decodeIfPresent(ChatTextInputStateText.self, forKey: "at")) ?? ChatTextInputStateText()).attributedText() self.text = ((try? container.decode(ChatTextInputStateText.self, forKey: "at")) ?? ChatTextInputStateText()).attributedText()
} }
public func encode(to encoder: Encoder) throws { public func encode(to encoder: Encoder) throws {
@ -429,16 +361,6 @@ public final class ChatEmbeddedInterfaceState: PeerChatListEmbeddedInterfaceStat
try container.encode(ChatTextInputStateText(attributedText: self.text), forKey: "at") try container.encode(ChatTextInputStateText(attributedText: self.text), forKey: "at")
} }
/*public init(decoder: PostboxDecoder) {
self.timestamp = decoder.decodeInt32ForKey("d", orElse: 0)
self.text = ((decoder.decodeObjectForKey("at", decoder: { ChatTextInputStateText(decoder: $0) }) as? ChatTextInputStateText) ?? ChatTextInputStateText()).attributedText()
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32(self.timestamp, forKey: "d")
encoder.encodeObject(ChatTextInputStateText(attributedText: self.text), forKey: "at")
}*/
public func isEqual(to: PeerChatListEmbeddedInterfaceState) -> Bool { public func isEqual(to: PeerChatListEmbeddedInterfaceState) -> Bool {
if let to = to as? ChatEmbeddedInterfaceState { if let to = to as? ChatEmbeddedInterfaceState {
return self.timestamp == to.timestamp && self.text.isEqual(to: to.text) return self.timestamp == to.timestamp && self.text.isEqual(to: to.text)

View File

@ -603,16 +603,12 @@ public final class PostboxEncoder {
self.buffer.write(innerData) self.buffer.write(innerData)
} }
public func encodeInnerObjectData(_ value: Data, forKey key: String) { func encodeInnerObjectData(_ value: Data, valueType: ValueType, forKey key: String) {
self.encodeKey(key) self.encodeKey(key)
var t: Int8 = ValueType.Object.rawValue
var t: Int8 = valueType.rawValue
self.buffer.write(&t, offset: 0, length: 1) self.buffer.write(&t, offset: 0, length: 1)
var typeHash: Int32 = 0
self.buffer.write(&typeHash, offset: 0, length: 4)
var length: Int32 = Int32(value.count)
self.buffer.write(&length, offset: 0, length: 4)
self.buffer.write(value) self.buffer.write(value)
} }
@ -1008,7 +1004,7 @@ public final class PostboxDecoder {
let initialOffset = self.offset let initialOffset = self.offset
PostboxDecoder.skipValue(self.buffer.memory.assumingMemoryBound(to: Int8.self), offset: &self.offset, length: self.buffer.length, valueType: actualValueType) 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() let data = ReadBuffer(memory: UnsafeMutableRawPointer(mutating: self.buffer.memory.advanced(by: initialOffset)), length: self.offset - initialOffset, freeWhenDone: false).makeData()
return (data, actualValueType) return (data, actualValueType)
} }
@ -1179,7 +1175,16 @@ public final class PostboxDecoder {
return array return array
} else { } else {
return nil if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Int32Array) {
let array = decodeInt32ArrayRaw()
if array.isEmpty {
return []
} else {
return nil
}
} else {
return nil
}
} }
} }

View File

@ -14,6 +14,12 @@ extension _AdaptedPostboxDecoder {
} }
} }
private func decodingErrorBreakpoint() {
#if DEBUG
print("Decoding error. Install a breakpoint at decodingErrorBreakpoint to debug.")
#endif
}
extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol { extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol {
var allKeys: [Key] { var allKeys: [Key] {
preconditionFailure() preconditionFailure()
@ -32,9 +38,11 @@ extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol
if let mappedType = AdaptedPostboxDecoder.ContentType(valueType: valueType) { if let mappedType = AdaptedPostboxDecoder.ContentType(valueType: valueType) {
return try AdaptedPostboxDecoder().decode(T.self, from: data, contentType: mappedType) return try AdaptedPostboxDecoder().decode(T.self, from: data, contentType: mappedType)
} else { } else {
decodingErrorBreakpoint()
throw DecodingError.typeMismatch(T.self, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: "")) throw DecodingError.typeMismatch(T.self, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: ""))
} }
} else { } else {
decodingErrorBreakpoint()
throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: "")) throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: ""))
} }
} }
@ -43,6 +51,7 @@ extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol
if let value = self.decoder.decodeOptionalInt32ForKey(key.stringValue) { if let value = self.decoder.decodeOptionalInt32ForKey(key.stringValue) {
return value return value
} else { } else {
decodingErrorBreakpoint()
throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: "")) throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: ""))
} }
} }
@ -51,6 +60,7 @@ extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol
if let value = self.decoder.decodeOptionalInt64ForKey(key.stringValue) { if let value = self.decoder.decodeOptionalInt64ForKey(key.stringValue) {
return value return value
} else { } else {
decodingErrorBreakpoint()
throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: "")) throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: ""))
} }
} }
@ -59,6 +69,7 @@ extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol
if let value = self.decoder.decodeOptionalBoolForKey(key.stringValue) { if let value = self.decoder.decodeOptionalBoolForKey(key.stringValue) {
return value return value
} else { } else {
decodingErrorBreakpoint()
throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: "")) throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: ""))
} }
} }
@ -67,6 +78,7 @@ extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol
if let value = self.decoder.decodeOptionalStringForKey(key.stringValue) { if let value = self.decoder.decodeOptionalStringForKey(key.stringValue) {
return value return value
} else { } else {
decodingErrorBreakpoint()
throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: "")) throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: ""))
} }
} }

View File

@ -4,7 +4,7 @@ public class AdaptedPostboxEncoder {
func encode(_ value: Encodable) throws -> Data { func encode(_ value: Encodable) throws -> Data {
let encoder = _AdaptedPostboxEncoder() let encoder = _AdaptedPostboxEncoder()
try value.encode(to: encoder) try value.encode(to: encoder)
return encoder.data return encoder.makeData().0
} }
} }
@ -15,7 +15,7 @@ final class _AdaptedPostboxEncoder {
fileprivate var container: AdaptedPostboxEncodingContainer? fileprivate var container: AdaptedPostboxEncodingContainer?
var data: Data { func makeData() -> (Data, ValueType) {
return self.container!.makeData() return self.container!.makeData()
} }
} }
@ -35,7 +35,12 @@ extension _AdaptedPostboxEncoder: Encoder {
} }
func unkeyedContainer() -> UnkeyedEncodingContainer { func unkeyedContainer() -> UnkeyedEncodingContainer {
preconditionFailure() assertCanCreateContainer()
let container = UnkeyedContainer(codingPath: self.codingPath, userInfo: self.userInfo)
self.container = container
return container
} }
func singleValueContainer() -> SingleValueEncodingContainer { func singleValueContainer() -> SingleValueEncodingContainer {
@ -44,5 +49,5 @@ extension _AdaptedPostboxEncoder: Encoder {
} }
protocol AdaptedPostboxEncodingContainer: AnyObject { protocol AdaptedPostboxEncodingContainer: AnyObject {
func makeData() -> Data func makeData() -> (Data, ValueType)
} }

View File

@ -14,8 +14,19 @@ extension _AdaptedPostboxEncoder {
self.encoder = PostboxEncoder() self.encoder = PostboxEncoder()
} }
func makeData() -> Data { func makeData() -> (Data, ValueType) {
return self.encoder.makeData() let buffer = WriteBuffer()
var typeHash: Int32 = 0
buffer.write(&typeHash, offset: 0, length: 4)
let data = self.encoder.makeData()
var length: Int32 = Int32(data.count)
buffer.write(&length, offset: 0, length: 4)
buffer.write(data)
return (buffer.makeData(), .Object)
} }
} }
} }
@ -25,7 +36,8 @@ extension _AdaptedPostboxEncoder.KeyedContainer: KeyedEncodingContainerProtocol
let innerEncoder = _AdaptedPostboxEncoder() let innerEncoder = _AdaptedPostboxEncoder()
try! value.encode(to: innerEncoder) try! value.encode(to: innerEncoder)
self.encoder.encodeInnerObjectData(innerEncoder.data, forKey: key.stringValue) let (data, valueType) = innerEncoder.makeData()
self.encoder.encodeInnerObjectData(data, valueType: valueType, forKey: key.stringValue)
} }
func encodeNil(forKey key: Key) throws { func encodeNil(forKey key: Key) throws {

View File

@ -79,7 +79,7 @@ extension _AdaptedPostboxEncoder.SingleValueContainer: SingleValueEncodingContai
} }
extension _AdaptedPostboxEncoder.SingleValueContainer: AdaptedPostboxEncodingContainer { extension _AdaptedPostboxEncoder.SingleValueContainer: AdaptedPostboxEncodingContainer {
func makeData() -> Data { func makeData() -> (Data, ValueType) {
preconditionFailure() preconditionFailure()
} }
} }

View File

@ -1,17 +1,102 @@
import Foundation import Foundation
import MurMurHash32
extension _AdaptedPostboxEncoder { extension _AdaptedPostboxEncoder {
final class UnkeyedContainer { final class UnkeyedContainer {
var codingPath: [CodingKey] fileprivate enum Item {
var userInfo: [CodingUserInfoKey: Any] case int32(Int32)
case int64(Int64)
case string(String)
case object(Data)
case data(Data)
}
let codingPath: [CodingKey]
let userInfo: [CodingUserInfoKey: Any]
fileprivate var items: [Item] = []
var count: Int { var count: Int {
preconditionFailure() return self.items.count
} }
init(codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) { init(codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
self.codingPath = codingPath self.codingPath = codingPath
self.userInfo = userInfo self.userInfo = userInfo
} }
func makeData() -> (Data, ValueType) {
if self.items.isEmpty {
let buffer = WriteBuffer()
var length: Int32 = Int32(self.items.count)
buffer.write(&length, offset: 0, length: 4)
return (buffer.makeData(), .Int32Array)
} else if self.items.allSatisfy({ if case .int32 = $0 { return true } else { return false } }) {
let buffer = WriteBuffer()
var length: Int32 = Int32(self.items.count)
buffer.write(&length, offset: 0, length: 4)
for case .int32(var value) in self.items {
buffer.write(&value, offset: 0, length: 4)
}
return (buffer.makeData(), .Int32Array)
} else if self.items.allSatisfy({ if case .int64 = $0 { return true } else { return false } }) {
let buffer = WriteBuffer()
var length: Int32 = Int32(self.items.count)
buffer.write(&length, offset: 0, length: 4)
for case .int64(var value) in self.items {
buffer.write(&value, offset: 0, length: 4)
}
return (buffer.makeData(), .Int64Array)
} else if self.items.allSatisfy({ if case .string = $0 { return true } else { return false } }) {
let buffer = WriteBuffer()
var length: Int32 = Int32(self.items.count)
buffer.write(&length, offset: 0, length: 4)
for case .string(let value) in self.items {
let data = value.data(using: .utf8, allowLossyConversion: true) ?? (String("").data(using: .utf8)!)
var valueLength: Int32 = Int32(data.count)
buffer.write(&valueLength, offset: 0, length: 4)
buffer.write(data)
}
return (buffer.makeData(), .StringArray)
} else if self.items.allSatisfy({ if case .object = $0 { return true } else { return false } }) {
let buffer = WriteBuffer()
var length: Int32 = Int32(self.items.count)
buffer.write(&length, offset: 0, length: 4)
for case .object(let data) in self.items {
buffer.write(data)
}
return (buffer.makeData(), .ObjectArray)
} else if self.items.allSatisfy({ if case .data = $0 { return true } else { return false } }) {
let buffer = WriteBuffer()
var length: Int32 = Int32(self.items.count)
buffer.write(&length, offset: 0, length: 4)
for case .data(let data) in self.items {
var valueLength: Int32 = Int32(data.count)
buffer.write(&valueLength, offset: 0, length: 4)
buffer.write(data)
}
return (buffer.makeData(), .BytesArray)
} else {
preconditionFailure()
}
}
} }
} }
@ -21,7 +106,37 @@ extension _AdaptedPostboxEncoder.UnkeyedContainer: UnkeyedEncodingContainer {
} }
func encode<T>(_ value: T) throws where T : Encodable { func encode<T>(_ value: T) throws where T : Encodable {
preconditionFailure() let innerEncoder = _AdaptedPostboxEncoder()
try! value.encode(to: innerEncoder)
let (data, _) = innerEncoder.makeData()
let buffer = WriteBuffer()
var typeHash: Int32 = murMurHashString32("\(type(of: value))")
buffer.write(&typeHash, offset: 0, length: 4)
var length: Int32 = Int32(data.count)
buffer.write(&length, offset: 0, length: 4)
buffer.write(data)
self.items.append(.object(buffer.makeData()))
}
func encode(_ value: Int32) throws {
self.items.append(.int32(value))
}
func encode(_ value: Int64) throws {
self.items.append(.int64(value))
}
func encode(_ value: String) throws {
self.items.append(.string(value))
}
func encode(_ value: Data) throws {
self.items.append(.data(value))
} }
func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey { func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey {