diff --git a/td/telegram/StoryContent.cpp b/td/telegram/StoryContent.cpp index 8ecf79f0a..3550605c3 100644 --- a/td/telegram/StoryContent.cpp +++ b/td/telegram/StoryContent.cpp @@ -13,6 +13,7 @@ #include "td/telegram/files/FileManager.h" #include "td/telegram/files/FileType.h" #include "td/telegram/Photo.h" +#include "td/telegram/Photo.hpp" #include "td/telegram/PhotoSize.h" #include "td/telegram/StickersManager.h" #include "td/telegram/Td.h" @@ -67,6 +68,109 @@ class StoryContentUnsupported final : public StoryContent { } }; +template +static void store(const StoryContent *content, StorerT &storer) { + CHECK(content != nullptr); + + Td *td = storer.context()->td().get_actor_unsafe(); + CHECK(td != nullptr); + + auto content_type = content->get_type(); + store(content_type, storer); + + switch (content_type) { + case StoryContentType::Photo: { + const auto *story_content = static_cast(content); + BEGIN_STORE_FLAGS(); + END_STORE_FLAGS(); + store(story_content->photo_, storer); + break; + } + case StoryContentType::Video: { + const auto *story_content = static_cast(content); + bool has_alt_file_id = story_content->alt_file_id_.is_valid(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_alt_file_id); + END_STORE_FLAGS(); + td->videos_manager_->store_video(story_content->file_id_, storer); + if (has_alt_file_id) { + td->videos_manager_->store_video(story_content->alt_file_id_, storer); + } + break; + } + case StoryContentType::Unsupported: { + const auto *story_content = static_cast(content); + store(story_content->version_, storer); + break; + } + default: + UNREACHABLE(); + } +} + +template +static void parse(unique_ptr &content, ParserT &parser) { + Td *td = parser.context()->td().get_actor_unsafe(); + CHECK(td != nullptr); + + StoryContentType content_type; + parse(content_type, parser); + + bool is_bad = false; + switch (content_type) { + case StoryContentType::Photo: { + auto story_content = make_unique(); + BEGIN_PARSE_FLAGS(); + END_PARSE_FLAGS(); + parse(story_content->photo_, parser); + is_bad |= story_content->photo_.is_bad(); + content = std::move(story_content); + break; + } + case StoryContentType::Video: { + auto story_content = make_unique(); + bool has_alt_file_id; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_alt_file_id); + END_PARSE_FLAGS(); + story_content->file_id_ = td->videos_manager_->parse_video(parser); + if (has_alt_file_id) { + story_content->alt_file_id_ = td->videos_manager_->parse_video(parser); + if (!story_content->alt_file_id_.is_valid()) { + LOG(ERROR) << "Failed to parse alternative video"; + } + } + content = std::move(story_content); + break; + } + case StoryContentType::Unsupported: { + auto story_content = make_unique(); + parse(story_content->version_, parser); + content = std::move(story_content); + break; + } + default: + LOG(ERROR) << "Have unknown story content type " << static_cast(content_type); + is_bad = true; + } + if (is_bad) { + LOG(ERROR) << "Load a story with an invalid content of type " << content_type; + content = make_unique(0); + } +} + +void store_story_content(const StoryContent *content, LogEventStorerCalcLength &storer) { + store(content, storer); +} + +void store_story_content(const StoryContent *content, LogEventStorerUnsafe &storer) { + store(content, storer); +} + +void parse_story_content(unique_ptr &content, LogEventParser &parser) { + parse(content, parser); +} + unique_ptr get_story_content(Td *td, tl_object_ptr &&media_ptr, DialogId owner_dialog_id) { CHECK(media_ptr != nullptr); diff --git a/td/telegram/StoryContent.h b/td/telegram/StoryContent.h index 1f982dcc4..840b6b409 100644 --- a/td/telegram/StoryContent.h +++ b/td/telegram/StoryContent.h @@ -8,6 +8,7 @@ #include "td/telegram/DialogId.h" #include "td/telegram/files/FileId.h" +#include "td/telegram/logevent/LogEvent.h" #include "td/telegram/StoryContentType.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" @@ -31,6 +32,12 @@ class StoryContent { virtual ~StoryContent() = default; }; +void store_story_content(const StoryContent *content, LogEventStorerCalcLength &storer); + +void store_story_content(const StoryContent *content, LogEventStorerUnsafe &storer); + +void parse_story_content(unique_ptr &content, LogEventParser &parser); + unique_ptr get_story_content(Td *td, telegram_api::object_ptr &&media_ptr, DialogId owner_dialog_id);