mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
101 lines
2.8 KiB
Swift
101 lines
2.8 KiB
Swift
import Foundation
|
|
import MurMurHash32
|
|
|
|
public class AdaptedPostboxEncoder {
|
|
public final class RawObjectData: Encodable {
|
|
public let typeHash: Int32
|
|
public let data: Data
|
|
|
|
public init(typeHash: Int32, data: Data) {
|
|
self.typeHash = typeHash
|
|
self.data = data
|
|
}
|
|
|
|
public func encode(to encoder: Encoder) throws {
|
|
preconditionFailure()
|
|
}
|
|
}
|
|
|
|
public init() {
|
|
}
|
|
|
|
public func encode(_ value: Encodable) throws -> Data {
|
|
let typeHash: Int32 = murMurHashString32("\(type(of: value))")
|
|
|
|
let encoder = _AdaptedPostboxEncoder(typeHash: typeHash)
|
|
try value.encode(to: encoder)
|
|
return encoder.makeData(addHeader: false, isDictionary: false).0
|
|
}
|
|
}
|
|
|
|
final class _AdaptedPostboxEncoder {
|
|
var codingPath: [CodingKey] = []
|
|
|
|
var userInfo: [CodingUserInfoKey : Any] = [:]
|
|
|
|
let typeHash: Int32
|
|
|
|
fileprivate var container: AdaptedPostboxEncodingContainer?
|
|
|
|
init(typeHash: Int32) {
|
|
self.typeHash = typeHash
|
|
}
|
|
|
|
func makeData(addHeader: Bool, isDictionary: Bool) -> (Data, ValueType) {
|
|
if let container = self.container {
|
|
return container.makeData(addHeader: addHeader, isDictionary: isDictionary)
|
|
} else {
|
|
let buffer = WriteBuffer()
|
|
|
|
if addHeader {
|
|
var typeHash: Int32 = self.typeHash
|
|
buffer.write(&typeHash, offset: 0, length: 4)
|
|
}
|
|
|
|
let innerEncoder = PostboxEncoder()
|
|
let data = innerEncoder.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: 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, typeHash: self.typeHash)
|
|
self.container = container
|
|
|
|
return KeyedEncodingContainer(container)
|
|
}
|
|
|
|
func unkeyedContainer() -> UnkeyedEncodingContainer {
|
|
assertCanCreateContainer()
|
|
|
|
let container = UnkeyedContainer(codingPath: self.codingPath, userInfo: self.userInfo)
|
|
self.container = container
|
|
|
|
return container
|
|
}
|
|
|
|
func singleValueContainer() -> SingleValueEncodingContainer {
|
|
preconditionFailure()
|
|
}
|
|
}
|
|
|
|
protocol AdaptedPostboxEncodingContainer: AnyObject {
|
|
func makeData(addHeader: Bool, isDictionary: Bool) -> (Data, ValueType)
|
|
}
|