Fixes for delete_file_reference.

GitOrigin-RevId: 15ffa944a037d34954ce5e7b0cea22131e1e976e
This commit is contained in:
levlam 2019-01-31 02:57:14 +03:00
parent 996869d4ca
commit 346202fbaa
5 changed files with 66 additions and 47 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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),

View File

@ -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) {

View File

@ -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");
}