Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2124|回复: 1
打印 上一主题 下一主题

网络数据加载逻辑

[复制链接]

1265

主题

2054

帖子

7897

积分

认证用户组

Rank: 5Rank: 5

积分
7897
跳转到指定楼层
楼主
发表于 2020-3-18 18:25:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
\Telegram\Resources\scheme.tl
userGroupList#3b9aca0e tag_users:Vector<UserGroup> = UserGroupList;

\out\Debug\gen\scheme.h
mtpc_userGroupList = 0x3b9aca0e,


out\Debug\gen\scheme.cpp
result.insert(mtpc_userGroupList, Serialize_userGroupList);

void Serialize_userGroupList(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, uint32 iflag) {
        if (stage) {
                to.add(",\n").addSpaces(lev);
        } else {
                to.add("{ userGroupList");
                to.add("\n").addSpaces(lev);
        }
        switch (stage) {
        case 0: to.add("  tag_users: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
        default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
        }
}



void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons) {
        static auto serializers = createTextSerializers();

        QVector<mtpTypeId> types, vtypes;
        QVector<int32> stages, flags;
        types.reserve(20); vtypes.reserve(20); stages.reserve(20); flags.reserve(20);
        types.push_back(mtpTypeId(cons)); vtypes.push_back(mtpTypeId(vcons)); stages.push_back(0); flags.push_back(0);

        mtpTypeId type = cons, vtype = vcons;
        int32 stage = 0, flag = 0;

        while (!types.isEmpty()) {
                type = types.back();
                vtype = vtypes.back();
                stage = stages.back();
                flag = flags.back();
                if (!type) {
                        if (from >= end) {
                                throw Exception("from >= end");
                        } else if (stage) {
                                throw Exception("unknown type on stage > 0");
                        }
                        types.back() = type = *from;
                        ++from;
                }

                int32 lev = level + types.size() - 1;
                auto it = serializers.constFind(type);
                if (it != serializers.cend()) {
                        (*it.value())(to, stage, lev, types, vtypes, stages, flags, from, end, flag);
                } else {
                        mtpTextSerializeCore(to, from, end, type, lev, vtype);
                        types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
                }
        }
}


void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons) {
        static auto serializers = createTextSerializers();

        QVector<mtpTypeId> types, vtypes;
        QVector<int32> stages, flags;
        types.reserve(20); vtypes.reserve(20); stages.reserve(20); flags.reserve(20);
        types.push_back(mtpTypeId(cons)); vtypes.push_back(mtpTypeId(vcons)); stages.push_back(0); flags.push_back(0);

        mtpTypeId type = cons, vtype = vcons;
        int32 stage = 0, flag = 0;

        while (!types.isEmpty()) {
                type = types.back();
                vtype = vtypes.back();
                stage = stages.back();
                flag = flags.back();
                if (!type) {
                        if (from >= end) {
                                throw Exception("from >= end");
                        } else if (stage) {
                                throw Exception("unknown type on stage > 0");
                        }
                        types.back() = type = *from;
                        ++from;
                }

                int32 lev = level + types.size() - 1;
                auto it = serializers.constFind(type);
                if (it != serializers.cend()) {
                        (*it.value())(to, stage, lev, types, vtypes, stages, flags, from, end, flag);
                } else {
                        mtpTextSerializeCore(to, from, end, type, lev, vtype);
                        types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
                }
        }
}


\Telegram\SourceFiles\mtproto\core_types.h

void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons = 0, uint32 level = 0, mtpPrime vcons = 0);

void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons, uint32 level, mtpPrime vcons = 0);

inline QString mtpTextSerialize(const mtpPrime *&from, const mtpPrime *end) {
        MTPStringLogger to;
        try {
                mtpTextSerializeType(to, from, end, mtpc_core_message);
        } catch (Exception &e) {
                to.add("[ERROR] (").add(e.what()).add(")");
        }
        return QString::fromUtf8(to.p, to.size);
}



\Telegram\SourceFiles\mtproto\core_types.cpp

void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons, uint32 level, mtpPrime vcons) {
        switch (mtpTypeId(cons)) {
        case mtpc_int: {
                MTPint value;
                value.read(from, end, cons);
                to.add(QString::number(value.v)).add(" [INT]");
        } break;

        case mtpc_long: {
                MTPlong value;
                value.read(from, end, cons);
                to.add(QString::number(value.v)).add(" [LONG]");
        } break;

        case mtpc_int128: {
                MTPint128 value;
                value.read(from, end, cons);
                to.add(QString::number(value.h)).add(" * 2^64 + ").add(QString::number(value.l)).add(" [INT128]");
        } break;

        case mtpc_int256: {
                MTPint256 value;
                value.read(from, end, cons);
                to.add(QString::number(value.h.h)).add(" * 2^192 + ").add(QString::number(value.h.l)).add(" * 2^128 + ").add(QString::number(value.l.h)).add(" * 2 ^ 64 + ").add(QString::number(value.l.l)).add(" [INT256]");
        } break;

        case mtpc_double: {
                MTPdouble value;
                value.read(from, end, cons);
                to.add(QString::number(value.v)).add(" [DOUBLE]");
        } break;

        case mtpc_string: {
                MTPstring value;
                value.read(from, end, cons);
                auto strUtf8 = value.v;
                auto str = QString::fromUtf8(strUtf8);
                if (str.toUtf8() == strUtf8) {
                        to.add("\"").add(str.replace('\\', "\\\\").replace('"', "\\\"").replace('\n', "\\n")).add("\" [STRING]");
                } else if (strUtf8.size() < 64) {
                        to.add(Logs::mb(strUtf8.constData(), strUtf8.size()).str()).add(" [").add(QString::number(strUtf8.size())).add(" BYTES]");
                } else {
                        to.add(Logs::mb(strUtf8.constData(), 16).str()).add("... [").add(QString::number(strUtf8.size())).add(" BYTES]");
                }
        } break;

        case mtpc_vector: {
                if (from >= end) {
                        throw Exception("from >= end in vector");
                }
                int32 cnt = *(from++);
                to.add("[ vector<0x").add(QString::number(vcons, 16)).add(">");
                if (cnt) {
                        to.add("\n").addSpaces(level);
                        for (int32 i = 0; i < cnt; ++i) {
                                to.add("  ");
                                mtpTextSerializeType(to, from, end, vcons, level + 1);
                                to.add(",\n").addSpaces(level);
                        }
                } else {
                        to.add(" ");
                }
                to.add("]");
        } break;

        case mtpc_gzip_packed: {
                MTPstring packed;
                packed.read(from, end); // read packed string as serialized mtp string type
                uint32 packedLen = packed.v.size(), unpackedChunk = packedLen;
                mtpBuffer result; // * 4 because of mtpPrime type
                result.resize(0);

                z_stream stream;
                stream.zalloc = nullptr;
                stream.zfree = nullptr;
                stream.opaque = nullptr;
                stream.avail_in = 0;
                stream.next_in = nullptr;
                int res = inflateInit2(&stream, 16 + MAX_WBITS);
                if (res != Z_OK) {
                        throw Exception(QString("ungzip init, code: %1").arg(res));
                }
                stream.avail_in = packedLen;
                stream.next_in = reinterpret_cast<Bytef*>(packed.v.data());
                stream.avail_out = 0;
                while (!stream.avail_out) {
                        result.resize(result.size() + unpackedChunk);
                        stream.avail_out = unpackedChunk * sizeof(mtpPrime);
                        stream.next_out = (Bytef*)&result[result.size() - unpackedChunk];
                        int res = inflate(&stream, Z_NO_FLUSH);
                        if (res != Z_OK && res != Z_STREAM_END) {
                                inflateEnd(&stream);
                                throw Exception(QString("ungzip unpack, code: %1").arg(res));
                        }
                }
                if (stream.avail_out & 0x03) {
                        uint32 badSize = result.size() * sizeof(mtpPrime) - stream.avail_out;
                        throw Exception(QString("ungzip bad length, size: %1").arg(badSize));
                }
                result.resize(result.size() - (stream.avail_out >> 2));
                inflateEnd(&stream);

                if (result.empty()) {
                        throw Exception("ungzip void data");
                }
                const mtpPrime *newFrom = result.constData(), *newEnd = result.constData() + result.size();
                to.add("[GZIPPED] "); mtpTextSerializeType(to, newFrom, newEnd, 0, level);
        } break;

        default: {
                for (uint32 i = 1; i < mtpLayerMaxSingle; ++i) {
                        if (cons == mtpLayers[i]) {
                                to.add("[LAYER").add(QString::number(i + 1)).add("] "); mtpTextSerializeType(to, from, end, 0, level);
                                return;
                        }
                }
                if (cons == mtpc_invokeWithLayer) {
                        if (from >= end) {
                                throw Exception("from >= end in invokeWithLayer");
                        }
                        int32 layer = *(from++);
                        to.add("[LAYER").add(QString::number(layer)).add("] "); mtpTextSerializeType(to, from, end, 0, level);
                        return;
                }
                throw Exception(QString("unknown cons 0x%1").arg(cons, 0, 16));
        } break;
        }


\Telegram\SourceFiles\mtproto\connection.cpp
void ConnectionPrivate::handleReceived() {
MTP_LOG(_shiftedDcId, ("Recv: ") + mtpTextSerialize(sfrom, end));}
bool ConnectionPrivate::sendSecureRequest(..){
MTP_LOG(_shiftedDcId, ("Send: ") + mtpTextSerialize(from, from + messageSize));}

//把数据写入缓存供主线程调用
ConnectionPrivate::HandleResult ConnectionPrivate::handleOneReceived(const mtpPrime *from..){
sessionData->haveReceivedResponses().insert(requestId, response);}


回复

使用道具 举报

1265

主题

2054

帖子

7897

积分

认证用户组

Rank: 5Rank: 5

积分
7897
沙发
 楼主| 发表于 2020-3-23 18:38:00 | 只看该作者
上面是有明确的发送和接收处理函数,而对于只接收的信号,又该如何设置呢!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-11-1 08:00 , Processed in 0.057360 second(s), 19 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表