// // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once #include "td/actor/actor.h" #include "td/actor/PromiseFuture.h" #include "td/telegram/ChannelId.h" #include "td/telegram/ChatId.h" #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileSourceId.h" #include "td/telegram/MessageId.h" #include "td/telegram/SetWithPosition.h" #include "td/telegram/UserId.h" #include "td/utils/logging.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/Variant.h" #include <unordered_map> namespace td { class Td; extern int VERBOSITY_NAME(file_references); class FileReferenceManager : public Actor { public: static bool is_file_reference_error(const Status &error); static size_t get_file_reference_error_pos(const Status &error); FileSourceId create_message_file_source(FullMessageId full_message_id); FileSourceId create_user_photo_file_source(UserId user_id, int64 photo_id); FileSourceId create_chat_photo_file_source(ChatId chat_id); FileSourceId create_channel_photo_file_source(ChannelId channel_id); FileSourceId create_wallpapers_file_source(); FileSourceId create_web_page_file_source(string url); FileSourceId create_saved_animations_file_source(); FileSourceId create_recent_stickers_file_source(bool is_attached); FileSourceId create_favorite_stickers_file_source(); using NodeId = FileId; void repair_file_reference(NodeId node_id, Promise<> promise); bool add_file_source(NodeId node_id, FileSourceId file_source_id); std::vector<FileSourceId> get_some_file_sources(NodeId node_id); bool remove_file_source(NodeId node_id, FileSourceId file_source_id); void merge(NodeId to_node_id, NodeId from_node_id); template <class StorerT> void store_file_source(FileSourceId file_source_id, StorerT &storer) const; template <class ParserT> FileSourceId parse_file_source(Td *td, ParserT &parser); private: struct Destination { bool empty() const { return node_id.empty(); } NodeId node_id; int64 generation; }; struct Query { std::vector<Promise<>> promises; int32 active_queries{0}; Destination proxy; int64 generation; }; struct Node { SetWithPosition<FileSourceId> file_source_ids; unique_ptr<Query> query; }; struct FileSourceMessage { FullMessageId full_message_id; }; struct FileSourceUserPhoto { int64 photo_id; UserId user_id; }; struct FileSourceChatPhoto { ChatId chat_id; }; struct FileSourceChannelPhoto { ChannelId channel_id; }; struct FileSourceWallpapers { // empty }; struct FileSourceWebPage { string url; }; struct FileSourceSavedAnimations { // empty }; struct FileSourceRecentStickers { bool is_attached; }; struct FileSourceFavoriteStickers {}; // append only using FileSource = Variant<FileSourceMessage, FileSourceUserPhoto, FileSourceChatPhoto, FileSourceChannelPhoto, FileSourceWallpapers, FileSourceWebPage, FileSourceSavedAnimations, FileSourceRecentStickers, FileSourceFavoriteStickers>; vector<FileSource> file_sources_; int64 query_generation_{0}; std::unordered_map<NodeId, Node, FileIdHash> nodes_; void run_node(NodeId node); void send_query(Destination dest, FileSourceId file_source_id); Destination on_query_result(Destination dest, FileSourceId file_source_id, Status status, int32 sub = 0); template <class T> FileSourceId add_file_source_id(T source, Slice source_str); FileSourceId get_current_file_source_id() const; }; } // namespace td