mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
153 lines
4.4 KiB
Swift
153 lines
4.4 KiB
Swift
import Foundation
|
|
|
|
final public class AdaptedPostboxDecoder {
|
|
enum ContentType {
|
|
case object
|
|
case int32Array
|
|
case int64Array
|
|
case objectArray
|
|
case stringArray
|
|
case dataArray
|
|
case objectDict
|
|
}
|
|
|
|
public final class RawObjectData: Decodable {
|
|
public let data: Data
|
|
public let typeHash: Int32
|
|
|
|
public init(data: Data, typeHash: Int32) {
|
|
self.data = data
|
|
self.typeHash = typeHash
|
|
}
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
preconditionFailure()
|
|
}
|
|
}
|
|
|
|
public init() {
|
|
}
|
|
|
|
public func decode<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable {
|
|
return try self.decode(type, from: data, contentType: .object)
|
|
}
|
|
|
|
func decode<T>(_ type: T.Type, from data: Data, contentType: ContentType) throws -> T where T : Decodable {
|
|
if type == AdaptedPostboxDecoder.RawObjectData.self {
|
|
if case .object = contentType {
|
|
return AdaptedPostboxDecoder.RawObjectData(data: data, typeHash: 0) as! T
|
|
} else {
|
|
preconditionFailure()
|
|
}
|
|
}
|
|
let decoder = _AdaptedPostboxDecoder(data: data, contentType: contentType)
|
|
return try T(from: decoder)
|
|
}
|
|
}
|
|
|
|
extension AdaptedPostboxDecoder.ContentType {
|
|
init?(valueType: ObjectDataValueType) {
|
|
switch valueType {
|
|
case .Int32:
|
|
return nil
|
|
case .Int64:
|
|
return nil
|
|
case .Bool:
|
|
return nil
|
|
case .Double:
|
|
return nil
|
|
case .String:
|
|
return nil
|
|
case .Object:
|
|
self = .object
|
|
case .Int32Array:
|
|
self = .int32Array
|
|
case .Int64Array:
|
|
self = .int64Array
|
|
case .ObjectArray:
|
|
self = .objectArray
|
|
case .ObjectDictionary:
|
|
self = .objectDict
|
|
case .Bytes:
|
|
return nil
|
|
case .Nil:
|
|
return nil
|
|
case .StringArray:
|
|
self = .stringArray
|
|
case .BytesArray:
|
|
self = .dataArray
|
|
}
|
|
}
|
|
}
|
|
|
|
final class _AdaptedPostboxDecoder {
|
|
var codingPath: [CodingKey] = []
|
|
|
|
var userInfo: [CodingUserInfoKey : Any] = [:]
|
|
|
|
var container: AdaptedPostboxDecodingContainer?
|
|
|
|
fileprivate let data: Data
|
|
fileprivate let contentType: AdaptedPostboxDecoder.ContentType
|
|
|
|
init(data: Data, contentType: AdaptedPostboxDecoder.ContentType) {
|
|
self.data = data
|
|
self.contentType = contentType
|
|
}
|
|
}
|
|
|
|
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 {
|
|
assertCanCreateContainer()
|
|
|
|
let decoder = PostboxDecoder(buffer: MemoryBuffer(data: self.data))
|
|
|
|
var content: UnkeyedContainer.Content?
|
|
switch self.contentType {
|
|
case .object:
|
|
preconditionFailure()
|
|
case .int32Array:
|
|
content = .int32Array(decoder.decodeInt32ArrayRaw())
|
|
case .int64Array:
|
|
content = .int64Array(decoder.decodeInt64ArrayRaw())
|
|
case .objectArray:
|
|
content = .objectArray(decoder.decodeObjectDataArrayRaw())
|
|
case .stringArray:
|
|
content = .stringArray(decoder.decodeStringArrayRaw())
|
|
case .dataArray:
|
|
content = .dataArray(decoder.decodeBytesArrayRaw().map { $0.makeData() })
|
|
case .objectDict:
|
|
content = .objectDict(decoder.decodeObjectDataDictRaw())
|
|
}
|
|
|
|
if let content = content {
|
|
let container = UnkeyedContainer(data: self.data, codingPath: self.codingPath, userInfo: self.userInfo, content: content)
|
|
self.container = container
|
|
|
|
return container
|
|
} else {
|
|
preconditionFailure()
|
|
}
|
|
}
|
|
|
|
func singleValueContainer() -> SingleValueDecodingContainer {
|
|
preconditionFailure()
|
|
}
|
|
}
|
|
|
|
protocol AdaptedPostboxDecodingContainer: AnyObject {
|
|
}
|