Home telegram - api parser
Post
Cancel

telegram - api parser

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)
}
This post is licensed under CC BY 4.0 by the author.