// // 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/telegram/files/FileLocation.h" #include "td/telegram/files/FileType.h" #include "td/telegram/net/DcId.h" #include "td/telegram/PhotoSizeSource.hpp" #include "td/telegram/Version.h" #include "td/utils/common.h" #include "td/utils/tl_helpers.h" #include "td/utils/Variant.h" namespace td { template void PartialRemoteFileLocation::store(StorerT &storer) const { using td::store; store(file_id_, storer); store(part_count_, storer); store(part_size_, storer); store(ready_part_count_, storer); store(is_big_, storer); } template void PartialRemoteFileLocation::parse(ParserT &parser) { using td::parse; parse(file_id_, parser); parse(part_count_, parser); parse(part_size_, parser); parse(ready_part_count_, parser); parse(is_big_, parser); } template void PhotoRemoteFileLocation::store(StorerT &storer) const { using td::store; store(id_, storer); store(access_hash_, storer); store(volume_id_, storer); store(source_, storer); store(local_id_, storer); } template void PhotoRemoteFileLocation::parse(ParserT &parser) { using td::parse; parse(id_, parser); parse(access_hash_, parser); parse(volume_id_, parser); if (parser.version() >= static_cast(Version::AddPhotoSizeSource)) { parse(source_, parser); } else { int64 secret; parse(secret, parser); source_ = PhotoSizeSource(secret); } parse(local_id_, parser); } template void PhotoRemoteFileLocation::AsKey::store(StorerT &storer) const { using td::store; store(key.id_, storer); store(key.volume_id_, storer); store(key.local_id_, storer); } template void WebRemoteFileLocation::store(StorerT &storer) const { using td::store; store(url_, storer); store(access_hash_, storer); } template void WebRemoteFileLocation::parse(ParserT &parser) { using td::parse; parse(url_, parser); parse(access_hash_, parser); } template void WebRemoteFileLocation::AsKey::store(StorerT &storer) const { td::store(key.url_, storer); } template void CommonRemoteFileLocation::store(StorerT &storer) const { using td::store; store(id_, storer); store(access_hash_, storer); } template void CommonRemoteFileLocation::parse(ParserT &parser) { using td::parse; parse(id_, parser); parse(access_hash_, parser); } template void CommonRemoteFileLocation::AsKey::store(StorerT &storer) const { td::store(key.id_, storer); } template void FullRemoteFileLocation::store(StorerT &storer) const { using ::td::store; store(full_type(), storer); store(dc_id_.get_value(), storer); if (!file_reference_.empty()) { store(file_reference_, storer); } variant_.visit([&](auto &&value) { using td::store; store(value, storer); }); } template void FullRemoteFileLocation::parse(ParserT &parser) { using ::td::parse; int32 raw_type; parse(raw_type, parser); web_location_flag_ = (raw_type & WEB_LOCATION_FLAG) != 0; raw_type &= ~WEB_LOCATION_FLAG; bool has_file_reference = (raw_type & FILE_REFERENCE_FLAG) != 0; raw_type &= ~FILE_REFERENCE_FLAG; if (raw_type < 0 || raw_type >= static_cast(FileType::Size)) { return parser.set_error("Invalid FileType in FullRemoteFileLocation"); } file_type_ = static_cast(raw_type); int32 dc_id_value; parse(dc_id_value, parser); dc_id_ = DcId::from_value(dc_id_value); if (has_file_reference) { parse(file_reference_, parser); file_reference_.clear(); } switch (location_type()) { case LocationType::Web: variant_ = WebRemoteFileLocation(); return web().parse(parser); case LocationType::Photo: variant_ = PhotoRemoteFileLocation(); photo().parse(parser); if (parser.get_error() != nullptr) { return; } switch (photo().source_.get_type()) { case PhotoSizeSource::Type::Legacy: break; case PhotoSizeSource::Type::Thumbnail: if (photo().source_.get_file_type() != file_type_ || (file_type_ != FileType::Photo && file_type_ != FileType::Thumbnail && file_type_ != FileType::EncryptedThumbnail)) { parser.set_error("Invalid FileType in PhotoRemoteFileLocation Thumbnail"); } break; case PhotoSizeSource::Type::DialogPhotoSmall: case PhotoSizeSource::Type::DialogPhotoBig: if (file_type_ != FileType::ProfilePhoto) { parser.set_error("Invalid FileType in PhotoRemoteFileLocation DialogPhoto"); } break; case PhotoSizeSource::Type::StickerSetThumbnail: if (file_type_ != FileType::Thumbnail) { parser.set_error("Invalid FileType in PhotoRemoteFileLocation StickerSetThumbnail"); } break; default: UNREACHABLE(); break; } return; case LocationType::Common: variant_ = CommonRemoteFileLocation(); return common().parse(parser); case LocationType::None: break; } parser.set_error("Invalid FileType in FullRemoteFileLocation"); } template void FullRemoteFileLocation::AsKey::store(StorerT &storer) const { using td::store; store(key.key_type(), storer); key.variant_.visit([&](auto &&value) { using td::store; store(value.as_key(), storer); }); } template void RemoteFileLocation::store(StorerT &storer) const { td::store(variant_, storer); } template void RemoteFileLocation::parse(ParserT &parser) { td::parse(variant_, parser); } template void PartialLocalFileLocation::store(StorerT &storer) const { using td::store; store(file_type_, storer); store(path_, storer); store(part_size_, storer); int32 deprecated_ready_part_count = -1; store(deprecated_ready_part_count, storer); store(iv_, storer); store(ready_bitmask_, storer); } template void PartialLocalFileLocation::parse(ParserT &parser) { using td::parse; parse(file_type_, parser); if (file_type_ < FileType::Thumbnail || file_type_ >= FileType::Size) { return parser.set_error("Invalid type in PartialLocalFileLocation"); } parse(path_, parser); parse(part_size_, parser); int32 deprecated_ready_part_count; parse(deprecated_ready_part_count, parser); parse(iv_, parser); if (deprecated_ready_part_count == -1) { parse(ready_bitmask_, parser); } else { CHECK(0 <= deprecated_ready_part_count); CHECK(deprecated_ready_part_count <= (1 << 22)); ready_bitmask_ = Bitmask(Bitmask::Ones{}, deprecated_ready_part_count).encode(); } } template void FullLocalFileLocation::store(StorerT &storer) const { using td::store; store(file_type_, storer); store(mtime_nsec_, storer); store(path_, storer); } template void FullLocalFileLocation::parse(ParserT &parser) { using td::parse; parse(file_type_, parser); if (file_type_ < FileType::Thumbnail || file_type_ >= FileType::Size) { return parser.set_error("Invalid type in FullLocalFileLocation"); } parse(mtime_nsec_, parser); parse(path_, parser); } template void PartialLocalFileLocationPtr::store(StorerT &storer) const { td::store(*location_, storer); } template void PartialLocalFileLocationPtr::parse(ParserT &parser) { td::parse(*location_, parser); } template void LocalFileLocation::store(StorerT &storer) const { td::store(variant_, storer); } template void LocalFileLocation::parse(ParserT &parser) { td::parse(variant_, parser); } template void FullGenerateFileLocation::store(StorerT &storer) const { using td::store; store(file_type_, storer); store(original_path_, storer); store(conversion_, storer); } template void FullGenerateFileLocation::parse(ParserT &parser) { using td::parse; parse(file_type_, parser); parse(original_path_, parser); parse(conversion_, parser); } template void GenerateFileLocation::store(StorerT &storer) const { td::store(type_, storer); switch (type_) { case Type::Empty: return; case Type::Full: return td::store(full_, storer); } } template void GenerateFileLocation::parse(ParserT &parser) { td::parse(type_, parser); switch (type_) { case Type::Empty: return; case Type::Full: return td::parse(full_, parser); } return parser.set_error("Invalid type in GenerateFileLocation"); } } // namespace td