mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
114 lines
3.7 KiB
Swift
114 lines
3.7 KiB
Swift
import Foundation
|
|
import MurMurHash32
|
|
|
|
extension _AdaptedPostboxEncoder {
|
|
final class KeyedContainer<Key> where Key: CodingKey {
|
|
var codingPath: [CodingKey]
|
|
var userInfo: [CodingUserInfoKey: Any]
|
|
let typeHash: Int32
|
|
|
|
let encoder: PostboxEncoder
|
|
|
|
init(codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any], typeHash: Int32) {
|
|
self.codingPath = codingPath
|
|
self.userInfo = userInfo
|
|
self.typeHash = typeHash
|
|
|
|
self.encoder = PostboxEncoder()
|
|
}
|
|
|
|
func makeData(addHeader: Bool, isDictionary: Bool) -> (Data, ValueType) {
|
|
let buffer = WriteBuffer()
|
|
|
|
if addHeader {
|
|
var typeHash: Int32 = self.typeHash
|
|
buffer.write(&typeHash, offset: 0, length: 4)
|
|
}
|
|
|
|
let data = self.encoder.makeData()
|
|
|
|
if addHeader {
|
|
var length: Int32 = Int32(data.count)
|
|
buffer.write(&length, offset: 0, length: 4)
|
|
}
|
|
|
|
buffer.write(data)
|
|
|
|
return (buffer.makeData(), .Object)
|
|
}
|
|
}
|
|
}
|
|
|
|
extension _AdaptedPostboxEncoder.KeyedContainer: KeyedEncodingContainerProtocol {
|
|
func encode<T>(_ value: T, forKey key: Key) throws where T : Encodable {
|
|
if let value = value as? Data {
|
|
self.encoder.encodeData(value, forKey: key.stringValue)
|
|
} else if let value = value as? AdaptedPostboxEncoder.RawObjectData {
|
|
self.encoder.encodeInnerObjectDataWithHeader(typeHash: value.typeHash, data: value.data, valueType: .Object, forKey: key.stringValue)
|
|
} else {
|
|
let typeHash: Int32 = murMurHashString32("\(type(of: value))")
|
|
let innerEncoder = _AdaptedPostboxEncoder(typeHash: typeHash)
|
|
try! value.encode(to: innerEncoder)
|
|
|
|
let typeOfValue = type(of: value)
|
|
let typeString = "\(typeOfValue)"
|
|
var isDictionary = false
|
|
if typeString.hasPrefix("Dictionary<") {
|
|
isDictionary = true
|
|
}
|
|
|
|
let (data, valueType) = innerEncoder.makeData(addHeader: true, isDictionary: isDictionary)
|
|
|
|
self.encoder.encodeInnerObjectData(data, valueType: valueType, 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: Int, forKey key: Key) throws {
|
|
assertionFailure()
|
|
|
|
self.encoder.encodeInt32(Int32(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 {}
|