This commit is contained in:
Ali 2021-07-29 21:07:15 +02:00
parent d46c7b739d
commit e874fa92ff
15 changed files with 869 additions and 67 deletions

View File

@ -130,7 +130,7 @@ public enum ChatControllerInteractionNavigateToPeer {
case withBotStartPayload(ChatControllerInitialBotStart)
}
public struct ChatTextInputState: PostboxCoding, Equatable {
public struct ChatTextInputState: Codable, Equatable {
public let inputText: NSAttributedString
public let selectionRange: Range<Int>
@ -153,28 +153,89 @@ public struct ChatTextInputState: PostboxCoding, Equatable {
let length = inputText.length
self.selectionRange = length ..< length
}
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 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
if rangeFrom <= rangeTo {
self.selectionRange = Int(rangeFrom) ..< Int(rangeTo)
} else {
let length = self.inputText.length
self.selectionRange = length ..< length
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(ChatTextInputStateText(attributedText: self.inputText), forKey: "at")
try container.encode(Int32(self.selectionRange.lowerBound), forKey: "as0")
try container.encode(Int32(self.selectionRange.upperBound), forKey: "as1")
}
public func encode(_ encoder: PostboxEncoder) {
/*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: PostboxCoding, Equatable {
public enum ChatTextInputStateTextAttributeType: Codable, Equatable {
case bold
case italic
case monospace
case textMention(EnginePeer.Id)
case textUrl(String)
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
switch (try? container.decodeIfPresent(Int32.self, forKey: "t")) ?? 0 {
case 0:
self = .bold
case 1:
self = .italic
case 2:
self = .monospace
case 3:
let peerId = (try? container.decode(Int64.self, forKey: "peerId")) ?? 0
self = .textMention(EnginePeer.Id(peerId))
case 4:
let url = (try? container.decode(String.self, forKey: "url")) ?? ""
self = .textUrl(url)
default:
assertionFailure()
self = .bold
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
switch self {
case .bold:
try container.encode(0 as Int32, forKey: "t")
case .italic:
try container.encode(1 as Int32, forKey: "t")
case .monospace:
try container.encode(2 as Int32, forKey: "t")
case let .textMention(id):
try container.encode(3 as Int32, forKey: "t")
try container.encode(id.toInt64(), forKey: "peerId")
case let .textUrl(url):
try container.encode(4 as Int32, forKey: "t")
try container.encode(url, forKey: "url")
}
}
public init(decoder: PostboxDecoder) {
/*public init(decoder: PostboxDecoder) {
switch decoder.decodeInt32ForKey("t", orElse: 0) {
case 0:
self = .bold
@ -207,45 +268,10 @@ public enum ChatTextInputStateTextAttributeType: PostboxCoding, Equatable {
encoder.encodeInt32(4, forKey: "t")
encoder.encodeString(url, forKey: "url")
}
}
public static func ==(lhs: ChatTextInputStateTextAttributeType, rhs: ChatTextInputStateTextAttributeType) -> Bool {
switch lhs {
case .bold:
if case .bold = rhs {
return true
} else {
return false
}
case .italic:
if case .italic = rhs {
return true
} else {
return false
}
case .monospace:
if case .monospace = rhs {
return true
} else {
return false
}
case let .textMention(id):
if case .textMention(id) = rhs {
return true
} else {
return false
}
case let .textUrl(url):
if case .textUrl(url) = rhs {
return true
} else {
return false
}
}
}
}*/
}
public struct ChatTextInputStateTextAttribute: PostboxCoding, Equatable {
public struct ChatTextInputStateTextAttribute: Codable, Equatable {
public let type: ChatTextInputStateTextAttributeType
public let range: Range<Int>
@ -253,8 +279,26 @@ public struct ChatTextInputStateTextAttribute: PostboxCoding, Equatable {
self.type = type
self.range = range
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.type = try container.decode(ChatTextInputStateTextAttributeType.self, forKey: "type")
let rangeFrom = (try? container.decodeIfPresent(Int32.self, forKey: "range0")) ?? 0
let rangeTo = (try? container.decodeIfPresent(Int32.self, forKey: "range1")) ?? 0
self.range = Int(rangeFrom) ..< Int(rangeTo)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(self.type, forKey: "type")
try container.encode(Int32(self.range.lowerBound), forKey: "range0")
try container.encode(Int32(self.range.upperBound), forKey: "range1")
}
public init(decoder: PostboxDecoder) {
/*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))
}
@ -263,14 +307,14 @@ public struct ChatTextInputStateTextAttribute: PostboxCoding, Equatable {
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 {
return lhs.type == rhs.type && lhs.range == rhs.range
}
}
public struct ChatTextInputStateText: PostboxCoding, Equatable {
public struct ChatTextInputStateText: Codable, Equatable {
public let text: String
public let attributes: [ChatTextInputStateTextAttribute]
@ -304,8 +348,20 @@ public struct ChatTextInputStateText: PostboxCoding, Equatable {
})
self.attributes = parsedAttributes
}
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")) ?? []
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(self.text, forKey: "text")
try container.encode(self.attributes, forKey: "attributes")
}
public init(decoder: PostboxDecoder) {
/*public init(decoder: PostboxDecoder) {
self.text = decoder.decodeStringForKey("text", orElse: "")
self.attributes = decoder.decodeObjectArrayWithDecoderForKey("attributes")
}
@ -313,7 +369,7 @@ public struct ChatTextInputStateText: PostboxCoding, Equatable {
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 {
return lhs.text == rhs.text && lhs.attributes == rhs.attributes
@ -359,8 +415,21 @@ public final class ChatEmbeddedInterfaceState: PeerChatListEmbeddedInterfaceStat
self.timestamp = timestamp
self.text = text
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.timestamp = (try? container.decode(Int32.self, forKey: "d")) ?? 0
self.text = ((try? container.decodeIfPresent(ChatTextInputStateText.self, forKey: "at")) ?? ChatTextInputStateText()).attributedText()
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(self.timestamp, forKey: "d")
try container.encode(ChatTextInputStateText(attributedText: self.text), forKey: "at")
}
public init(decoder: PostboxDecoder) {
/*public init(decoder: PostboxDecoder) {
self.timestamp = decoder.decodeInt32ForKey("d", orElse: 0)
self.text = ((decoder.decodeObjectForKey("at", decoder: { ChatTextInputStateText(decoder: $0) }) as? ChatTextInputStateText) ?? ChatTextInputStateText()).attributedText()
}
@ -368,7 +437,7 @@ public final class ChatEmbeddedInterfaceState: PeerChatListEmbeddedInterfaceStat
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 {
if let to = to as? ChatEmbeddedInterfaceState {

View File

@ -10,7 +10,7 @@ public enum ChatTextInputMediaRecordingButtonMode: Int32 {
case video = 1
}
public struct ChatInterfaceSelectionState: PostboxCoding, Equatable {
public struct ChatInterfaceSelectionState: Codable, Equatable {
public let selectedIds: Set<MessageId>
public static func ==(lhs: ChatInterfaceSelectionState, rhs: ChatInterfaceSelectionState) -> Bool {
@ -20,8 +20,28 @@ public struct ChatInterfaceSelectionState: PostboxCoding, Equatable {
public init(selectedIds: Set<MessageId>) {
self.selectedIds = selectedIds
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
if let data = try? container.decodeIfPresent(Data.self, forKey: "i") {
self.selectedIds = Set(MessageId.decodeArrayFromBuffer(ReadBuffer(data: data)))
} else {
self.selectedIds = Set()
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
let buffer = WriteBuffer()
MessageId.encodeArrayToBuffer(Array(selectedIds), buffer: buffer)
try container.encode(buffer.makeData(), forKey: "i")
}
public init(decoder: PostboxDecoder) {
/*public init(decoder: PostboxDecoder) {
if let data = decoder.decodeBytesForKeyNoCopy("i") {
self.selectedIds = Set(MessageId.decodeArrayFromBuffer(data))
} else {
@ -33,10 +53,10 @@ public struct ChatInterfaceSelectionState: PostboxCoding, Equatable {
let buffer = WriteBuffer()
MessageId.encodeArrayToBuffer(Array(selectedIds), buffer: buffer)
encoder.encodeBytes(buffer, forKey: "i")
}
}*/
}
public struct ChatEditMessageState: PostboxCoding, Equatable {
public struct ChatEditMessageState: Codable, Equatable {
public let messageId: MessageId
public let inputState: ChatTextInputState
public let disableUrlPreview: String?
@ -48,8 +68,41 @@ public struct ChatEditMessageState: PostboxCoding, Equatable {
self.disableUrlPreview = disableUrlPreview
self.inputTextMaxLength = inputTextMaxLength
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.messageId = MessageId(
peerId: PeerId((try? container.decode(Int64.self, forKey: "mp")) ?? 0),
namespace: (try? container.decode(Int32.self, forKey: "mn")) ?? 0,
id: (try? container.decode(Int32.self, forKey: "mi")) ?? 0
)
if let inputState = try? container.decode(ChatTextInputState.self, forKey: "is") {
self.inputState = inputState
} else {
self.inputState = ChatTextInputState()
}
self.disableUrlPreview = try? container.decodeIfPresent(String.self, forKey: "dup")
self.inputTextMaxLength = try? container.decodeIfPresent(Int32.self, forKey: "tl")
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(self.messageId.peerId.toInt64(), forKey: "mp")
try container.encode(self.messageId.namespace, forKey: "mn")
try container.encode(self.messageId.id, forKey: "mi")
try container.encode(self.inputState, forKey: "is")
try container.encodeIfPresent(self.disableUrlPreview, forKey: "dup")
try container.encodeIfPresent(self.inputTextMaxLength, forKey: "tl")
}
public init(decoder: PostboxDecoder) {
/*public init(decoder: PostboxDecoder) {
self.messageId = MessageId(peerId: PeerId(decoder.decodeInt64ForKey("mp", orElse: 0)), namespace: decoder.decodeInt32ForKey("mn", orElse: 0), id: decoder.decodeInt32ForKey("mi", orElse: 0))
if let inputState = decoder.decodeObjectForKey("is", decoder: { return ChatTextInputState(decoder: $0) }) as? ChatTextInputState {
self.inputState = inputState
@ -75,7 +128,7 @@ public struct ChatEditMessageState: PostboxCoding, Equatable {
} else {
encoder.encodeNil(forKey: "ml")
}
}
}*/
public static func ==(lhs: ChatEditMessageState, rhs: ChatEditMessageState) -> Bool {
return lhs.messageId == rhs.messageId && lhs.inputState == rhs.inputState && lhs.disableUrlPreview == rhs.disableUrlPreview && lhs.inputTextMaxLength == rhs.inputTextMaxLength
@ -322,7 +375,7 @@ public final class ChatInterfaceState: SynchronizeableChatInterfaceState, Equata
public init(decoder: PostboxDecoder) {
self.timestamp = decoder.decodeInt32ForKey("ts", orElse: 0)
if let inputState = decoder.decodeObjectForKey("is", decoder: { return ChatTextInputState(decoder: $0) }) as? ChatTextInputState {
if let inputState = decoder.decode(ChatTextInputState.self, forKey: "is") {
self.composeInputState = inputState
} else {
self.composeInputState = ChatTextInputState()
@ -345,12 +398,12 @@ public final class ChatInterfaceState: SynchronizeableChatInterfaceState, Equata
} else {
self.forwardMessageIds = nil
}
if let editMessage = decoder.decodeObjectForKey("em", decoder: { ChatEditMessageState(decoder: $0) }) as? ChatEditMessageState {
if let editMessage = decoder.decode(ChatEditMessageState.self, forKey: "em") {
self.editMessage = editMessage
} else {
self.editMessage = nil
}
if let selectionState = decoder.decodeObjectForKey("ss", decoder: { return ChatInterfaceSelectionState(decoder: $0) }) as? ChatInterfaceSelectionState {
if let selectionState = decoder.decode(ChatInterfaceSelectionState.self, forKey: "ss") {
self.selectionState = selectionState
} else {
self.selectionState = nil
@ -372,7 +425,7 @@ public final class ChatInterfaceState: SynchronizeableChatInterfaceState, Equata
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32(self.timestamp, forKey: "ts")
encoder.encodeObject(self.composeInputState, forKey: "is")
encoder.encode(self.composeInputState, forKey: "is")
if let composeDisableUrlPreview = self.composeDisableUrlPreview {
encoder.encodeString(composeDisableUrlPreview, forKey: "dup")
} else {
@ -395,12 +448,12 @@ public final class ChatInterfaceState: SynchronizeableChatInterfaceState, Equata
encoder.encodeNil(forKey: "fm")
}
if let editMessage = self.editMessage {
encoder.encodeObject(editMessage, forKey: "em")
encoder.encode(editMessage, forKey: "em")
} else {
encoder.encodeNil(forKey: "em")
}
if let selectionState = self.selectionState {
encoder.encodeObject(selectionState, forKey: "ss")
encoder.encode(selectionState, forKey: "ss")
} else {
encoder.encodeNil(forKey: "ss")
}

View File

@ -278,6 +278,12 @@ public final class PostboxEncoder {
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)
@ -302,6 +308,14 @@ public final class PostboxEncoder {
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
self.buffer.write(&type, offset: 0, length: 1)
var v = value
self.buffer.write(&v, offset: 0, length: 8)
}
public func encodeBool(_ value: Bool, forKey key: StaticString) {
self.encodeKey(key)
@ -310,6 +324,14 @@ public final class PostboxEncoder {
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
self.buffer.write(&type, offset: 0, length: 1)
var v: Int8 = value ? 1 : 0
self.buffer.write(&v, offset: 0, length: 1)
}
public func encodeDouble(_ value: Double, forKey key: StaticString) {
self.encodeKey(key)
@ -318,6 +340,14 @@ public final class PostboxEncoder {
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
self.buffer.write(&type, offset: 0, length: 1)
var v = value
self.buffer.write(&v, offset: 0, length: 8)
}
public func encodeString(_ value: String, forKey key: StaticString) {
self.encodeKey(key)
@ -332,6 +362,20 @@ public final class PostboxEncoder {
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
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 encodeRootObject(_ value: PostboxCoding) {
self.encodeObject(value, forKey: "_")
@ -598,6 +642,38 @@ public final class PostboxEncoder {
}
}
public func encode<T: Encodable>(_ value: T, forKey key: String) {
let innerEncoder = AdaptedPostboxEncoder()
guard let innerData = try? innerEncoder.encode(value) else {
return
}
self.encodeKey(key)
var t: Int8 = ValueType.Object.rawValue
self.buffer.write(&t, offset: 0, length: 1)
let string = "\(type(of: value))"
var typeHash: Int32 = murMurHashString32(string)
self.buffer.write(&typeHash, offset: 0, length: 4)
var length: Int32 = Int32(innerData.count)
self.buffer.write(&length, offset: 0, length: 4)
self.buffer.write(innerData)
}
public func encodeInnerObjectData(_ value: Data, forKey key: String) {
self.encodeKey(key)
var t: Int8 = ValueType.Object.rawValue
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)
}
public let sharedWriteBuffer = WriteBuffer()
}
@ -718,6 +794,60 @@ public final class PostboxDecoder {
return false
}
private class func positionOnKey(_ rawBytes: UnsafeRawPointer, offset: inout Int, maxOffset: Int, length: Int, key: String, valueType: ValueType?, consumeKey: Bool = true) -> Bool
{
let bytes = rawBytes.assumingMemoryBound(to: Int8.self)
let startOffset = offset
let keyData = key.data(using: .utf8)!
let keyLength: Int = keyData.count
while (offset < maxOffset) {
let keyOffset = offset
let readKeyLength = bytes[offset]
assert(readKeyLength >= 0)
offset += 1
offset += Int(readKeyLength)
let readValueType = bytes[offset]
offset += 1
if keyLength != Int(readKeyLength) {
skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!)
continue
}
if keyData.withUnsafeBytes({ keyBytes -> Bool in
return memcmp(bytes + (offset - Int(readKeyLength) - 1), keyBytes.baseAddress!, keyLength) == 0
}) {
if let valueType = valueType {
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 {
if !consumeKey {
offset = keyOffset
}
return true
}
} 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 positionOnStringKey(_ rawBytes: UnsafeRawPointer, offset: inout Int, maxOffset: Int, length: Int, key: String, valueType: ValueType) -> Bool
{
let bytes = rawBytes.assumingMemoryBound(to: Int8.self)
@ -789,6 +919,22 @@ public final class PostboxDecoder {
return false
}
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) {
return true
} else {
return false
}
}
public func decodeNilForKey(_ key: String) -> Bool {
if PostboxDecoder.positionOnKey(self.buffer.memory, offset: &self.offset, maxOffset: self.buffer.length, length: self.buffer.length, key: key, valueType: .Nil) {
return true
} else {
return false
}
}
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) {
@ -1520,4 +1666,38 @@ public final class PostboxDecoder {
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
memcpy(&length, self.buffer.memory + self.offset, 4)
self.offset += 4 + Int(length)
var result = Data(count: Int(length))
result.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<Int8>) -> Void in
memcpy(bytes, self.buffer.memory.advanced(by: self.offset - Int(length)), Int(length))
}
return result
} else {
return nil
}
}
public func decode<T: Decodable>(_ type: T.Type, forKey key: String) -> T? {
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)
self.offset += 4
var length: Int32 = 0
memcpy(&length, self.buffer.memory + self.offset, 4)
let innerBuffer = ReadBuffer(memory: self.buffer.memory + (self.offset + 4), length: Int(length), freeWhenDone: false)
let innerData = innerBuffer.makeData()
self.offset += 4 + Int(length)
return try? AdaptedPostboxDecoder().decode(T.self, from: innerData)
} else {
return nil
}
}
}

View File

@ -1,5 +1,5 @@
public protocol PeerChatListEmbeddedInterfaceState: PostboxCoding {
public protocol PeerChatListEmbeddedInterfaceState: Codable {
var timestamp: Int32 { get }
func isEqual(to: PeerChatListEmbeddedInterfaceState) -> Bool

View File

@ -0,0 +1,47 @@
import Foundation
final public class AdaptedPostboxDecoder {
func decode<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable {
let decoder = _AdaptedPostboxDecoder(data: data)
return try T(from: decoder)
}
}
final class _AdaptedPostboxDecoder {
var codingPath: [CodingKey] = []
var userInfo: [CodingUserInfoKey : Any] = [:]
var container: AdaptedPostboxDecodingContainer?
fileprivate var data: Data
init(data: Data) {
self.data = data
}
}
extension _AdaptedPostboxDecoder: Decoder {
fileprivate func assertCanCreateContainer() {
precondition(self.container == nil)
}
func container<Key>(keyedBy type: Key.Type) -> KeyedDecodingContainer<Key> where Key : CodingKey {
assertCanCreateContainer()
let container = KeyedContainer<Key>(data: self.data, codingPath: self.codingPath, userInfo: self.userInfo)
self.container = container
return KeyedDecodingContainer(container)
}
func unkeyedContainer() -> UnkeyedDecodingContainer {
preconditionFailure()
}
func singleValueContainer() -> SingleValueDecodingContainer {
preconditionFailure()
}
}
protocol AdaptedPostboxDecodingContainer: AnyObject {
}

View File

@ -0,0 +1,83 @@
import Foundation
extension _AdaptedPostboxDecoder {
final class KeyedContainer<Key> where Key: CodingKey {
var codingPath: [CodingKey]
var userInfo: [CodingUserInfoKey: Any]
let decoder: PostboxDecoder
init(data: Data, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
self.codingPath = codingPath
self.userInfo = userInfo
self.decoder = PostboxDecoder(buffer: MemoryBuffer(data: data))
}
}
}
extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol {
var allKeys: [Key] {
preconditionFailure()
}
func contains(_ key: Key) -> Bool {
return self.decoder.containsKey(key.stringValue)
}
func decodeNil(forKey key: Key) throws -> Bool {
return self.decoder.decodeNilForKey(key.stringValue)
}
func decode<T>(_ type: T.Type, forKey key: Key) throws -> T where T : Decodable {
preconditionFailure()
}
func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 {
if let value = self.decoder.decodeOptionalInt32ForKey(key.stringValue) {
return value
} else {
throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: ""))
}
}
func decode(_ type: Int64.Type, forKey key: Key) throws -> Int32 {
if let value = self.decoder.decodeOptionalInt64ForKey(key.stringValue) {
return value
} else {
throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: ""))
}
}
func decode(_ type: Bool.Type, forKey key: Key) throws -> Int32 {
if let value = self.decoder.decodeOptionalBoolForKey(key.stringValue) {
return value
} else {
throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: ""))
}
}
func decode(_ type: String.Type, forKey key: Key) throws -> Int32 {
if let value = self.decoder.decodeOptionalStringForKey(key.stringValue) {
return value
} else {
throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: ""))
}
}
func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer {
preconditionFailure()
}
func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer<NestedKey> where NestedKey : CodingKey {
preconditionFailure()
}
func superDecoder() throws -> Decoder {
preconditionFailure()
}
func superDecoder(forKey key: Key) throws -> Decoder {
preconditionFailure()
}
}
extension _AdaptedPostboxDecoder.KeyedContainer: AdaptedPostboxDecodingContainer {}

View File

@ -0,0 +1,82 @@
import Foundation
extension _AdaptedPostboxDecoder {
final class SingleValueContainer {
var codingPath: [CodingKey]
var userInfo: [CodingUserInfoKey: Any]
init(codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
self.codingPath = codingPath
self.userInfo = userInfo
}
}
}
extension _AdaptedPostboxDecoder.SingleValueContainer: SingleValueDecodingContainer {
func decodeNil() -> Bool {
preconditionFailure()
}
func decode(_ type: Bool.Type) throws -> Bool {
preconditionFailure()
}
func decode(_ type: String.Type) throws -> String {
preconditionFailure()
}
func decode(_ type: Double.Type) throws -> Double {
preconditionFailure()
}
func decode(_ type: Float.Type) throws -> Float {
preconditionFailure()
}
func decode(_ type: Int.Type) throws -> Int {
preconditionFailure()
}
func decode(_ type: Int8.Type) throws -> Int8 {
preconditionFailure()
}
func decode(_ type: Int16.Type) throws -> Int16 {
preconditionFailure()
}
func decode(_ type: Int32.Type) throws -> Int32 {
preconditionFailure()
}
func decode(_ type: Int64.Type) throws -> Int64 {
preconditionFailure()
}
func decode(_ type: UInt.Type) throws -> UInt {
preconditionFailure()
}
func decode(_ type: UInt8.Type) throws -> UInt8 {
preconditionFailure()
}
func decode(_ type: UInt16.Type) throws -> UInt16 {
preconditionFailure()
}
func decode(_ type: UInt32.Type) throws -> UInt32 {
preconditionFailure()
}
func decode(_ type: UInt64.Type) throws -> UInt64 {
preconditionFailure()
}
func decode<T>(_ type: T.Type) throws -> T where T : Decodable {
preconditionFailure()
}
}
extension _AdaptedPostboxDecoder.SingleValueContainer: AdaptedPostboxDecodingContainer {}

View File

@ -0,0 +1,15 @@
import Foundation
extension _AdaptedPostboxDecoder {
final class UnkeyedContainer {
var codingPath: [CodingKey]
var userInfo: [CodingUserInfoKey: Any]
init(data: Data, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
self.codingPath = codingPath
self.userInfo = userInfo
}
}
}

View File

@ -0,0 +1,48 @@
import Foundation
public class AdaptedPostboxEncoder {
func encode(_ value: Encodable) throws -> Data {
let encoder = _AdaptedPostboxEncoder()
try value.encode(to: encoder)
return encoder.data
}
}
final class _AdaptedPostboxEncoder {
var codingPath: [CodingKey] = []
var userInfo: [CodingUserInfoKey : Any] = [:]
fileprivate var container: AdaptedPostboxEncodingContainer?
var data: Data {
return self.container!.makeData()
}
}
extension _AdaptedPostboxEncoder: Encoder {
fileprivate func assertCanCreateContainer() {
precondition(self.container == nil)
}
func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key : CodingKey {
assertCanCreateContainer()
let container = KeyedContainer<Key>(codingPath: self.codingPath, userInfo: self.userInfo)
self.container = container
return KeyedEncodingContainer(container)
}
func unkeyedContainer() -> UnkeyedEncodingContainer {
preconditionFailure()
}
func singleValueContainer() -> SingleValueEncodingContainer {
preconditionFailure()
}
}
protocol AdaptedPostboxEncodingContainer: AnyObject {
func makeData() -> Data
}

View File

@ -0,0 +1,72 @@
import Foundation
extension _AdaptedPostboxEncoder {
final class KeyedContainer<Key> where Key: CodingKey {
var codingPath: [CodingKey]
var userInfo: [CodingUserInfoKey: Any]
let encoder: PostboxEncoder
init(codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
self.codingPath = codingPath
self.userInfo = userInfo
self.encoder = PostboxEncoder()
}
func makeData() -> Data {
return self.encoder.makeData()
}
}
}
extension _AdaptedPostboxEncoder.KeyedContainer: KeyedEncodingContainerProtocol {
func encode<T>(_ value: T, forKey key: Key) throws where T : Encodable {
let innerEncoder = _AdaptedPostboxEncoder()
try! value.encode(to: innerEncoder)
self.encoder.encodeInnerObjectData(innerEncoder.data, forKey: key.stringValue)
}
func encodeNil(forKey key: Key) throws {
self.encoder.encodeNil(forKey: key.stringValue)
}
func encode(_ value: Int32, forKey key: Key) throws {
self.encoder.encodeInt32(value, forKey: key.stringValue)
}
func encode(_ value: Int64, forKey key: Key) throws {
self.encoder.encodeInt64(value, forKey: key.stringValue)
}
func encode(_ value: Bool, forKey key: Key) throws {
self.encoder.encodeBool(value, forKey: key.stringValue)
}
func encode(_ value: Double, forKey key: Key) throws {
self.encoder.encodeDouble(value, forKey: key.stringValue)
}
func encode(_ value: String, forKey key: Key) throws {
self.encoder.encodeString(value, forKey: key.stringValue)
}
func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer {
preconditionFailure()
}
func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey {
preconditionFailure()
}
func superEncoder() -> Encoder {
preconditionFailure()
}
func superEncoder(forKey key: Key) -> Encoder {
preconditionFailure()
}
}
extension _AdaptedPostboxEncoder.KeyedContainer: AdaptedPostboxEncodingContainer {}

View File

@ -0,0 +1,85 @@
import Foundation
extension _AdaptedPostboxEncoder {
final class SingleValueContainer {
var codingPath: [CodingKey]
var userInfo: [CodingUserInfoKey: Any]
init(codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
self.codingPath = codingPath
self.userInfo = userInfo
}
}
}
extension _AdaptedPostboxEncoder.SingleValueContainer: SingleValueEncodingContainer {
func encodeNil() throws {
preconditionFailure()
}
func encode(_ value: Bool) throws {
preconditionFailure()
}
func encode(_ value: String) throws {
preconditionFailure()
}
func encode(_ value: Double) throws {
preconditionFailure()
}
func encode(_ value: Float) throws {
preconditionFailure()
}
func encode(_ value: Int) throws {
preconditionFailure()
}
func encode(_ value: Int8) throws {
preconditionFailure()
}
func encode(_ value: Int16) throws {
preconditionFailure()
}
func encode(_ value: Int32) throws {
preconditionFailure()
}
func encode(_ value: Int64) throws {
preconditionFailure()
}
func encode(_ value: UInt) throws {
preconditionFailure()
}
func encode(_ value: UInt8) throws {
preconditionFailure()
}
func encode(_ value: UInt16) throws {
preconditionFailure()
}
func encode(_ value: UInt32) throws {
preconditionFailure()
}
func encode(_ value: UInt64) throws {
preconditionFailure()
}
func encode<T>(_ value: T) throws where T : Encodable {
preconditionFailure()
}
}
extension _AdaptedPostboxEncoder.SingleValueContainer: AdaptedPostboxEncodingContainer {
func makeData() -> Data {
preconditionFailure()
}
}

View File

@ -0,0 +1,44 @@
import Foundation
extension _AdaptedPostboxEncoder {
final class UnkeyedContainer {
var codingPath: [CodingKey]
var userInfo: [CodingUserInfoKey: Any]
var count: Int {
preconditionFailure()
}
init(codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
self.codingPath = codingPath
self.userInfo = userInfo
}
}
}
extension _AdaptedPostboxEncoder.UnkeyedContainer: UnkeyedEncodingContainer {
func encodeNil() throws {
preconditionFailure()
}
func encode<T>(_ value: T) throws where T : Encodable {
preconditionFailure()
}
func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> where NestedKey : CodingKey {
preconditionFailure()
}
func nestedUnkeyedContainer() -> UnkeyedEncodingContainer {
preconditionFailure()
}
func superEncoder() -> Encoder {
preconditionFailure()
}
}
extension _AdaptedPostboxEncoder.UnkeyedContainer: AdaptedPostboxEncodingContainer {
func makeData() -> Data {
preconditionFailure()
}
}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,24 @@
public struct StringCodingKey: CodingKey, ExpressibleByStringLiteral {
public var stringValue: String
public init?(stringValue: String) {
self.stringValue = stringValue
}
public init(_ stringValue: String) {
self.stringValue = stringValue
}
public init(stringLiteral: String) {
self.stringValue = stringLiteral
}
public var intValue: Int? {
return nil
}
public init?(intValue: Int) {
return nil
}
}

View File

@ -16,7 +16,6 @@ import ChatInterfaceState
private var telegramUIDeclaredEncodables: Void = {
declareEncodable(InAppNotificationSettings.self, f: { InAppNotificationSettings(decoder: $0) })
declareEncodable(ChatInterfaceState.self, f: { ChatInterfaceState(decoder: $0) })
declareEncodable(ChatEmbeddedInterfaceState.self, f: { ChatEmbeddedInterfaceState(decoder: $0) })
declareEncodable(VideoLibraryMediaResource.self, f: { VideoLibraryMediaResource(decoder: $0) })
declareEncodable(LocalFileVideoMediaResource.self, f: { LocalFileVideoMediaResource(decoder: $0) })
declareEncodable(LocalFileGifMediaResource.self, f: { LocalFileGifMediaResource(decoder: $0) })