Fixes for delete_file_reference.
GitOrigin-RevId: 15ffa944a037d34954ce5e7b0cea22131e1e976e
This commit is contained in:
parent
996869d4ca
commit
346202fbaa
@ -6923,6 +6923,7 @@ void ContactsManager::add_user_photo_id(User *u, UserId user_id, int64 photo_id,
|
||||
file_source_id = it->second;
|
||||
user_profile_photo_file_source_ids_.erase(it);
|
||||
} else {
|
||||
VLOG(file_references) << "Need to create new file source for " << photo_id << " of " << user_id;
|
||||
file_source_id = td_->file_reference_manager_->create_user_photo_file_source(user_id, photo_id);
|
||||
}
|
||||
for (auto &file_id : photo_file_ids) {
|
||||
|
@ -2122,7 +2122,7 @@ tl_object_ptr<telegram_api::InputMedia> get_input_media(const MessageContent *co
|
||||
}
|
||||
if (!was_uploaded) {
|
||||
auto file_reference = FileManager::extract_file_reference(input_media);
|
||||
if (file_reference == FileReferenceView::invalid_file_reference()) {
|
||||
if (!FileReferenceView(file_reference).has_upload()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -2132,7 +2132,7 @@ tl_object_ptr<telegram_api::InputMedia> get_input_media(const MessageContent *co
|
||||
tl_object_ptr<telegram_api::InputMedia> get_input_media(const MessageContent *content, Td *td, int32 ttl) {
|
||||
auto input_media = get_input_media(content, td, nullptr, nullptr, ttl);
|
||||
auto file_reference = FileManager::extract_file_reference(input_media);
|
||||
if (file_reference == FileReferenceView::invalid_file_reference()) {
|
||||
if (!FileReferenceView(file_reference).has_upload()) {
|
||||
return nullptr;
|
||||
}
|
||||
return input_media;
|
||||
|
@ -481,9 +481,6 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr<telegram_api::photo> &&
|
||||
res.date = photo->date_;
|
||||
res.has_stickers = (photo->flags_ & telegram_api::photo::HAS_STICKERS_MASK) != 0;
|
||||
|
||||
auto file_reference = photo->file_reference_.as_slice().str();
|
||||
// TODO use file_reference
|
||||
|
||||
for (auto &size_ptr : photo->sizes_) {
|
||||
res.photos.push_back(get_photo_size(file_manager, FileType::Photo, photo->id_, photo->access_hash_,
|
||||
photo->file_reference_.as_slice().str(), owner_dialog_id, std::move(size_ptr),
|
||||
|
@ -23,35 +23,30 @@
|
||||
#include "td/utils/Variant.h"
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace td {
|
||||
|
||||
class FileReferenceView {
|
||||
public:
|
||||
static Slice invalid_file_reference() {
|
||||
return "#";
|
||||
static std::string create_invalid() {
|
||||
return create_one(invalid_file_reference());
|
||||
}
|
||||
static std::string create_one(Slice first) {
|
||||
unsigned char second_length = 255;
|
||||
return PSTRING() << static_cast<char>(second_length) << first;
|
||||
}
|
||||
static std::string create_two(Slice first, Slice second = {}) {
|
||||
static std::string create_two(Slice first, Slice second) {
|
||||
if (second.size() >= 255) {
|
||||
LOG(ERROR) << "File reference is too big " << base64_encode(second);
|
||||
second = invalid_file_reference();
|
||||
}
|
||||
char second_length = narrow_cast<unsigned char>(second.size());
|
||||
char second_length = static_cast<char>(narrow_cast<unsigned char>(second.size()));
|
||||
return PSTRING() << second_length << first << second;
|
||||
}
|
||||
std::string create(Slice first, Slice second) const {
|
||||
if (size() == 1) {
|
||||
return create_one(first);
|
||||
}
|
||||
return create_two(first, second);
|
||||
}
|
||||
|
||||
FileReferenceView(Slice data) {
|
||||
if (data.empty()) {
|
||||
size_ = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -59,10 +54,9 @@ class FileReferenceView {
|
||||
if (second_size == 255) {
|
||||
first_ = data.substr(1);
|
||||
second_ = data.substr(1);
|
||||
size_ = 1;
|
||||
} else {
|
||||
if (second_size > data.size() - 1) {
|
||||
size_ = 1;
|
||||
first_ = second_ = data;
|
||||
return;
|
||||
}
|
||||
auto first_size = data.size() - 1 - second_size;
|
||||
@ -71,46 +65,54 @@ class FileReferenceView {
|
||||
size_ = 2;
|
||||
}
|
||||
}
|
||||
size_t size() const {
|
||||
return size_;
|
||||
}
|
||||
Slice first() const {
|
||||
Slice upload() const {
|
||||
return first_;
|
||||
}
|
||||
Slice second() const {
|
||||
Slice download() const {
|
||||
return second_;
|
||||
}
|
||||
bool has_first() const {
|
||||
return first() != invalid_file_reference();
|
||||
bool has_upload() const {
|
||||
return upload() != invalid_file_reference();
|
||||
}
|
||||
bool has_second() const {
|
||||
return second() != invalid_file_reference();
|
||||
bool has_download() const {
|
||||
return download() != invalid_file_reference();
|
||||
}
|
||||
std::pair<std::string, bool> delete_file_reference(Slice bad_file_reference) const {
|
||||
if (bad_file_reference == FileReferenceView::invalid_file_reference()) {
|
||||
return {"", false};
|
||||
return {string(), false};
|
||||
}
|
||||
auto first = this->first();
|
||||
auto second = this->second();
|
||||
bool changed = false;
|
||||
auto first = first_;
|
||||
auto second = second_;
|
||||
bool is_changed = false;
|
||||
if (first == bad_file_reference) {
|
||||
first = invalid_file_reference();
|
||||
changed = true;
|
||||
is_changed = true;
|
||||
}
|
||||
if (second == bad_file_reference) {
|
||||
second = invalid_file_reference();
|
||||
changed = true;
|
||||
is_changed = true;
|
||||
}
|
||||
if (!changed) {
|
||||
return {"", false};
|
||||
if (!is_changed) {
|
||||
return {string(), false};
|
||||
}
|
||||
return {create(first, second), true};
|
||||
}
|
||||
|
||||
private:
|
||||
static Slice invalid_file_reference() {
|
||||
return Slice("#");
|
||||
}
|
||||
|
||||
std::string create(Slice first, Slice second) const {
|
||||
if (size_ == 1) {
|
||||
return create_one(first);
|
||||
}
|
||||
return create_two(first, second);
|
||||
}
|
||||
|
||||
Slice first_;
|
||||
Slice second_;
|
||||
int size_;
|
||||
int size_ = 1;
|
||||
};
|
||||
|
||||
struct EmptyRemoteFileLocation {
|
||||
@ -459,6 +461,7 @@ class FullRemoteFileLocation {
|
||||
CHECK(!is_web());
|
||||
return dc_id_;
|
||||
}
|
||||
|
||||
int64 get_access_hash() const {
|
||||
switch (location_type()) {
|
||||
case LocationType::Photo:
|
||||
@ -473,6 +476,7 @@ class FullRemoteFileLocation {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int64 get_id() const {
|
||||
switch (location_type()) {
|
||||
case LocationType::Photo:
|
||||
@ -486,18 +490,21 @@ class FullRemoteFileLocation {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool delete_file_reference(Slice bad_file_reference) {
|
||||
auto res = FileReferenceView(file_reference_).delete_file_reference(bad_file_reference);
|
||||
if (res.second) {
|
||||
file_reference_ = res.first;
|
||||
} else if (file_reference_ == bad_file_reference) {
|
||||
file_reference_ = FileReferenceView::create_invalid();
|
||||
}
|
||||
return res.second;
|
||||
}
|
||||
bool has_upload_file_reference() const {
|
||||
return FileReferenceView(file_reference_).has_first();
|
||||
return FileReferenceView(file_reference_).has_upload();
|
||||
}
|
||||
bool has_download_file_reference() const {
|
||||
return FileReferenceView(file_reference_).has_second();
|
||||
return FileReferenceView(file_reference_).has_download();
|
||||
}
|
||||
bool has_any_file_reference() const {
|
||||
return has_upload_file_reference() || has_download_file_reference();
|
||||
@ -506,11 +513,12 @@ class FullRemoteFileLocation {
|
||||
return file_reference_;
|
||||
}
|
||||
Slice get_upload_file_reference() const {
|
||||
return FileReferenceView(file_reference_).first();
|
||||
return FileReferenceView(file_reference_).upload();
|
||||
}
|
||||
Slice get_download_file_reference() const {
|
||||
return FileReferenceView(file_reference_).second();
|
||||
return FileReferenceView(file_reference_).download();
|
||||
}
|
||||
|
||||
string get_url() const {
|
||||
if (is_web()) {
|
||||
return web().url_;
|
||||
@ -555,7 +563,7 @@ class FullRemoteFileLocation {
|
||||
case LocationType::Photo:
|
||||
return make_tl_object<telegram_api::inputFileLocation>(
|
||||
photo().volume_id_, photo().local_id_, photo().secret_,
|
||||
BufferSlice(FileReferenceView(file_reference_).second()));
|
||||
BufferSlice(FileReferenceView(file_reference_).download()));
|
||||
case LocationType::Common:
|
||||
if (is_encrypted_secret()) {
|
||||
return make_tl_object<telegram_api::inputEncryptedFileLocation>(common().id_, common().access_hash_);
|
||||
@ -585,7 +593,7 @@ class FullRemoteFileLocation {
|
||||
tl_object_ptr<telegram_api::inputPhoto> as_input_photo_impl(const char *file, int line) const {
|
||||
CHECK(is_photo()) << file << ' ' << line;
|
||||
return make_tl_object<telegram_api::inputPhoto>(photo().id_, photo().access_hash_,
|
||||
BufferSlice(FileReferenceView(file_reference_).first()));
|
||||
BufferSlice(FileReferenceView(file_reference_).upload()));
|
||||
}
|
||||
|
||||
tl_object_ptr<telegram_api::inputEncryptedFile> as_input_encrypted_file() const {
|
||||
@ -609,7 +617,7 @@ class FullRemoteFileLocation {
|
||||
, variant_(PhotoRemoteFileLocation{id, access_hash, volume_id, secret, local_id}) {
|
||||
CHECK(is_photo());
|
||||
FileReferenceView view(file_reference_);
|
||||
if (!view.has_first() || !view.has_second()) {
|
||||
if (!(view.has_upload() && view.has_download())) {
|
||||
LOG(ERROR) << "Tried to register file with invalid file reference";
|
||||
file_reference_.clear();
|
||||
}
|
||||
@ -621,7 +629,7 @@ class FullRemoteFileLocation {
|
||||
, variant_(CommonRemoteFileLocation{id, access_hash}) {
|
||||
CHECK(is_common());
|
||||
FileReferenceView view(file_reference_);
|
||||
if (!view.has_first() || !view.has_second()) {
|
||||
if (!(view.has_upload() && view.has_download())) {
|
||||
LOG(ERROR) << "Tried to register file with invalid file reference";
|
||||
file_reference_.clear();
|
||||
}
|
||||
@ -677,7 +685,7 @@ class FullRemoteFileLocation {
|
||||
}
|
||||
|
||||
static const int32 KEY_MAGIC = 0x64374632;
|
||||
}; // namespace td
|
||||
};
|
||||
|
||||
inline StringBuilder &operator<<(StringBuilder &string_builder,
|
||||
const FullRemoteFileLocation &full_remote_file_location) {
|
||||
|
@ -162,7 +162,11 @@ void FileNode::set_remote_location(const RemoteFileLocation &remote, FileLocatio
|
||||
}
|
||||
|
||||
bool FileNode::delete_file_reference(Slice file_reference) {
|
||||
if (remote_.type() == RemoteFileLocation::Type::Full && remote_.full().delete_file_reference(file_reference)) {
|
||||
if (remote_.type() != RemoteFileLocation::Type::Full) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (remote_.full().delete_file_reference(file_reference)) {
|
||||
VLOG(file_references) << "Do delete file reference of main file " << main_file_id_;
|
||||
upload_was_update_file_reference_ = false;
|
||||
download_was_update_file_reference_ = false;
|
||||
@ -1531,7 +1535,7 @@ void FileManager::flush_to_pmc(FileNodePtr node, bool new_remote, bool new_local
|
||||
data.url_ = node->url_;
|
||||
data.owner_dialog_id_ = node->owner_dialog_id_;
|
||||
data.file_source_ids_ = context_->get_some_file_sources(view.file_id());
|
||||
VLOG(file_references) << "Save " << data.file_source_ids_ << " to database for file " << view.file_id() << " from "
|
||||
VLOG(file_references) << "Save file " << view.file_id() << " to database with " << data.file_source_ids_ << " from "
|
||||
<< source;
|
||||
|
||||
file_db_->set_file_data(node->pmc_id_, data, (create_flag || new_remote), (create_flag || new_local),
|
||||
@ -1950,6 +1954,15 @@ void FileManager::delete_file_reference(FileId file_id, string file_reference) {
|
||||
return;
|
||||
}
|
||||
node->delete_file_reference(file_reference);
|
||||
auto remote = get_remote(file_id.get_remote());
|
||||
if (remote != nullptr) {
|
||||
VLOG(file_references) << "Do delete file reference of remote file " << file_id;
|
||||
if (remote->delete_file_reference(file_reference)) {
|
||||
node->upload_was_update_file_reference_ = false;
|
||||
node->download_was_update_file_reference_ = false;
|
||||
node->on_pmc_changed();
|
||||
}
|
||||
}
|
||||
try_flush_node_pmc(node, "delete_file_reference");
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user