Update layer to 128. Remove photo volume_id/local_id.
This commit is contained in:
parent
e1ebf74398
commit
4bb76a7b6f
@ -19,6 +19,9 @@ ipPortSecret#37982646 ipv4:int port:int secret:bytes = IpPort;
|
||||
accessPointRule#4679b65f phone_prefix_rules:string dc_id:int ips:vector<IpPort> = AccessPointRule;
|
||||
help.configSimple#5a592a6c date:int expires:int rules:vector<AccessPointRule> = help.ConfigSimple;
|
||||
|
||||
inputPeerPhotoFileLocationLegacy#27d69997 flags:# big:flags.0?true peer:InputPeer volume_id:long local_id:int = InputFileLocation;
|
||||
inputStickerSetThumbLegacy#dbaeae9 stickerset:InputStickerSet volume_id:long local_id:int = InputFileLocation;
|
||||
|
||||
---functions---
|
||||
|
||||
test.useError = Error;
|
||||
@ -77,8 +80,8 @@ inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation;
|
||||
inputTakeoutFileLocation#29be5899 = InputFileLocation;
|
||||
inputPhotoFileLocation#40181ffe id:long access_hash:long file_reference:bytes thumb_size:string = InputFileLocation;
|
||||
inputPhotoLegacyFileLocation#d83466f3 id:long access_hash:long file_reference:bytes volume_id:long local_id:int secret:long = InputFileLocation;
|
||||
inputPeerPhotoFileLocation#27d69997 flags:# big:flags.0?true peer:InputPeer volume_id:long local_id:int = InputFileLocation;
|
||||
inputStickerSetThumb#dbaeae9 stickerset:InputStickerSet volume_id:long local_id:int = InputFileLocation;
|
||||
inputPeerPhotoFileLocation#37257e99 flags:# big:flags.0?true peer:InputPeer photo_id:long = InputFileLocation;
|
||||
inputStickerSetThumb#9d84f3db stickerset:InputStickerSet thumb_version:int = InputFileLocation;
|
||||
inputGroupCallStream#bba51639 call:InputGroupCall time_ms:long scale:int = InputFileLocation;
|
||||
|
||||
peerUser#9db1bc6d user_id:int = Peer;
|
||||
@ -100,7 +103,7 @@ userEmpty#200250ba id:int = User;
|
||||
user#938458c1 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
|
||||
|
||||
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
||||
userProfilePhoto#cc656077 flags:# has_video:flags.0?true photo_id:long photo_small:FileLocation photo_big:FileLocation stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
|
||||
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
|
||||
|
||||
userStatusEmpty#9d05049 = UserStatus;
|
||||
userStatusOnline#edb93949 expires:int = UserStatus;
|
||||
@ -126,7 +129,7 @@ chatParticipantsForbidden#fc900c2b flags:# chat_id:int self_participant:flags.0?
|
||||
chatParticipants#3f460fed chat_id:int participants:Vector<ChatParticipant> version:int = ChatParticipants;
|
||||
|
||||
chatPhotoEmpty#37c1011c = ChatPhoto;
|
||||
chatPhoto#4790ee05 flags:# has_video:flags.0?true photo_small:FileLocation photo_big:FileLocation stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto;
|
||||
chatPhoto#1c6e1c11 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto;
|
||||
|
||||
messageEmpty#90a6ca84 flags:# id:int peer_id:flags.0?Peer = Message;
|
||||
message#bce383d2 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector<RestrictionReason> ttl_period:flags.25?int = Message;
|
||||
@ -182,10 +185,10 @@ photoEmpty#2331b22d id:long = Photo;
|
||||
photo#fb197a65 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector<PhotoSize> video_sizes:flags.1?Vector<VideoSize> dc_id:int = Photo;
|
||||
|
||||
photoSizeEmpty#e17e23c type:string = PhotoSize;
|
||||
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
|
||||
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
|
||||
photoSize#75c78e60 type:string w:int h:int size:int = PhotoSize;
|
||||
photoCachedSize#21e1ad6 type:string w:int h:int bytes:bytes = PhotoSize;
|
||||
photoStrippedSize#e0b0bc2e type:string bytes:bytes = PhotoSize;
|
||||
photoSizeProgressive#5aa86a51 type:string location:FileLocation w:int h:int sizes:Vector<int> = PhotoSize;
|
||||
photoSizeProgressive#fa3efb95 type:string w:int h:int sizes:Vector<int> = PhotoSize;
|
||||
photoPathSize#d8214d41 type:string bytes:bytes = PhotoSize;
|
||||
|
||||
geoPointEmpty#1117dd5f = GeoPoint;
|
||||
@ -1078,8 +1081,6 @@ emojiURL#a575739d url:string = EmojiURL;
|
||||
|
||||
emojiLanguage#b3fb5361 lang_code:string = EmojiLanguage;
|
||||
|
||||
fileLocationToBeDeprecated#bc7fc6cd volume_id:long local_id:int = FileLocation;
|
||||
|
||||
folder#ff544e65 flags:# autofill_new_broadcasts:flags.0?true autofill_public_groups:flags.1?true autofill_new_correspondents:flags.2?true id:int title:string photo:flags.3?ChatPhoto = Folder;
|
||||
|
||||
inputFolderPeer#fbd2c296 peer:InputPeer folder_id:int = InputFolderPeer;
|
||||
@ -1159,7 +1160,7 @@ stats.broadcastStats#bdf78394 period:StatsDateRangeDays followers:StatsAbsValueA
|
||||
help.promoDataEmpty#98f6ac75 expires:int = help.PromoData;
|
||||
help.promoData#8c39793f flags:# proxy:flags.0?true expires:int peer:Peer chats:Vector<Chat> users:Vector<User> psa_type:flags.1?string psa_message:flags.2?string = help.PromoData;
|
||||
|
||||
videoSize#e831c556 flags:# type:string location:FileLocation w:int h:int size:int video_start_ts:flags.0?double = VideoSize;
|
||||
videoSize#de33b094 flags:# type:string w:int h:int size:int video_start_ts:flags.0?double = VideoSize;
|
||||
|
||||
statsGroupTopPoster#18f3d0f7 user_id:int messages:int avg_chars:int = StatsGroupTopPoster;
|
||||
|
||||
|
@ -8410,8 +8410,6 @@ ContactsManager::User *ContactsManager::get_user_force(UserId user_id) {
|
||||
int32 flags = telegram_api::user::ACCESS_HASH_MASK | telegram_api::user::FIRST_NAME_MASK |
|
||||
telegram_api::user::APPLY_MIN_PHOTO_MASK;
|
||||
int64 profile_photo_id = 0;
|
||||
int64 profile_photo_volume_id = 0;
|
||||
int32 profile_photo_local_id = 0;
|
||||
int32 profile_photo_dc_id = 1;
|
||||
string first_name;
|
||||
string last_name;
|
||||
@ -8428,8 +8426,6 @@ ContactsManager::User *ContactsManager::get_user_force(UserId user_id) {
|
||||
}
|
||||
phone_number = "42777";
|
||||
profile_photo_id = 3337190045231023;
|
||||
profile_photo_volume_id = 107738948;
|
||||
profile_photo_local_id = 13226;
|
||||
} else if (user_id == get_replies_bot_user_id()) {
|
||||
flags |= telegram_api::user::USERNAME_MASK | telegram_api::user::BOT_MASK;
|
||||
if (!G()->is_test_dc()) {
|
||||
@ -8447,20 +8443,13 @@ ContactsManager::User *ContactsManager::get_user_force(UserId user_id) {
|
||||
username = G()->is_test_dc() ? "izgroupbot" : "GroupAnonymousBot";
|
||||
bot_info_version = G()->is_test_dc() ? 1 : 3;
|
||||
profile_photo_id = 5159307831025969322;
|
||||
profile_photo_volume_id = 806529792;
|
||||
profile_photo_local_id = 188482;
|
||||
}
|
||||
|
||||
telegram_api::object_ptr<telegram_api::userProfilePhoto> profile_photo;
|
||||
if (!G()->is_test_dc() && profile_photo_id != 0) {
|
||||
flags |= telegram_api::user::PHOTO_MASK;
|
||||
profile_photo = telegram_api::make_object<telegram_api::userProfilePhoto>(
|
||||
0, false /*ignored*/, profile_photo_id,
|
||||
telegram_api::make_object<telegram_api::fileLocationToBeDeprecated>(profile_photo_volume_id,
|
||||
profile_photo_local_id),
|
||||
telegram_api::make_object<telegram_api::fileLocationToBeDeprecated>(profile_photo_volume_id,
|
||||
profile_photo_local_id + 2),
|
||||
BufferSlice(), profile_photo_dc_id);
|
||||
profile_photo = telegram_api::make_object<telegram_api::userProfilePhoto>(0, false /*ignored*/, profile_photo_id,
|
||||
BufferSlice(), profile_photo_dc_id);
|
||||
}
|
||||
|
||||
auto user = telegram_api::make_object<telegram_api::user>(
|
||||
|
@ -354,16 +354,25 @@ void FileReferenceManager::reload_photo(PhotoSizeSource source, Promise<Unit> pr
|
||||
switch (source.get_type()) {
|
||||
case PhotoSizeSource::Type::DialogPhotoBig:
|
||||
case PhotoSizeSource::Type::DialogPhotoSmall:
|
||||
case PhotoSizeSource::Type::DialogPhotoBigLegacy:
|
||||
case PhotoSizeSource::Type::DialogPhotoSmallLegacy:
|
||||
send_closure(G()->contacts_manager(), &ContactsManager::reload_dialog_info, source.dialog_photo().dialog_id,
|
||||
std::move(promise));
|
||||
break;
|
||||
case PhotoSizeSource::Type::StickerSetThumbnail:
|
||||
case PhotoSizeSource::Type::StickerSetThumbnailLegacy:
|
||||
case PhotoSizeSource::Type::StickerSetThumbnailVersion:
|
||||
send_closure(G()->stickers_manager(), &StickersManager::reload_sticker_set,
|
||||
StickerSetId(source.sticker_set_thumbnail().sticker_set_id),
|
||||
source.sticker_set_thumbnail().sticker_set_access_hash, std::move(promise));
|
||||
break;
|
||||
default:
|
||||
case PhotoSizeSource::Type::Legacy:
|
||||
case PhotoSizeSource::Type::FullLegacy:
|
||||
case PhotoSizeSource::Type::Thumbnail:
|
||||
promise.set_error(Status::Error("Unexpected PhotoSizeSource type"));
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3091,10 +3091,9 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo
|
||||
new_file_view.remote_location().get_file_reference() ||
|
||||
old_file_view.main_remote_location().get_access_hash() !=
|
||||
new_file_view.remote_location().get_access_hash()) {
|
||||
auto volume_id = -new_file_view.remote_location().get_id();
|
||||
FileId file_id = td->file_manager_->register_remote(
|
||||
FullRemoteFileLocation({FileType::Photo, 'i'}, new_file_view.remote_location().get_id(),
|
||||
new_file_view.remote_location().get_access_hash(), 0, volume_id, DcId::invalid(),
|
||||
new_file_view.remote_location().get_access_hash(), DcId::invalid(),
|
||||
new_file_view.remote_location().get_file_reference().str()),
|
||||
FileLocationSource::FromServer, dialog_id, old_photo->photos.back().size, 0, "");
|
||||
LOG_STATUS(td->file_manager_->merge(file_id, old_file_id));
|
||||
@ -3592,16 +3591,6 @@ void unregister_message_content(Td *td, const MessageContent *content, FullMessa
|
||||
template <class ToT, class FromT>
|
||||
static tl_object_ptr<ToT> secret_to_telegram(FromT &from);
|
||||
|
||||
// fileLocationUnavailable volume_id:long local_id:int secret:long = FileLocation;
|
||||
static auto secret_to_telegram(secret_api::fileLocationUnavailable &file_location) {
|
||||
return make_tl_object<telegram_api::fileLocationToBeDeprecated>(file_location.volume_id_, file_location.local_id_);
|
||||
}
|
||||
|
||||
// fileLocation dc_id:int volume_id:long local_id:int secret:long = FileLocation;
|
||||
static auto secret_to_telegram(secret_api::fileLocation &file_location) {
|
||||
return make_tl_object<telegram_api::fileLocationToBeDeprecated>(file_location.volume_id_, file_location.local_id_);
|
||||
}
|
||||
|
||||
// photoSizeEmpty type:string = PhotoSize;
|
||||
static auto secret_to_telegram(secret_api::photoSizeEmpty &empty) {
|
||||
if (!clean_input_string(empty.type_)) {
|
||||
@ -3615,9 +3604,7 @@ static auto secret_to_telegram(secret_api::photoSize &photo_size) {
|
||||
if (!clean_input_string(photo_size.type_)) {
|
||||
photo_size.type_.clear();
|
||||
}
|
||||
return make_tl_object<telegram_api::photoSize>(
|
||||
photo_size.type_, secret_to_telegram<telegram_api::fileLocationToBeDeprecated>(*photo_size.location_),
|
||||
photo_size.w_, photo_size.h_, photo_size.size_);
|
||||
return make_tl_object<telegram_api::photoSize>(photo_size.type_, photo_size.w_, photo_size.h_, photo_size.size_);
|
||||
}
|
||||
|
||||
// photoCachedSize type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
|
||||
@ -3625,9 +3612,8 @@ static auto secret_to_telegram(secret_api::photoCachedSize &photo_size) {
|
||||
if (!clean_input_string(photo_size.type_)) {
|
||||
photo_size.type_.clear();
|
||||
}
|
||||
return make_tl_object<telegram_api::photoCachedSize>(
|
||||
photo_size.type_, secret_to_telegram<telegram_api::fileLocationToBeDeprecated>(*photo_size.location_),
|
||||
photo_size.w_, photo_size.h_, photo_size.bytes_.clone());
|
||||
return make_tl_object<telegram_api::photoCachedSize>(photo_size.type_, photo_size.w_, photo_size.h_,
|
||||
photo_size.bytes_.clone());
|
||||
}
|
||||
|
||||
// documentAttributeImageSize w:int h:int = DocumentAttribute;
|
||||
|
@ -139,20 +139,15 @@ static StringBuilder &operator<<(StringBuilder &string_builder, PhotoFormat form
|
||||
}
|
||||
|
||||
static FileId register_photo(FileManager *file_manager, const PhotoSizeSource &source, int64 id, int64 access_hash,
|
||||
std::string file_reference,
|
||||
tl_object_ptr<telegram_api::fileLocationToBeDeprecated> &&location,
|
||||
DialogId owner_dialog_id, int32 file_size, DcId dc_id, PhotoFormat format) {
|
||||
int32 local_id = location->local_id_;
|
||||
int64 volume_id = location->volume_id_;
|
||||
LOG(DEBUG) << "Receive " << format << " photo of type " << source.get_file_type() << " in [" << dc_id << ","
|
||||
<< volume_id << "," << local_id << "]. Id: (" << id << ", " << access_hash << ")";
|
||||
auto suggested_name = PSTRING() << static_cast<uint64>(volume_id) << "_" << static_cast<uint64>(local_id) << '.'
|
||||
<< format;
|
||||
std::string file_reference, DialogId owner_dialog_id, int32 file_size, DcId dc_id,
|
||||
PhotoFormat format) {
|
||||
LOG(DEBUG) << "Receive " << format << " photo " << id << " of type " << source.get_file_type() << " from " << dc_id;
|
||||
auto suggested_name = PSTRING() << source.get_unique_name(id) << '.' << format;
|
||||
auto file_location_source = owner_dialog_id.get_type() == DialogType::SecretChat ? FileLocationSource::FromUser
|
||||
: FileLocationSource::FromServer;
|
||||
return file_manager->register_remote(
|
||||
FullRemoteFileLocation(source, id, access_hash, local_id, volume_id, dc_id, std::move(file_reference)),
|
||||
file_location_source, owner_dialog_id, file_size, 0, std::move(suggested_name));
|
||||
FullRemoteFileLocation(source, id, access_hash, dc_id, std::move(file_reference)), file_location_source,
|
||||
owner_dialog_id, file_size, 0, std::move(suggested_name));
|
||||
}
|
||||
|
||||
ProfilePhoto get_profile_photo(FileManager *file_manager, UserId user_id, int64 user_access_hash,
|
||||
@ -171,11 +166,11 @@ ProfilePhoto get_profile_photo(FileManager *file_manager, UserId user_id, int64
|
||||
result.id = profile_photo->photo_id_;
|
||||
result.minithumbnail = profile_photo->stripped_thumb_.as_slice().str();
|
||||
result.small_file_id =
|
||||
register_photo(file_manager, {DialogId(user_id), user_access_hash, false}, result.id, 0, "",
|
||||
std::move(profile_photo->photo_small_), DialogId(), 0, dc_id, PhotoFormat::Jpeg);
|
||||
register_photo(file_manager, {DialogId(user_id), user_access_hash, false}, result.id, 0 /*access_hash*/,
|
||||
"" /*file_reference*/, DialogId(), 0 /*file_size*/, dc_id, PhotoFormat::Jpeg);
|
||||
result.big_file_id =
|
||||
register_photo(file_manager, {DialogId(user_id), user_access_hash, true}, result.id, 0, "",
|
||||
std::move(profile_photo->photo_big_), DialogId(), 0, dc_id, PhotoFormat::Jpeg);
|
||||
register_photo(file_manager, {DialogId(user_id), user_access_hash, true}, result.id, 0 /*access_hash*/,
|
||||
"" /*file_reference*/, DialogId(), 0 /*file_size*/, dc_id, PhotoFormat::Jpeg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -199,17 +194,9 @@ tl_object_ptr<td_api::profilePhoto> get_profile_photo_object(FileManager *file_m
|
||||
|
||||
bool operator==(const ProfilePhoto &lhs, const ProfilePhoto &rhs) {
|
||||
bool location_differs = lhs.small_file_id != rhs.small_file_id || lhs.big_file_id != rhs.big_file_id;
|
||||
bool id_differs;
|
||||
if (lhs.id == -1 && rhs.id == -1) {
|
||||
// group chat photo
|
||||
id_differs = location_differs;
|
||||
} else {
|
||||
id_differs = lhs.id != rhs.id;
|
||||
}
|
||||
bool id_differs = lhs.id != rhs.id;
|
||||
|
||||
if (location_differs) {
|
||||
LOG_IF(ERROR, !id_differs) << "Photo " << lhs.id << " location has changed. First profilePhoto: " << lhs
|
||||
<< ", second profilePhoto: " << rhs;
|
||||
return false;
|
||||
}
|
||||
return lhs.has_animation == rhs.has_animation && lhs.minithumbnail == rhs.minithumbnail && !id_differs;
|
||||
@ -239,11 +226,10 @@ DialogPhoto get_dialog_photo(FileManager *file_manager, DialogId dialog_id, int6
|
||||
auto dc_id = DcId::create(chat_photo->dc_id_);
|
||||
result.has_animation = (chat_photo->flags_ & telegram_api::chatPhoto::HAS_VIDEO_MASK) != 0;
|
||||
result.minithumbnail = chat_photo->stripped_thumb_.as_slice().str();
|
||||
result.small_file_id =
|
||||
register_photo(file_manager, {dialog_id, dialog_access_hash, false}, 0, 0, "",
|
||||
std::move(chat_photo->photo_small_), DialogId(), 0, dc_id, PhotoFormat::Jpeg);
|
||||
result.big_file_id = register_photo(file_manager, {dialog_id, dialog_access_hash, true}, 0, 0, "",
|
||||
std::move(chat_photo->photo_big_), DialogId(), 0, dc_id, PhotoFormat::Jpeg);
|
||||
result.small_file_id = register_photo(file_manager, {dialog_id, dialog_access_hash, false}, chat_photo->photo_id_,
|
||||
0, "", DialogId(), 0, dc_id, PhotoFormat::Jpeg);
|
||||
result.big_file_id = register_photo(file_manager, {dialog_id, dialog_access_hash, true}, chat_photo->photo_id_, 0,
|
||||
"", DialogId(), 0, dc_id, PhotoFormat::Jpeg);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -287,6 +273,7 @@ DialogPhoto as_fake_dialog_photo(const Photo &photo) {
|
||||
result.big_file_id = size.file_id;
|
||||
}
|
||||
}
|
||||
result.minithumbnail = photo.minithumbnail;
|
||||
result.has_animation = !photo.animations.empty();
|
||||
if (!result.small_file_id.is_valid() || !result.big_file_id.is_valid()) {
|
||||
LOG(ERROR) << "Failed to convert " << photo << " to chat photo";
|
||||
@ -348,14 +335,12 @@ PhotoSize get_secret_thumbnail_photo_size(FileManager *file_manager, BufferSlice
|
||||
|
||||
// generate some random remote location to save
|
||||
auto dc_id = DcId::invalid();
|
||||
auto local_id = -(Random::secure_int32() & 0x7FFFFFFF);
|
||||
auto volume_id = Random::secure_int64();
|
||||
auto photo_id = -(Random::secure_int64() & std::numeric_limits<int64>::max());
|
||||
|
||||
res.file_id = file_manager->register_remote(
|
||||
FullRemoteFileLocation(PhotoSizeSource(FileType::EncryptedThumbnail, 't'), 0, 0, local_id, volume_id, dc_id,
|
||||
string()),
|
||||
FullRemoteFileLocation(PhotoSizeSource(FileType::EncryptedThumbnail, 't'), photo_id, 0, dc_id, string()),
|
||||
FileLocationSource::FromServer, owner_dialog_id, res.size, 0,
|
||||
PSTRING() << static_cast<uint64>(volume_id) << "_" << static_cast<uint64>(local_id) << ".jpg");
|
||||
PSTRING() << static_cast<uint64>(photo_id) << ".jpg");
|
||||
file_manager->set_content(res.file_id, std::move(bytes));
|
||||
|
||||
return res;
|
||||
@ -367,7 +352,6 @@ Variant<PhotoSize, string> get_photo_size(FileManager *file_manager, PhotoSizeSo
|
||||
PhotoFormat format) {
|
||||
CHECK(size_ptr != nullptr);
|
||||
|
||||
tl_object_ptr<telegram_api::fileLocationToBeDeprecated> location;
|
||||
string type;
|
||||
PhotoSize res;
|
||||
BufferSlice content;
|
||||
@ -378,7 +362,6 @@ Variant<PhotoSize, string> get_photo_size(FileManager *file_manager, PhotoSizeSo
|
||||
auto size = move_tl_object_as<telegram_api::photoSize>(size_ptr);
|
||||
|
||||
type = std::move(size->type_);
|
||||
location = std::move(size->location_);
|
||||
res.dimensions = get_dimensions(size->w_, size->h_, "photoSize");
|
||||
res.size = size->size_;
|
||||
|
||||
@ -388,7 +371,6 @@ Variant<PhotoSize, string> get_photo_size(FileManager *file_manager, PhotoSizeSo
|
||||
auto size = move_tl_object_as<telegram_api::photoCachedSize>(size_ptr);
|
||||
|
||||
type = std::move(size->type_);
|
||||
location = std::move(size->location_);
|
||||
CHECK(size->bytes_.size() <= static_cast<size_t>(std::numeric_limits<int32>::max()));
|
||||
res.dimensions = get_dimensions(size->w_, size->h_, "photoCachedSize");
|
||||
res.size = static_cast<int32>(size->bytes_.size());
|
||||
@ -415,7 +397,6 @@ Variant<PhotoSize, string> get_photo_size(FileManager *file_manager, PhotoSizeSo
|
||||
std::sort(size->sizes_.begin(), size->sizes_.end());
|
||||
|
||||
type = std::move(size->type_);
|
||||
location = std::move(size->location_);
|
||||
res.dimensions = get_dimensions(size->w_, size->h_, "photoSizeProgressive");
|
||||
res.size = size->sizes_.back();
|
||||
size->sizes_.pop_back();
|
||||
@ -437,17 +418,21 @@ Variant<PhotoSize, string> get_photo_size(FileManager *file_manager, PhotoSizeSo
|
||||
}
|
||||
|
||||
if (type.size() != 1) {
|
||||
res.type = 0;
|
||||
LOG(ERROR) << "Wrong photoSize \"" << type << "\" " << res;
|
||||
res.type = 0;
|
||||
} else {
|
||||
res.type = static_cast<uint8>(type[0]);
|
||||
if (res.type >= 128) {
|
||||
LOG(ERROR) << "Wrong photoSize \"" << type << "\" " << res;
|
||||
res.type = 0;
|
||||
}
|
||||
}
|
||||
if (source.get_type() == PhotoSizeSource::Type::Thumbnail) {
|
||||
source.thumbnail().thumbnail_type = res.type;
|
||||
}
|
||||
|
||||
res.file_id = register_photo(file_manager, source, id, access_hash, file_reference, std::move(location),
|
||||
owner_dialog_id, res.size, dc_id, format);
|
||||
res.file_id =
|
||||
register_photo(file_manager, source, id, access_hash, file_reference, owner_dialog_id, res.size, dc_id, format);
|
||||
|
||||
if (!content.empty()) {
|
||||
file_manager->set_content(res.file_id, std::move(content));
|
||||
@ -465,6 +450,10 @@ AnimationSize get_animation_size(FileManager *file_manager, PhotoSizeSource sour
|
||||
LOG(ERROR) << "Wrong videoSize \"" << size->type_ << "\" in " << to_string(size);
|
||||
}
|
||||
res.type = static_cast<uint8>(size->type_[0]);
|
||||
if (res.type >= 128) {
|
||||
LOG(ERROR) << "Wrong videoSize \"" << res.type << "\" " << res;
|
||||
res.type = 0;
|
||||
}
|
||||
res.dimensions = get_dimensions(size->w_, size->h_, "get_animation_size");
|
||||
res.size = size->size_;
|
||||
if ((size->flags_ & telegram_api::videoSize::VIDEO_START_TS_MASK) != 0) {
|
||||
@ -475,8 +464,8 @@ AnimationSize get_animation_size(FileManager *file_manager, PhotoSizeSource sour
|
||||
source.thumbnail().thumbnail_type = res.type;
|
||||
}
|
||||
|
||||
res.file_id = register_photo(file_manager, source, id, access_hash, file_reference, std::move(size->location_),
|
||||
owner_dialog_id, res.size, dc_id, PhotoFormat::Mpeg4);
|
||||
res.file_id = register_photo(file_manager, source, id, access_hash, file_reference, owner_dialog_id, res.size, dc_id,
|
||||
PhotoFormat::Mpeg4);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -937,20 +926,14 @@ StringBuilder &operator<<(StringBuilder &string_builder, const Photo &photo) {
|
||||
return string_builder << ']';
|
||||
}
|
||||
|
||||
static tl_object_ptr<telegram_api::fileLocationToBeDeprecated> copy_location(
|
||||
const tl_object_ptr<telegram_api::fileLocationToBeDeprecated> &location) {
|
||||
CHECK(location != nullptr);
|
||||
return make_tl_object<telegram_api::fileLocationToBeDeprecated>(location->volume_id_, location->local_id_);
|
||||
}
|
||||
|
||||
tl_object_ptr<telegram_api::userProfilePhoto> convert_photo_to_profile_photo(
|
||||
const tl_object_ptr<telegram_api::photo> &photo) {
|
||||
if (photo == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tl_object_ptr<telegram_api::fileLocationToBeDeprecated> photo_small;
|
||||
tl_object_ptr<telegram_api::fileLocationToBeDeprecated> photo_big;
|
||||
bool have_photo_small = false;
|
||||
bool have_photo_big = false;
|
||||
for (auto &size_ptr : photo->sizes_) {
|
||||
switch (size_ptr->get_id()) {
|
||||
case telegram_api::photoSizeEmpty::ID:
|
||||
@ -958,18 +941,18 @@ tl_object_ptr<telegram_api::userProfilePhoto> convert_photo_to_profile_photo(
|
||||
case telegram_api::photoSize::ID: {
|
||||
auto size = static_cast<const telegram_api::photoSize *>(size_ptr.get());
|
||||
if (size->type_ == "a") {
|
||||
photo_small = copy_location(size->location_);
|
||||
have_photo_small = true;
|
||||
} else if (size->type_ == "c") {
|
||||
photo_big = copy_location(size->location_);
|
||||
have_photo_big = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case telegram_api::photoCachedSize::ID: {
|
||||
auto size = static_cast<const telegram_api::photoCachedSize *>(size_ptr.get());
|
||||
if (size->type_ == "a") {
|
||||
photo_small = copy_location(size->location_);
|
||||
have_photo_small = true;
|
||||
} else if (size->type_ == "c") {
|
||||
photo_big = copy_location(size->location_);
|
||||
have_photo_big = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -978,9 +961,9 @@ tl_object_ptr<telegram_api::userProfilePhoto> convert_photo_to_profile_photo(
|
||||
case telegram_api::photoSizeProgressive::ID: {
|
||||
auto size = static_cast<const telegram_api::photoSizeProgressive *>(size_ptr.get());
|
||||
if (size->type_ == "a") {
|
||||
photo_small = copy_location(size->location_);
|
||||
have_photo_small = true;
|
||||
} else if (size->type_ == "c") {
|
||||
photo_big = copy_location(size->location_);
|
||||
have_photo_big = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -989,15 +972,15 @@ tl_object_ptr<telegram_api::userProfilePhoto> convert_photo_to_profile_photo(
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (photo_small == nullptr || photo_big == nullptr) {
|
||||
if (!have_photo_small || !have_photo_big) {
|
||||
return nullptr;
|
||||
}
|
||||
int32 flags = 0;
|
||||
if (!photo->video_sizes_.empty()) {
|
||||
flags |= telegram_api::userProfilePhoto::HAS_VIDEO_MASK;
|
||||
}
|
||||
return make_tl_object<telegram_api::userProfilePhoto>(flags, false /*ignored*/, photo->id_, std::move(photo_small),
|
||||
std::move(photo_big), BufferSlice(), photo->dc_id_);
|
||||
return make_tl_object<telegram_api::userProfilePhoto>(flags, false /*ignored*/, photo->id_, BufferSlice(),
|
||||
photo->dc_id_);
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -99,6 +99,10 @@ void parse(PhotoSize &photo_size, ParserT &parser) {
|
||||
} else {
|
||||
photo_size.progressive_sizes.clear();
|
||||
}
|
||||
if (photo_size.type < 0 || photo_size.type >= 128) {
|
||||
parser.set_error("Wrong PhotoSize type");
|
||||
return;
|
||||
}
|
||||
LOG(DEBUG) << "Parsed photo size " << photo_size;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,9 @@
|
||||
#include "td/telegram/UserId.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/StackAllocator.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
#include "td/utils/tl_storers.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
@ -40,22 +43,117 @@ tl_object_ptr<telegram_api::InputPeer> PhotoSizeSource::DialogPhoto::get_input_p
|
||||
|
||||
FileType PhotoSizeSource::get_file_type() const {
|
||||
switch (get_type()) {
|
||||
case PhotoSizeSource::Type::Thumbnail:
|
||||
case Type::Thumbnail:
|
||||
return thumbnail().file_type;
|
||||
case PhotoSizeSource::Type::DialogPhotoSmall:
|
||||
case PhotoSizeSource::Type::DialogPhotoBig:
|
||||
case Type::DialogPhotoSmall:
|
||||
case Type::DialogPhotoBig:
|
||||
case Type::DialogPhotoSmallLegacy:
|
||||
case Type::DialogPhotoBigLegacy:
|
||||
return FileType::ProfilePhoto;
|
||||
case PhotoSizeSource::Type::StickerSetThumbnail:
|
||||
case Type::StickerSetThumbnail:
|
||||
case Type::StickerSetThumbnailLegacy:
|
||||
case Type::StickerSetThumbnailVersion:
|
||||
return FileType::Thumbnail;
|
||||
case PhotoSizeSource::Type::Legacy:
|
||||
case Type::Legacy:
|
||||
case Type::FullLegacy:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return FileType::Thumbnail;
|
||||
}
|
||||
}
|
||||
|
||||
string PhotoSizeSource::get_unique() const {
|
||||
auto ptr = StackAllocator::alloc(16);
|
||||
MutableSlice data = ptr.as_slice();
|
||||
TlStorerUnsafe storer(data.ubegin());
|
||||
switch (get_type()) {
|
||||
case Type::Legacy:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case Type::Thumbnail: {
|
||||
auto type = thumbnail().thumbnail_type;
|
||||
CHECK(0 <= type && type <= 127);
|
||||
if (type == 'a') {
|
||||
type = 0;
|
||||
} else if (type == 'c') {
|
||||
type = 1;
|
||||
} else {
|
||||
type += 5;
|
||||
}
|
||||
return string(1, static_cast<char>(type));
|
||||
}
|
||||
case Type::DialogPhotoSmall:
|
||||
// it doesn't matter to which Dialog the photo belongs
|
||||
return string(1, '\x00');
|
||||
case Type::DialogPhotoBig:
|
||||
// it doesn't matter to which Dialog the photo belongs
|
||||
return string(1, '\x01');
|
||||
case Type::StickerSetThumbnail:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case Type::FullLegacy: {
|
||||
auto &legacy = full_legacy();
|
||||
td::store(legacy.volume_id, storer);
|
||||
td::store(legacy.local_id, storer);
|
||||
break;
|
||||
}
|
||||
case Type::DialogPhotoSmallLegacy:
|
||||
case Type::DialogPhotoBigLegacy: {
|
||||
auto &legacy = dialog_photo_legacy();
|
||||
td::store(legacy.volume_id, storer);
|
||||
td::store(legacy.local_id, storer);
|
||||
break;
|
||||
}
|
||||
case Type::StickerSetThumbnailLegacy: {
|
||||
auto &legacy = sticker_set_thumbnail_legacy();
|
||||
td::store(legacy.volume_id, storer);
|
||||
td::store(legacy.local_id, storer);
|
||||
break;
|
||||
}
|
||||
case Type::StickerSetThumbnailVersion: {
|
||||
auto &thumbnail = sticker_set_thumbnail_version();
|
||||
storer.store_slice(Slice("\x02"));
|
||||
td::store(thumbnail.sticker_set_id, storer);
|
||||
td::store(thumbnail.version, storer);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
auto size = storer.get_buf() - data.ubegin();
|
||||
CHECK(size <= 13);
|
||||
return string(data.begin(), size);
|
||||
}
|
||||
|
||||
string PhotoSizeSource::get_unique_name(int64 photo_id) const {
|
||||
switch (get_type()) {
|
||||
case Type::Thumbnail:
|
||||
CHECK(0 <= thumbnail().thumbnail_type && thumbnail().thumbnail_type <= 127);
|
||||
return PSTRING() << photo_id << '_' << thumbnail().thumbnail_type;
|
||||
case Type::DialogPhotoSmall:
|
||||
return to_string(photo_id);
|
||||
case Type::DialogPhotoBig:
|
||||
return PSTRING() << photo_id << '_' << 1;
|
||||
case Type::StickerSetThumbnailVersion:
|
||||
return PSTRING() << sticker_set_thumbnail_version().sticker_set_id << '_'
|
||||
<< static_cast<uint32>(sticker_set_thumbnail_version().version);
|
||||
case Type::Legacy:
|
||||
case Type::StickerSetThumbnail:
|
||||
case Type::FullLegacy:
|
||||
case Type::DialogPhotoSmallLegacy:
|
||||
case Type::DialogPhotoBigLegacy:
|
||||
case Type::StickerSetThumbnailLegacy:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool operator==(const PhotoSizeSource::Legacy &lhs, const PhotoSizeSource::Legacy &rhs) {
|
||||
return lhs.secret == rhs.secret;
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool operator==(const PhotoSizeSource::Thumbnail &lhs, const PhotoSizeSource::Thumbnail &rhs) {
|
||||
@ -81,6 +179,42 @@ static bool operator==(const PhotoSizeSource::StickerSetThumbnail &lhs,
|
||||
return lhs.sticker_set_id == rhs.sticker_set_id && lhs.sticker_set_access_hash == rhs.sticker_set_access_hash;
|
||||
}
|
||||
|
||||
static bool operator==(const PhotoSizeSource::FullLegacy &lhs, const PhotoSizeSource::FullLegacy &rhs) {
|
||||
return lhs.volume_id == rhs.volume_id && lhs.local_id == rhs.local_id && lhs.secret == rhs.secret;
|
||||
}
|
||||
|
||||
static bool operator==(const PhotoSizeSource::DialogPhotoLegacy &lhs, const PhotoSizeSource::DialogPhotoLegacy &rhs) {
|
||||
return static_cast<const PhotoSizeSource::DialogPhoto &>(lhs) ==
|
||||
static_cast<const PhotoSizeSource::DialogPhoto &>(rhs) &&
|
||||
lhs.volume_id == rhs.volume_id && lhs.local_id == rhs.local_id;
|
||||
}
|
||||
|
||||
static bool operator==(const PhotoSizeSource::DialogPhotoSmallLegacy &lhs,
|
||||
const PhotoSizeSource::DialogPhotoSmallLegacy &rhs) {
|
||||
return static_cast<const PhotoSizeSource::DialogPhotoLegacy &>(lhs) ==
|
||||
static_cast<const PhotoSizeSource::DialogPhotoLegacy &>(rhs);
|
||||
}
|
||||
|
||||
static bool operator==(const PhotoSizeSource::DialogPhotoBigLegacy &lhs,
|
||||
const PhotoSizeSource::DialogPhotoBigLegacy &rhs) {
|
||||
return static_cast<const PhotoSizeSource::DialogPhotoLegacy &>(lhs) ==
|
||||
static_cast<const PhotoSizeSource::DialogPhotoLegacy &>(rhs);
|
||||
}
|
||||
|
||||
static bool operator==(const PhotoSizeSource::StickerSetThumbnailLegacy &lhs,
|
||||
const PhotoSizeSource::StickerSetThumbnailLegacy &rhs) {
|
||||
return static_cast<const PhotoSizeSource::StickerSetThumbnail &>(lhs) ==
|
||||
static_cast<const PhotoSizeSource::StickerSetThumbnail &>(rhs) &&
|
||||
lhs.volume_id == rhs.volume_id && lhs.local_id == rhs.local_id;
|
||||
}
|
||||
|
||||
static bool operator==(const PhotoSizeSource::StickerSetThumbnailVersion &lhs,
|
||||
const PhotoSizeSource::StickerSetThumbnailVersion &rhs) {
|
||||
return static_cast<const PhotoSizeSource::StickerSetThumbnail &>(lhs) ==
|
||||
static_cast<const PhotoSizeSource::StickerSetThumbnail &>(rhs) &&
|
||||
lhs.version == rhs.version;
|
||||
}
|
||||
|
||||
bool operator==(const PhotoSizeSource &lhs, const PhotoSizeSource &rhs) {
|
||||
return lhs.variant == rhs.variant;
|
||||
}
|
||||
@ -91,6 +225,8 @@ bool operator!=(const PhotoSizeSource &lhs, const PhotoSizeSource &rhs) {
|
||||
|
||||
StringBuilder &operator<<(StringBuilder &string_builder, const PhotoSizeSource &source) {
|
||||
switch (source.get_type()) {
|
||||
case PhotoSizeSource::Type::Legacy:
|
||||
return string_builder << "PhotoSizeSourceLegacy[]";
|
||||
case PhotoSizeSource::Type::Thumbnail:
|
||||
return string_builder << "PhotoSizeSourceThumbnail[" << source.thumbnail().file_type
|
||||
<< ", type = " << source.thumbnail().thumbnail_type << ']';
|
||||
@ -101,8 +237,19 @@ StringBuilder &operator<<(StringBuilder &string_builder, const PhotoSizeSource &
|
||||
case PhotoSizeSource::Type::StickerSetThumbnail:
|
||||
return string_builder << "PhotoSizeSourceStickerSetThumbnail[" << source.sticker_set_thumbnail().sticker_set_id
|
||||
<< ']';
|
||||
case PhotoSizeSource::Type::Legacy:
|
||||
return string_builder << "PhotoSizeSourceLegacy[]";
|
||||
case PhotoSizeSource::Type::FullLegacy:
|
||||
return string_builder << "PhotoSizeSourceFullLegacy[]";
|
||||
case PhotoSizeSource::Type::DialogPhotoSmallLegacy:
|
||||
return string_builder << "PhotoSizeSourceChatPhotoSmallLegacy[" << source.dialog_photo().dialog_id << ']';
|
||||
case PhotoSizeSource::Type::DialogPhotoBigLegacy:
|
||||
return string_builder << "PhotoSizeSourceChatPhotoBigLegacy[" << source.dialog_photo().dialog_id << ']';
|
||||
case PhotoSizeSource::Type::StickerSetThumbnailLegacy:
|
||||
return string_builder << "PhotoSizeSourceStickerSetThumbnailLegacy["
|
||||
<< source.sticker_set_thumbnail().sticker_set_id << ']';
|
||||
case PhotoSizeSource::Type::StickerSetThumbnailVersion:
|
||||
return string_builder << "PhotoSizeSourceStickerSetThumbnailVersion["
|
||||
<< source.sticker_set_thumbnail().sticker_set_id << '_'
|
||||
<< source.sticker_set_thumbnail_version().version << ']';
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return string_builder;
|
||||
|
@ -15,10 +15,23 @@
|
||||
#include "td/utils/StringBuilder.h"
|
||||
#include "td/utils/Variant.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace td {
|
||||
|
||||
struct PhotoSizeSource {
|
||||
enum class Type : int32 { Legacy, Thumbnail, DialogPhotoSmall, DialogPhotoBig, StickerSetThumbnail };
|
||||
enum class Type : int32 {
|
||||
Legacy,
|
||||
Thumbnail,
|
||||
DialogPhotoSmall,
|
||||
DialogPhotoBig,
|
||||
StickerSetThumbnail,
|
||||
FullLegacy,
|
||||
DialogPhotoSmallLegacy,
|
||||
DialogPhotoBigLegacy,
|
||||
StickerSetThumbnailLegacy,
|
||||
StickerSetThumbnailVersion
|
||||
};
|
||||
|
||||
// for legacy photos with secret
|
||||
struct Legacy {
|
||||
@ -75,9 +88,59 @@ struct PhotoSizeSource {
|
||||
}
|
||||
};
|
||||
|
||||
// for legacy photos with volume_id, local_id, secret
|
||||
struct FullLegacy {
|
||||
FullLegacy() = default;
|
||||
FullLegacy(int64 volume_id, int32 local_id, int64 secret)
|
||||
: volume_id(volume_id), local_id(local_id), secret(secret) {
|
||||
}
|
||||
|
||||
int64 volume_id = 0;
|
||||
int32 local_id = 0;
|
||||
int64 secret = 0;
|
||||
};
|
||||
|
||||
// for legacy dialog photos
|
||||
struct DialogPhotoLegacy : public DialogPhoto {
|
||||
DialogPhotoLegacy() = default;
|
||||
DialogPhotoLegacy(DialogId dialog_id, int64 dialog_access_hash, int64 volume_id, int32 local_id)
|
||||
: DialogPhoto(dialog_id, dialog_access_hash), volume_id(volume_id), local_id(local_id) {
|
||||
}
|
||||
|
||||
int64 volume_id = 0;
|
||||
int32 local_id = 0;
|
||||
};
|
||||
|
||||
struct DialogPhotoSmallLegacy : public DialogPhotoLegacy {
|
||||
using DialogPhotoLegacy::DialogPhotoLegacy;
|
||||
};
|
||||
|
||||
struct DialogPhotoBigLegacy : public DialogPhotoLegacy {
|
||||
using DialogPhotoLegacy::DialogPhotoLegacy;
|
||||
};
|
||||
|
||||
// for legacy sticker set thumbnails
|
||||
struct StickerSetThumbnailLegacy : public StickerSetThumbnail {
|
||||
StickerSetThumbnailLegacy() = default;
|
||||
StickerSetThumbnailLegacy(int64 sticker_set_id, int64 sticker_set_access_hash, int64 volume_id, int32 local_id)
|
||||
: StickerSetThumbnail(sticker_set_id, sticker_set_access_hash), volume_id(volume_id), local_id(local_id) {
|
||||
}
|
||||
|
||||
int64 volume_id = 0;
|
||||
int32 local_id = 0;
|
||||
};
|
||||
|
||||
// for sticker set thumbnails identified by version
|
||||
struct StickerSetThumbnailVersion : public StickerSetThumbnail {
|
||||
StickerSetThumbnailVersion() = default;
|
||||
StickerSetThumbnailVersion(int64 sticker_set_id, int64 sticker_set_access_hash, int32 version)
|
||||
: StickerSetThumbnail(sticker_set_id, sticker_set_access_hash), version(version) {
|
||||
}
|
||||
|
||||
int32 version = 0;
|
||||
};
|
||||
|
||||
PhotoSizeSource() = default;
|
||||
explicit PhotoSizeSource(int64 secret) : variant(Legacy(secret)) {
|
||||
}
|
||||
PhotoSizeSource(FileType file_type, int32 thumbnail_type) : variant(Thumbnail(file_type, thumbnail_type)) {
|
||||
}
|
||||
PhotoSizeSource(DialogId dialog_id, int64 dialog_access_hash, bool is_big) {
|
||||
@ -90,6 +153,22 @@ struct PhotoSizeSource {
|
||||
PhotoSizeSource(int64 sticker_set_id, int64 sticker_set_access_hash)
|
||||
: variant(StickerSetThumbnail(sticker_set_id, sticker_set_access_hash)) {
|
||||
}
|
||||
PhotoSizeSource(std::nullptr_t, int64 volume_id, int32 local_id, int64 secret)
|
||||
: variant(FullLegacy(volume_id, local_id, secret)) {
|
||||
}
|
||||
PhotoSizeSource(DialogId dialog_id, int64 dialog_access_hash, bool is_big, int64 volume_id, int32 local_id) {
|
||||
if (is_big) {
|
||||
variant = DialogPhotoBigLegacy(dialog_id, dialog_access_hash, volume_id, local_id);
|
||||
} else {
|
||||
variant = DialogPhotoSmallLegacy(dialog_id, dialog_access_hash, volume_id, local_id);
|
||||
}
|
||||
}
|
||||
PhotoSizeSource(int64 sticker_set_id, int64 sticker_set_access_hash, int64 volume_id, int32 local_id)
|
||||
: variant(StickerSetThumbnailLegacy(sticker_set_id, sticker_set_access_hash, volume_id, local_id)) {
|
||||
}
|
||||
PhotoSizeSource(int64 sticker_set_id, int64 sticker_set_access_hash, int32 version)
|
||||
: variant(StickerSetThumbnailVersion(sticker_set_id, sticker_set_access_hash, version)) {
|
||||
}
|
||||
|
||||
Type get_type() const {
|
||||
auto offset = variant.get_offset();
|
||||
@ -110,15 +189,55 @@ struct PhotoSizeSource {
|
||||
return variant.get<Thumbnail>();
|
||||
}
|
||||
const DialogPhoto &dialog_photo() const {
|
||||
if (variant.get_offset() == 2) {
|
||||
return variant.get<DialogPhotoSmall>();
|
||||
} else {
|
||||
return variant.get<DialogPhotoBig>();
|
||||
switch (variant.get_offset()) {
|
||||
case 2:
|
||||
return variant.get<DialogPhotoSmall>();
|
||||
case 3:
|
||||
return variant.get<DialogPhotoBig>();
|
||||
case 6:
|
||||
return variant.get<DialogPhotoSmallLegacy>();
|
||||
case 7:
|
||||
return variant.get<DialogPhotoBigLegacy>();
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return variant.get<DialogPhotoSmall>();
|
||||
}
|
||||
}
|
||||
const StickerSetThumbnail &sticker_set_thumbnail() const {
|
||||
return variant.get<StickerSetThumbnail>();
|
||||
switch (variant.get_offset()) {
|
||||
case 4:
|
||||
return variant.get<StickerSetThumbnail>();
|
||||
case 8:
|
||||
return variant.get<StickerSetThumbnailLegacy>();
|
||||
case 9:
|
||||
return variant.get<StickerSetThumbnailVersion>();
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return variant.get<StickerSetThumbnail>();
|
||||
}
|
||||
}
|
||||
const FullLegacy &full_legacy() const {
|
||||
return variant.get<FullLegacy>();
|
||||
}
|
||||
const DialogPhotoLegacy &dialog_photo_legacy() const {
|
||||
if (variant.get_offset() == 6) {
|
||||
return variant.get<DialogPhotoSmallLegacy>();
|
||||
} else {
|
||||
return variant.get<DialogPhotoBigLegacy>();
|
||||
}
|
||||
}
|
||||
const StickerSetThumbnailLegacy &sticker_set_thumbnail_legacy() const {
|
||||
return variant.get<StickerSetThumbnailLegacy>();
|
||||
}
|
||||
const StickerSetThumbnailVersion &sticker_set_thumbnail_version() const {
|
||||
return variant.get<StickerSetThumbnailVersion>();
|
||||
}
|
||||
|
||||
// returns unique representation of the source
|
||||
string get_unique() const;
|
||||
|
||||
// can't be called for Legacy sources
|
||||
string get_unique_name(int64 photo_id) const;
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const;
|
||||
@ -128,7 +247,9 @@ struct PhotoSizeSource {
|
||||
friend bool operator==(const PhotoSizeSource &lhs, const PhotoSizeSource &rhs);
|
||||
|
||||
private:
|
||||
Variant<Legacy, Thumbnail, DialogPhotoSmall, DialogPhotoBig, StickerSetThumbnail> variant;
|
||||
Variant<Legacy, Thumbnail, DialogPhotoSmall, DialogPhotoBig, StickerSetThumbnail, FullLegacy, DialogPhotoSmallLegacy,
|
||||
DialogPhotoBigLegacy, StickerSetThumbnailLegacy, StickerSetThumbnailVersion>
|
||||
variant;
|
||||
};
|
||||
|
||||
bool operator==(const PhotoSizeSource &lhs, const PhotoSizeSource &rhs);
|
||||
|
@ -15,6 +15,7 @@ namespace td {
|
||||
|
||||
template <class StorerT>
|
||||
void store(const PhotoSizeSource::Legacy &source, StorerT &storer) {
|
||||
UNREACHABLE();
|
||||
store(source.secret, storer);
|
||||
}
|
||||
|
||||
@ -39,23 +40,11 @@ void parse(PhotoSizeSource::Thumbnail &source, ParserT &parser) {
|
||||
source.file_type = static_cast<FileType>(raw_type);
|
||||
|
||||
parse(source.thumbnail_type, parser);
|
||||
if (source.thumbnail_type < 0 || source.thumbnail_type > 255) {
|
||||
if (source.thumbnail_type < 0 || source.thumbnail_type > 127) {
|
||||
parser.set_error("Wrong thumbnail type");
|
||||
}
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(const PhotoSizeSource::StickerSetThumbnail &source, StorerT &storer) {
|
||||
store(source.sticker_set_id, storer);
|
||||
store(source.sticker_set_access_hash, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(PhotoSizeSource::StickerSetThumbnail &source, ParserT &parser) {
|
||||
parse(source.sticker_set_id, parser);
|
||||
parse(source.sticker_set_access_hash, parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(const PhotoSizeSource::DialogPhoto &source, StorerT &storer) {
|
||||
store(source.dialog_id, storer);
|
||||
@ -96,6 +85,101 @@ void parse(PhotoSizeSource::DialogPhotoBig &source, ParserT &parser) {
|
||||
parse(static_cast<PhotoSizeSource::DialogPhoto &>(source), parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(const PhotoSizeSource::StickerSetThumbnail &source, StorerT &storer) {
|
||||
store(source.sticker_set_id, storer);
|
||||
store(source.sticker_set_access_hash, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(PhotoSizeSource::StickerSetThumbnail &source, ParserT &parser) {
|
||||
parse(source.sticker_set_id, parser);
|
||||
parse(source.sticker_set_access_hash, parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(const PhotoSizeSource::FullLegacy &source, StorerT &storer) {
|
||||
store(source.volume_id, storer);
|
||||
store(source.secret, storer);
|
||||
store(source.local_id, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(PhotoSizeSource::FullLegacy &source, ParserT &parser) {
|
||||
parse(source.volume_id, parser);
|
||||
parse(source.secret, parser);
|
||||
parse(source.local_id, parser);
|
||||
if (source.local_id < 0) {
|
||||
parser.set_error("Wrong local_id");
|
||||
}
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(const PhotoSizeSource::DialogPhotoLegacy &source, StorerT &storer) {
|
||||
store(static_cast<const PhotoSizeSource::DialogPhoto &>(source), storer);
|
||||
store(source.volume_id, storer);
|
||||
store(source.local_id, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(PhotoSizeSource::DialogPhotoLegacy &source, ParserT &parser) {
|
||||
parse(static_cast<PhotoSizeSource::DialogPhoto &>(source), parser);
|
||||
parse(source.volume_id, parser);
|
||||
parse(source.local_id, parser);
|
||||
if (source.local_id < 0) {
|
||||
parser.set_error("Wrong local_id");
|
||||
}
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(const PhotoSizeSource::DialogPhotoSmallLegacy &source, StorerT &storer) {
|
||||
store(static_cast<const PhotoSizeSource::DialogPhotoLegacy &>(source), storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(PhotoSizeSource::DialogPhotoSmallLegacy &source, ParserT &parser) {
|
||||
parse(static_cast<PhotoSizeSource::DialogPhotoLegacy &>(source), parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(const PhotoSizeSource::DialogPhotoBigLegacy &source, StorerT &storer) {
|
||||
store(static_cast<const PhotoSizeSource::DialogPhotoLegacy &>(source), storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(PhotoSizeSource::DialogPhotoBigLegacy &source, ParserT &parser) {
|
||||
parse(static_cast<PhotoSizeSource::DialogPhotoLegacy &>(source), parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(const PhotoSizeSource::StickerSetThumbnailLegacy &source, StorerT &storer) {
|
||||
store(static_cast<const PhotoSizeSource::StickerSetThumbnail &>(source), storer);
|
||||
store(source.volume_id, storer);
|
||||
store(source.local_id, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(PhotoSizeSource::StickerSetThumbnailLegacy &source, ParserT &parser) {
|
||||
parse(static_cast<PhotoSizeSource::StickerSetThumbnail &>(source), parser);
|
||||
parse(source.volume_id, parser);
|
||||
parse(source.local_id, parser);
|
||||
if (source.local_id < 0) {
|
||||
parser.set_error("Wrong local_id");
|
||||
}
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void store(const PhotoSizeSource::StickerSetThumbnailVersion &source, StorerT &storer) {
|
||||
store(static_cast<const PhotoSizeSource::StickerSetThumbnail &>(source), storer);
|
||||
store(source.version, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void parse(PhotoSizeSource::StickerSetThumbnailVersion &source, ParserT &parser) {
|
||||
parse(static_cast<PhotoSizeSource::StickerSetThumbnail &>(source), parser);
|
||||
parse(source.version, parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void PhotoSizeSource::store(StorerT &storer) const {
|
||||
td::store(variant, storer);
|
||||
|
@ -2445,8 +2445,8 @@ StickerSetId StickersManager::on_get_sticker_set(tl_object_ptr<telegram_api::sti
|
||||
PhotoSize thumbnail;
|
||||
string minithumbnail;
|
||||
for (auto &thumb : set->thumbs_) {
|
||||
auto photo_size = get_photo_size(td_->file_manager_.get(), {set_id.get(), s->access_hash}, 0, 0, "",
|
||||
DcId::create(set->thumb_dc_id_), DialogId(), std::move(thumb),
|
||||
auto photo_size = get_photo_size(td_->file_manager_.get(), {set_id.get(), s->access_hash, set->thumb_version_}, 0,
|
||||
0, "", DcId::create(set->thumb_dc_id_), DialogId(), std::move(thumb),
|
||||
is_animated ? PhotoFormat::Tgs : PhotoFormat::Webp);
|
||||
if (photo_size.get_offset() == 0) {
|
||||
if (!thumbnail.file_id.is_valid()) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
constexpr int32 MTPROTO_LAYER = 127;
|
||||
constexpr int32 MTPROTO_LAYER = 128;
|
||||
|
||||
enum class Version : int32 {
|
||||
Initial, // 0
|
||||
@ -43,6 +43,7 @@ enum class Version : int32 {
|
||||
AddLiveLocationHeading,
|
||||
AddLiveLocationProximityAlertDistance, // 30
|
||||
SupportBannedChannels,
|
||||
RemovePhotoVolumeAndLocalId,
|
||||
Next
|
||||
};
|
||||
|
||||
|
@ -40,7 +40,6 @@ Status drop_file_db(SqliteDb &db, int32 version) {
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status fix_file_remote_location_key_bug(SqliteDb &db);
|
||||
Status init_file_db(SqliteDb &db, int32 version) {
|
||||
LOG(INFO) << "Init file database " << tag("version", version);
|
||||
|
||||
@ -49,11 +48,9 @@ Status init_file_db(SqliteDb &db, int32 version) {
|
||||
|
||||
if (!has_table) {
|
||||
version = 0;
|
||||
} else if (version < static_cast<int32>(DbVersion::DialogDbCreated)) {
|
||||
} else if (version < static_cast<int32>(DbVersion::FixFileRemoteLocationKeyBug)) {
|
||||
TRY_STATUS(drop_file_db(db, version));
|
||||
version = 0;
|
||||
} else if (version < static_cast<int>(DbVersion::FixFileRemoteLocationKeyBug)) {
|
||||
TRY_STATUS(fix_file_remote_location_key_bug(db));
|
||||
}
|
||||
|
||||
if (version == 0) {
|
||||
@ -306,30 +303,4 @@ std::shared_ptr<FileDbInterface> create_file_db(std::shared_ptr<SqliteConnection
|
||||
return std::make_shared<FileDb>(std::move(kv), scheduler_id);
|
||||
}
|
||||
|
||||
Status fix_file_remote_location_key_bug(SqliteDb &db) {
|
||||
static const int32 OLD_KEY_MAGIC = 0x64378433;
|
||||
SqliteKeyValue kv;
|
||||
kv.init_with_connection(db.clone(), "files").ensure();
|
||||
auto ptr = StackAllocator::alloc(4);
|
||||
MutableSlice prefix = ptr.as_slice();
|
||||
TlStorerUnsafe(prefix.ubegin()).store_int(OLD_KEY_MAGIC);
|
||||
kv.get_by_prefix(prefix, [&](Slice key, Slice value) {
|
||||
CHECK(TlParser(key).fetch_int() == OLD_KEY_MAGIC);
|
||||
auto remote_str = PSTRING() << key.substr(4, 4) << Slice("\0\0\0\0") << key.substr(8);
|
||||
FullRemoteFileLocation remote;
|
||||
log_event::WithVersion<TlParser> parser(remote_str);
|
||||
parser.set_version(static_cast<int32>(Version::Initial));
|
||||
parse(remote, parser);
|
||||
parser.fetch_end();
|
||||
auto status = parser.get_status();
|
||||
if (status.is_ok()) {
|
||||
kv.set(FileDbInterface::as_key(remote), value);
|
||||
}
|
||||
LOG(DEBUG) << "ERASE " << format::as_hex_dump<4>(Slice(key));
|
||||
kv.erase(key);
|
||||
return true;
|
||||
});
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -81,8 +81,6 @@ inline StringBuilder &operator<<(StringBuilder &sb, const PartialRemoteFileLocat
|
||||
struct PhotoRemoteFileLocation {
|
||||
int64 id_;
|
||||
int64 access_hash_;
|
||||
int64 volume_id_;
|
||||
int32 local_id_;
|
||||
PhotoSizeSource source_;
|
||||
|
||||
template <class StorerT>
|
||||
@ -102,16 +100,19 @@ struct PhotoRemoteFileLocation {
|
||||
}
|
||||
|
||||
bool operator<(const PhotoRemoteFileLocation &other) const {
|
||||
return std::tie(id_, volume_id_, local_id_) < std::tie(other.id_, other.volume_id_, other.local_id_);
|
||||
if (id_ != other.id_) {
|
||||
return id_ < other.id_;
|
||||
}
|
||||
return source_.get_unique() < other.source_.get_unique();
|
||||
}
|
||||
bool operator==(const PhotoRemoteFileLocation &other) const {
|
||||
return std::tie(id_, volume_id_, local_id_) == std::tie(other.id_, other.volume_id_, other.local_id_);
|
||||
return id_ == other.id_ && source_.get_unique() == other.source_.get_unique();
|
||||
}
|
||||
};
|
||||
|
||||
inline StringBuilder &operator<<(StringBuilder &string_builder, const PhotoRemoteFileLocation &location) {
|
||||
return string_builder << "[ID = " << location.id_ << ", access_hash = " << location.access_hash_
|
||||
<< ", volume_id = " << location.volume_id_ << ", local_id = " << location.local_id_ << "]";
|
||||
return string_builder << "[ID = " << location.id_ << ", access_hash = " << location.access_hash_ << ", "
|
||||
<< location.source_ << "]";
|
||||
}
|
||||
|
||||
struct WebRemoteFileLocation {
|
||||
@ -165,10 +166,10 @@ struct CommonRemoteFileLocation {
|
||||
}
|
||||
|
||||
bool operator<(const CommonRemoteFileLocation &other) const {
|
||||
return std::tie(id_) < std::tie(other.id_);
|
||||
return id_ < other.id_;
|
||||
}
|
||||
bool operator==(const CommonRemoteFileLocation &other) const {
|
||||
return std::tie(id_) == std::tie(other.id_);
|
||||
return id_ == other.id_;
|
||||
}
|
||||
};
|
||||
|
||||
@ -324,11 +325,11 @@ class FullRemoteFileLocation {
|
||||
return photo().source_;
|
||||
case LocationType::Common:
|
||||
case LocationType::Web:
|
||||
return PhotoSizeSource(0);
|
||||
return PhotoSizeSource(nullptr, 0, 0, 0);
|
||||
case LocationType::None:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return PhotoSizeSource(0);
|
||||
return PhotoSizeSource(nullptr, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,22 +396,24 @@ class FullRemoteFileLocation {
|
||||
|
||||
tl_object_ptr<telegram_api::InputFileLocation> as_input_file_location() const {
|
||||
switch (location_type()) {
|
||||
case LocationType::Photo:
|
||||
switch (photo().source_.get_type()) {
|
||||
case LocationType::Photo: {
|
||||
const auto &id = photo().id_;
|
||||
const auto &access_hash = photo().access_hash_;
|
||||
const auto &source = photo().source_;
|
||||
switch (source.get_type()) {
|
||||
case PhotoSizeSource::Type::Legacy:
|
||||
return make_tl_object<telegram_api::inputPhotoLegacyFileLocation>(
|
||||
photo().id_, photo().access_hash_, BufferSlice(file_reference_), photo().volume_id_, photo().local_id_,
|
||||
photo().source_.legacy().secret);
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case PhotoSizeSource::Type::Thumbnail: {
|
||||
auto &thumbnail = photo().source_.thumbnail();
|
||||
auto &thumbnail = source.thumbnail();
|
||||
switch (thumbnail.file_type) {
|
||||
case FileType::Photo:
|
||||
return make_tl_object<telegram_api::inputPhotoFileLocation>(
|
||||
photo().id_, photo().access_hash_, BufferSlice(file_reference_),
|
||||
id, access_hash, BufferSlice(file_reference_),
|
||||
std::string(1, static_cast<char>(static_cast<uint8>(thumbnail.thumbnail_type))));
|
||||
case FileType::Thumbnail:
|
||||
return make_tl_object<telegram_api::inputDocumentFileLocation>(
|
||||
photo().id_, photo().access_hash_, BufferSlice(file_reference_),
|
||||
id, access_hash, BufferSlice(file_reference_),
|
||||
std::string(1, static_cast<char>(static_cast<uint8>(thumbnail.thumbnail_type))));
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -420,22 +423,46 @@ class FullRemoteFileLocation {
|
||||
}
|
||||
case PhotoSizeSource::Type::DialogPhotoSmall:
|
||||
case PhotoSizeSource::Type::DialogPhotoBig: {
|
||||
auto &dialog_photo = photo().source_.dialog_photo();
|
||||
bool is_big = photo().source_.get_type() == PhotoSizeSource::Type::DialogPhotoBig;
|
||||
auto &dialog_photo = source.dialog_photo();
|
||||
bool is_big = source.get_type() == PhotoSizeSource::Type::DialogPhotoBig;
|
||||
return make_tl_object<telegram_api::inputPeerPhotoFileLocation>(
|
||||
is_big * telegram_api::inputPeerPhotoFileLocation::Flags::BIG_MASK, false /*ignored*/,
|
||||
dialog_photo.get_input_peer(), photo().volume_id_, photo().local_id_);
|
||||
is_big * telegram_api::inputPeerPhotoFileLocation::BIG_MASK, false /*ignored*/,
|
||||
dialog_photo.get_input_peer(), id);
|
||||
}
|
||||
case PhotoSizeSource::Type::StickerSetThumbnail: {
|
||||
auto &sticker_set_thumbnail = photo().source_.sticker_set_thumbnail();
|
||||
case PhotoSizeSource::Type::StickerSetThumbnail:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case PhotoSizeSource::Type::FullLegacy: {
|
||||
const auto &full_legacy = source.full_legacy();
|
||||
return make_tl_object<telegram_api::inputPhotoLegacyFileLocation>(
|
||||
id, access_hash, BufferSlice(file_reference_), full_legacy.volume_id, full_legacy.local_id,
|
||||
full_legacy.secret);
|
||||
}
|
||||
case PhotoSizeSource::Type::DialogPhotoSmallLegacy:
|
||||
case PhotoSizeSource::Type::DialogPhotoBigLegacy: {
|
||||
auto &dialog_photo = source.dialog_photo_legacy();
|
||||
bool is_big = source.get_type() == PhotoSizeSource::Type::DialogPhotoBigLegacy;
|
||||
return make_tl_object<telegram_api::inputPeerPhotoFileLocationLegacy>(
|
||||
is_big * telegram_api::inputPeerPhotoFileLocationLegacy::BIG_MASK, false /*ignored*/,
|
||||
dialog_photo.get_input_peer(), dialog_photo.volume_id, dialog_photo.local_id);
|
||||
}
|
||||
case PhotoSizeSource::Type::StickerSetThumbnailLegacy: {
|
||||
auto &sticker_set_thumbnail = source.sticker_set_thumbnail_legacy();
|
||||
return make_tl_object<telegram_api::inputStickerSetThumbLegacy>(
|
||||
sticker_set_thumbnail.get_input_sticker_set(), sticker_set_thumbnail.volume_id,
|
||||
sticker_set_thumbnail.local_id);
|
||||
}
|
||||
case PhotoSizeSource::Type::StickerSetThumbnailVersion: {
|
||||
auto &sticker_set_thumbnail = source.sticker_set_thumbnail_version();
|
||||
return make_tl_object<telegram_api::inputStickerSetThumb>(sticker_set_thumbnail.get_input_sticker_set(),
|
||||
photo().volume_id_, photo().local_id_);
|
||||
sticker_set_thumbnail.version);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
case LocationType::Common:
|
||||
if (is_encrypted_secret()) {
|
||||
return make_tl_object<telegram_api::inputEncryptedFileLocation>(common().id_, common().access_hash_);
|
||||
@ -478,16 +505,16 @@ class FullRemoteFileLocation {
|
||||
return make_tl_object<telegram_api::inputSecureFile>(common().id_, common().access_hash_);
|
||||
}
|
||||
|
||||
// TODO: this constructor is just for immediate unserialize
|
||||
// this constructor is just for immediate unserialize
|
||||
FullRemoteFileLocation() = default;
|
||||
|
||||
// photo
|
||||
FullRemoteFileLocation(const PhotoSizeSource &source, int64 id, int64 access_hash, int32 local_id, int64 volume_id,
|
||||
DcId dc_id, std::string file_reference)
|
||||
FullRemoteFileLocation(const PhotoSizeSource &source, int64 id, int64 access_hash, DcId dc_id,
|
||||
std::string file_reference)
|
||||
: file_type_(source.get_file_type())
|
||||
, dc_id_(dc_id)
|
||||
, file_reference_(std::move(file_reference))
|
||||
, variant_(PhotoRemoteFileLocation{id, access_hash, volume_id, local_id, source}) {
|
||||
, variant_(PhotoRemoteFileLocation{id, access_hash, source}) {
|
||||
CHECK(is_photo());
|
||||
check_file_reference();
|
||||
}
|
||||
|
@ -44,9 +44,7 @@ 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 <class ParserT>
|
||||
@ -54,25 +52,87 @@ void PhotoRemoteFileLocation::parse(ParserT &parser) {
|
||||
using td::parse;
|
||||
parse(id_, parser);
|
||||
parse(access_hash_, parser);
|
||||
parse(volume_id_, parser);
|
||||
if (parser.version() >= static_cast<int32>(Version::AddPhotoSizeSource)) {
|
||||
if (parser.version() >= static_cast<int32>(Version::RemovePhotoVolumeAndLocalId)) {
|
||||
parse(source_, parser);
|
||||
} else {
|
||||
int64 secret;
|
||||
parse(secret, parser);
|
||||
source_ = PhotoSizeSource(secret);
|
||||
int64 volume_id;
|
||||
PhotoSizeSource source;
|
||||
int32 local_id;
|
||||
parse(volume_id, parser);
|
||||
if (parser.version() >= static_cast<int32>(Version::AddPhotoSizeSource)) {
|
||||
parse(source, parser);
|
||||
parse(local_id, parser);
|
||||
} else {
|
||||
int64 secret;
|
||||
parse(secret, parser);
|
||||
parse(local_id, parser);
|
||||
source = PhotoSizeSource(nullptr, volume_id, local_id, secret);
|
||||
}
|
||||
|
||||
if (parser.get_error() != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (source.get_type()) {
|
||||
case PhotoSizeSource::Type::Legacy:
|
||||
source_ = PhotoSizeSource(nullptr, volume_id, local_id, source.legacy().secret);
|
||||
break;
|
||||
case PhotoSizeSource::Type::FullLegacy:
|
||||
case PhotoSizeSource::Type::Thumbnail:
|
||||
source_ = source;
|
||||
break;
|
||||
case PhotoSizeSource::Type::DialogPhotoSmall:
|
||||
case PhotoSizeSource::Type::DialogPhotoBig: {
|
||||
auto &dialog_photo = source.dialog_photo();
|
||||
bool is_big = source.get_type() == PhotoSizeSource::Type::DialogPhotoBig;
|
||||
source_ = PhotoSizeSource(dialog_photo.dialog_id, dialog_photo.dialog_access_hash, is_big, volume_id, local_id);
|
||||
break;
|
||||
}
|
||||
case PhotoSizeSource::Type::StickerSetThumbnail: {
|
||||
auto &sticker_set_thumbnail = source.sticker_set_thumbnail();
|
||||
source_ = PhotoSizeSource(sticker_set_thumbnail.sticker_set_id, sticker_set_thumbnail.sticker_set_access_hash,
|
||||
volume_id, local_id);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
parser.set_error("Invalid PhotoSizeSource in legacy PhotoRemoteFileLocation");
|
||||
break;
|
||||
}
|
||||
}
|
||||
parse(local_id_, parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void PhotoRemoteFileLocation::AsKey::store(StorerT &storer) const {
|
||||
using td::store;
|
||||
if (!is_unique) {
|
||||
store(key.id_, storer);
|
||||
auto unique = key.source_.get_unique();
|
||||
switch (key.source_.get_type()) {
|
||||
case PhotoSizeSource::Type::Legacy:
|
||||
case PhotoSizeSource::Type::StickerSetThumbnail:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case PhotoSizeSource::Type::FullLegacy:
|
||||
case PhotoSizeSource::Type::DialogPhotoSmallLegacy:
|
||||
case PhotoSizeSource::Type::DialogPhotoBigLegacy:
|
||||
case PhotoSizeSource::Type::StickerSetThumbnailLegacy: // 12/20 bytes
|
||||
if (!is_unique) {
|
||||
store(key.id_, storer);
|
||||
}
|
||||
storer.store_slice(unique); // volume_id + local_id
|
||||
break;
|
||||
case PhotoSizeSource::Type::DialogPhotoSmall:
|
||||
case PhotoSizeSource::Type::DialogPhotoBig:
|
||||
case PhotoSizeSource::Type::Thumbnail: // 8 + 1 bytes
|
||||
store(key.id_, storer); // photo_id or document_id
|
||||
storer.store_slice(unique);
|
||||
break;
|
||||
case PhotoSizeSource::Type::StickerSetThumbnailVersion: // 13 bytes
|
||||
// sticker set thumbnails has no photo_id or document_id
|
||||
storer.store_slice(unique);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
store(key.volume_id_, storer);
|
||||
store(key.local_id_, storer);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
@ -172,6 +232,7 @@ void FullRemoteFileLocation::parse(ParserT &parser) {
|
||||
}
|
||||
switch (photo().source_.get_type()) {
|
||||
case PhotoSizeSource::Type::Legacy:
|
||||
case PhotoSizeSource::Type::FullLegacy:
|
||||
break;
|
||||
case PhotoSizeSource::Type::Thumbnail:
|
||||
if (photo().source_.get_file_type() != file_type_ ||
|
||||
@ -182,11 +243,15 @@ void FullRemoteFileLocation::parse(ParserT &parser) {
|
||||
break;
|
||||
case PhotoSizeSource::Type::DialogPhotoSmall:
|
||||
case PhotoSizeSource::Type::DialogPhotoBig:
|
||||
case PhotoSizeSource::Type::DialogPhotoSmallLegacy:
|
||||
case PhotoSizeSource::Type::DialogPhotoBigLegacy:
|
||||
if (file_type_ != FileType::ProfilePhoto) {
|
||||
parser.set_error("Invalid FileType in PhotoRemoteFileLocation DialogPhoto");
|
||||
}
|
||||
break;
|
||||
case PhotoSizeSource::Type::StickerSetThumbnail:
|
||||
case PhotoSizeSource::Type::StickerSetThumbnailLegacy:
|
||||
case PhotoSizeSource::Type::StickerSetThumbnailVersion:
|
||||
if (file_type_ != FileType::Thumbnail) {
|
||||
parser.set_error("Invalid FileType in PhotoRemoteFileLocation StickerSetThumbnail");
|
||||
}
|
||||
|
@ -324,8 +324,7 @@ class FileView {
|
||||
return false;
|
||||
}
|
||||
auto type = remote_location().get_source().get_type();
|
||||
return type == PhotoSizeSource::Type::DialogPhotoBig || type == PhotoSizeSource::Type::DialogPhotoSmall ||
|
||||
type == PhotoSizeSource::Type::StickerSetThumbnail;
|
||||
return type != PhotoSizeSource::Type::Legacy && type != PhotoSizeSource::Type::FullLegacy;
|
||||
}
|
||||
|
||||
string get_persistent_file_id() const;
|
||||
|
Loading…
Reference in New Issue
Block a user