/
erhoof
/
telegraf
Обзор
Документация
Войти
/
erhoof
/
telegraf
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
src/tdlib/tdlibdataparsingutils.cpp
276 строк
9 KB
mbarashkov
Лёгкий рефакторинг tdlibreceiver
26 фев 2025, 14:59
26 фев 2025, 14:59
fc11873
Код
Авторство
О чём код?
#include "tdlibdataparsingutils.h" #include <QJsonObject> namespace { const char STICKERS[] = "stickers"; const char CHAT_ID[] = "chat_id"; const char CONTENT[] = "content"; const char TYPE_STICKER[] = "sticker"; const char OUTLINE[] = "outline"; const char _TYPE[] = "@type"; const char TYPE_ANIMATED_EMOJI[] = "animatedEmoji"; const char STICKER[] = "sticker"; const char COLOR_REPLACEMENTS[] = "color_replacements"; const char TYPE_MESSAGE[] = "message"; const char MESSAGE_ID[] = "message_id"; const char TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE[] = "inputMessageReplyToMessage"; const char TYPE_STICKER_SET[] = "stickerSet"; const char TYPE_MESSAGE_STICKER[] = "messageSticker"; const char TYPE_MESSAGE_ANIMATED_EMOJI[] = "messageAnimatedEmoji"; const char TYPE_DRAFT_MESSAGE[] = "draftMessage"; const char REPLY_TO[] = "reply_to"; const char REPLY_IN_CHAT_ID[] = "reply_in_chat_id"; const char REPLY_TO_MESSAGE_ID[] = "reply_to_message_id"; const char DRAFT_MESSAGE[] = "draft_message"; const char TYPE_MESSAGE_REPLY_TO_MESSAGE[] = "messageReplyToMessage"; const char ANIMATED_EMOJI[] = "animated_emoji"; const char COVERS[] = "covers"; const char TYPE_STICKER_SET_INFO[] = "stickerSetInfo"; } // Recursively removes (some) unused entries from QVariantMaps to reduce // memory usage. QStrings allocated by QVariantMaps are the top consumers // of memory. The biggest saving is achieved by removing "outline" from // stickers. const QJsonObject TDLibDataParsingUtils::cleanupMap(const QJsonObject &map, bool *updated) { const QString type(map.value(_TYPE).toString()); if (type == TYPE_STICKER) { QJsonObject sticker(map); if (sticker.contains(OUTLINE)) { sticker.remove(OUTLINE); sticker.remove(_TYPE); sticker.insert(_TYPE, TYPE_STICKER); // Replace with a shared value if (updated) *updated = true; return sticker; } } else if (type == TYPE_ANIMATED_EMOJI) { bool cleaned = false; const QJsonObject sticker(cleanupMap(map.value(STICKER).toObject(), &cleaned)); if (cleaned) { QJsonObject animatedEmoji(map); animatedEmoji.remove(STICKER); animatedEmoji.insert(STICKER, sticker); animatedEmoji.remove(COLOR_REPLACEMENTS); animatedEmoji.remove(_TYPE); animatedEmoji.insert(_TYPE, TYPE_ANIMATED_EMOJI); // Replace with a shared value if (updated) *updated = true; return animatedEmoji; } } else if (type == TYPE_MESSAGE) { QJsonObject message(map); bool messageChanged = false; const QJsonObject content(cleanupMap(map.value(CONTENT).toObject(), &messageChanged)); if (messageChanged) { message.remove(CONTENT); message.insert(CONTENT, content); } if (map.contains(REPLY_TO)) { // In TdLib 1.8.15 reply_to_message_id and reply_in_chat_id attributes // had been replaced with reply_to structure, e.g: // // "reply_to": { // "@type": "messageReplyToMessage", // "chat_id": -1001234567890, // "is_quote_manual": false, // "message_id": 234567890, // "origin_send_date": 0 // } // QJsonObject replyTo(message.value(REPLY_TO).toObject()); if (replyTo.value(_TYPE).toString() == TYPE_MESSAGE_REPLY_TO_MESSAGE) { if (replyTo.contains(MESSAGE_ID) && !message.contains(REPLY_TO_MESSAGE_ID)) { message.insert(REPLY_TO_MESSAGE_ID, replyTo.value(MESSAGE_ID)); } if (replyTo.contains(CHAT_ID) && !message.contains(REPLY_IN_CHAT_ID)) { message.insert(REPLY_IN_CHAT_ID, replyTo.value(CHAT_ID)); } replyTo.remove(_TYPE); replyTo.insert(_TYPE, TYPE_MESSAGE_REPLY_TO_MESSAGE); message.insert(REPLY_TO, replyTo); messageChanged = true; } } if (messageChanged) { message.remove(_TYPE); message.insert(_TYPE, TYPE_MESSAGE); // Replace with a shared value if (updated) *updated = true; return message; } } else if (type == TYPE_DRAFT_MESSAGE) { QJsonObject draftMessage(map); QJsonObject replyTo(draftMessage.value(REPLY_TO).toObject()); // In TdLib 1.8.21 reply_to_message_id has been replaced with reply_to if (replyTo.value(_TYPE).toString() == TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE) { if (replyTo.contains(MESSAGE_ID) && !draftMessage.contains(REPLY_TO_MESSAGE_ID)) { // reply_to_message_id is what QML (still) expects draftMessage.insert(REPLY_TO_MESSAGE_ID, replyTo.value(MESSAGE_ID)); } replyTo.remove(_TYPE); replyTo.insert(_TYPE, TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE); // Shared value draftMessage.insert(REPLY_TO, replyTo); draftMessage.remove(_TYPE); draftMessage.insert(_TYPE, DRAFT_MESSAGE); // Shared value if (updated) *updated = true; return draftMessage; } } else if (type == TYPE_MESSAGE_STICKER) { bool cleaned = false; const QJsonObject content(cleanupMap(map.value(CONTENT).toObject(), &cleaned)); if (cleaned) { QJsonObject messageSticker(map); messageSticker.remove(CONTENT); messageSticker.insert(CONTENT, content); messageSticker.remove(_TYPE); messageSticker.insert(_TYPE, TYPE_MESSAGE_STICKER); // Replace with a shared value if (updated) *updated = true; return messageSticker; } } else if (type == TYPE_MESSAGE_ANIMATED_EMOJI) { bool cleaned = false; const QJsonObject animated_emoji(cleanupMap(map.value(ANIMATED_EMOJI).toObject(), &cleaned)); if (cleaned) { QJsonObject messageAnimatedEmoji(map); messageAnimatedEmoji.remove(ANIMATED_EMOJI); messageAnimatedEmoji.insert(ANIMATED_EMOJI, animated_emoji); messageAnimatedEmoji.remove(_TYPE); messageAnimatedEmoji.insert(_TYPE, TYPE_MESSAGE_ANIMATED_EMOJI); // Replace with a shared value if (updated) *updated = true; return messageAnimatedEmoji; } } else if (type == TYPE_STICKER_SET_INFO) { bool cleaned = false; const QJsonArray covers(cleanupList(map.value(COVERS).toArray(), &cleaned)); if (cleaned) { QJsonObject stickerSetInfo(map); stickerSetInfo.remove(COVERS); stickerSetInfo.insert(COVERS, covers); stickerSetInfo.remove(_TYPE); stickerSetInfo.insert(_TYPE, TYPE_STICKER_SET_INFO); // Replace with a shared value if (updated) *updated = true; return stickerSetInfo; } } else if (type == TYPE_STICKER_SET) { bool cleaned = false; const QJsonArray stickers(cleanupList(map.value(STICKERS).toArray(), &cleaned)); if (cleaned) { QJsonObject stickerSet(map); stickerSet.remove(STICKERS); stickerSet.insert(STICKERS, stickers); stickerSet.remove(_TYPE); stickerSet.insert(_TYPE, TYPE_STICKER_SET); // Replace with a shared value if (updated) *updated = true; return stickerSet; } } if (updated) *updated = false; return map; } const QJsonArray TDLibDataParsingUtils::cleanupList(const QJsonArray &list, bool *updated) { QJsonArray newList(list); bool somethingChanged = false; const int n = list.count(); for (int i = 0; i < n; i++) { bool cleaned = false; const QJsonObject entry(cleanupMap(list[i].toObject(), &cleaned)); if (cleaned) { newList.replace(i, entry); somethingChanged = true; } } if (somethingChanged) { if (updated) *updated = true; return newList; } return list; }