1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
public static func parse(_ buffer: Buffer) -> Any? {
let reader = BufferReader(buffer)
if let signature = reader.readInt32() {
return parse(reader, signature: signature)
}
return nil
}
public static func parse(_ reader: BufferReader, signature: Int32) -> Any? {
if let parser = parsers[signature] {
return parser(reader)
}
else {
telegramApiLog("Type constructor \(String(signature, radix: 16, uppercase: false)) not found")
return nil
}
}
// parse vector
public static func parseVector<T>(_ reader: BufferReader, elementSignature: Int32, elementType: T.Type) -> [T]? {
if let count = reader.readInt32() {
var array = [T]()
var i: Int32 = 0
while i < count {
var signature = elementSignature
if elementSignature == 0 {
if let unboxedSignature = reader.readInt32() {
signature = unboxedSignature
}
else {
return nil
}
}
if elementType == Buffer.self {
if let item = parseBytes(reader) as? T {
array.append(item)
} else {
return nil
}
} else {
if let item = Api.parse(reader, signature: signature) as? T {
array.append(item)
}
else {
return nil
}
}
i += 1
}
return array
}
return nil
}
// parse bytes
public func parseBytes(_ reader: BufferReader) -> Buffer? {
if let tmp = reader.readBytesAsInt32(1) {
var paddingBytes: Int = 0
var length: Int = 0
if tmp == 254 {
if let len = reader.readBytesAsInt32(3) {
length = Int(len)
paddingBytes = roundUp(length, multiple: 4) - length
}
else {
return nil
}
}
else {
length = Int(tmp)
paddingBytes = roundUp(length + 1, multiple: 4) - (length + 1)
}
let buffer = reader.readBuffer(length)
reader.skip(paddingBytes)
return buffer
}
return nil
}
// parse string
func parseString(_ reader: BufferReader) -> String? {
if let buffer = parseBytes(reader) {
return (NSString(data: buffer.makeData() as Data, encoding: String.Encoding.utf8.rawValue) as? String) ?? ""
}
return nil
}
// serialize int32
func serializeInt32(_ value: Int32, buffer: Buffer, boxed: Bool) {
if boxed {
buffer.appendInt32(-1471112230)
}
buffer.appendInt32(value)
}
// serialize int64
func serializeInt64(_ value: Int64, buffer: Buffer, boxed: Bool) {
if boxed {
buffer.appendInt32(570911930)
}
buffer.appendInt64(value)
}
// serialize double
func serializeDouble(_ value: Double, buffer: Buffer, boxed: Bool) {
if boxed {
buffer.appendInt32(571523412)
}
buffer.appendDouble(value)
}
// serialize string
func serializeString(_ value: String, buffer: Buffer, boxed: Bool) {
let stringBuffer = Buffer()
let data = value.data(using: .utf8, allowLossyConversion: true) ?? Data()
data.withUnsafeBytes { bytes in
stringBuffer.appendBytes(bytes, length: UInt(data.count))
}
serializeBytes(stringBuffer, buffer: buffer, boxed: boxed)
}
telegram - api parser
This post is licensed under
CC BY 4.0
by the author.