| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- /*
- This file is part of Telegram Desktop,
- the official desktop application for the Telegram messaging service.
- For license and copyright information please follow this link:
- https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
- */
- #include "mtproto/details/mtproto_dump_to_text.h"
- #include "scheme-dump_to_text.h"
- #include "scheme.h"
- #include <zlib.h>
- namespace MTP::details {
- bool DumpToTextCore(DumpToTextBuffer &to, const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons, uint32 level, mtpPrime vcons) {
- switch (mtpTypeId(cons)) {
- case mtpc_int: {
- MTPint value;
- if (value.read(from, end, cons)) {
- to.add(QString::number(value.v)).add(" [INT]");
- return true;
- }
- } break;
- case mtpc_long: {
- MTPlong value;
- if (value.read(from, end, cons)) {
- to.add(QString::number(value.v)).add(" [LONG]");
- return true;
- }
- } break;
- case mtpc_int128: {
- MTPint128 value;
- if (value.read(from, end, cons)) {
- to.add(QString::number(value.h)).add(" * 2^64 + ").add(QString::number(value.l)).add(" [INT128]");
- return true;
- }
- } break;
- case mtpc_int256: {
- MTPint256 value;
- if (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]");
- return true;
- }
- } break;
- case mtpc_double: {
- MTPdouble value;
- if (value.read(from, end, cons)) {
- to.add(QString::number(value.v)).add(" [DOUBLE]");
- return true;
- }
- } break;
- case mtpc_string: {
- MTPstring value;
- if (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]");
- }
- return true;
- }
- } break;
- case mtpc_vector: {
- if (from < end) {
- int32 cnt = *(from++);
- to.add("[ vector<0x").add(QString::number(vcons, 16)).add("> (").add(QString::number(cnt)).add(")");
- if (cnt) {
- to.add("\n").addSpaces(level);
- for (int32 i = 0; i < cnt; ++i) {
- to.add(" ");
- if (!DumpToTextType(to, from, end, vcons, level + 1)) {
- return false;
- }
- to.add(",\n").addSpaces(level);
- }
- } else {
- to.add(" ");
- }
- to.add("]");
- return true;
- }
- } break;
- case mtpc_gzip_packed: {
- MTPstring packed;
- // read packed string as serialized mtp string type
- if (!packed.read(from, end)) {
- return false;
- }
- 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) {
- return false;
- }
- 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);
- return false;
- }
- }
- if (stream.avail_out & 0x03) {
- return false;
- }
- result.resize(result.size() - (stream.avail_out >> 2));
- inflateEnd(&stream);
- if (result.empty()) {
- return false;
- }
- const mtpPrime *newFrom = result.constData(), *newEnd = result.constData() + result.size();
- to.add("[GZIPPED] ");
- return DumpToTextType(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("] ");
- return DumpToTextType(to, from, end, 0, level);
- }
- }
- if (cons == mtpc_invokeWithLayer) {
- if (from >= end) {
- return false;
- }
- int32 layer = *(from++);
- to.add("[LAYER").add(QString::number(layer)).add("] ");
- return DumpToTextType(to, from, end, 0, level);
- }
- } break;
- }
- return false;
- }
- QString DumpToText(const mtpPrime *&from, const mtpPrime *end) {
- DumpToTextBuffer to;
- [[maybe_unused]] bool result = DumpToTextType(to, from, end, mtpc_core_message);
- return QString::fromUtf8(to.p, to.size);
- }
- } // namespace MTP::details
|