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.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 {
@ -198,7 +186,7 @@ public enum ChatTextInputStateTextAttributeType: Codable, Equatable {
public init(from decoder: Decoder) throws {
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:
self = .bold
case 1:
@ -234,41 +222,6 @@ public enum ChatTextInputStateTextAttributeType: Codable, Equatable {
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 {
@ -283,8 +236,8 @@ public struct ChatTextInputStateTextAttribute: Codable, Equatable {
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
let rangeFrom = (try? container.decode(Int32.self, forKey: "range0")) ?? 0
let rangeTo = (try? container.decode(Int32.self, forKey: "range1")) ?? 0
self.range = Int(rangeFrom) ..< Int(rangeTo)
}
@ -298,17 +251,6 @@ public struct ChatTextInputStateTextAttribute: Codable, Equatable {
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 {
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")
}
/*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 {
return lhs.text == rhs.text && lhs.attributes == rhs.attributes
}
@ -419,7 +351,7 @@ public final class ChatEmbeddedInterfaceState: PeerChatListEmbeddedInterfaceStat
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()
self.text = ((try? container.decode(ChatTextInputStateText.self, forKey: "at")) ?? ChatTextInputStateText()).attributedText()
}
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")
}
/*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 {
if let to = to as? ChatEmbeddedInterfaceState {
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)
}
public func encodeInnerObjectData(_ value: Data, forKey key: String) {
func encodeInnerObjectData(_ value: Data, valueType: ValueType, forKey key: String) {
self.encodeKey(key)
var t: Int8 = ValueType.Object.rawValue
var t: Int8 = valueType.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)
}
@ -1008,7 +1004,7 @@ public final class PostboxDecoder {
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()
let data = ReadBuffer(memory: UnsafeMutableRawPointer(mutating: self.buffer.memory.advanced(by: initialOffset)), length: self.offset - initialOffset, freeWhenDone: false).makeData()
return (data, actualValueType)
}
@ -1179,7 +1175,16 @@ public final class PostboxDecoder {
return array
} 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 {
var allKeys: [Key] {
preconditionFailure()
@ -32,9 +38,11 @@ extension _AdaptedPostboxDecoder.KeyedContainer: KeyedDecodingContainerProtocol
if let mappedType = AdaptedPostboxDecoder.ContentType(valueType: valueType) {
return try AdaptedPostboxDecoder().decode(T.self, from: data, contentType: mappedType)
} else {
decodingErrorBreakpoint()
throw DecodingError.typeMismatch(T.self, DecodingError.Context(codingPath: self.codingPath + [key], debugDescription: ""))
}
} else {
decodingErrorBreakpoint()
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) {
return value
} else {
decodingErrorBreakpoint()
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) {
return value
} else {
decodingErrorBreakpoint()
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) {
return value
} else {
decodingErrorBreakpoint()
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) {
return value
} else {
decodingErrorBreakpoint()
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 {
let encoder = _AdaptedPostboxEncoder()
try value.encode(to: encoder)
return encoder.data
return encoder.makeData().0
}
}
@ -15,7 +15,7 @@ final class _AdaptedPostboxEncoder {
fileprivate var container: AdaptedPostboxEncodingContainer?
var data: Data {
func makeData() -> (Data, ValueType) {
return self.container!.makeData()
}
}
@ -35,7 +35,12 @@ extension _AdaptedPostboxEncoder: Encoder {
}
func unkeyedContainer() -> UnkeyedEncodingContainer {
preconditionFailure()
assertCanCreateContainer()
let container = UnkeyedContainer(codingPath: self.codingPath, userInfo: self.userInfo)
self.container = container
return container
}
func singleValueContainer() -> SingleValueEncodingContainer {
@ -44,5 +49,5 @@ extension _AdaptedPostboxEncoder: Encoder {
}
protocol AdaptedPostboxEncodingContainer: AnyObject {
func makeData() -> Data
func makeData() -> (Data, ValueType)
}

View File

@ -14,8 +14,19 @@ extension _AdaptedPostboxEncoder {
self.encoder = PostboxEncoder()
}
func makeData() -> Data {
return self.encoder.makeData()
func makeData() -> (Data, ValueType) {
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()
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 {

View File

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

View File

@ -1,17 +1,102 @@
import Foundation
import MurMurHash32
extension _AdaptedPostboxEncoder {
final class UnkeyedContainer {
var codingPath: [CodingKey]
var userInfo: [CodingUserInfoKey: Any]
fileprivate enum Item {
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 {
preconditionFailure()
return self.items.count
}
init(codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) {
self.codingPath = codingPath
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 {
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 {