1 // 2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 // 7 #pragma once 8 9 #include "td/telegram/DialogId.h" 10 #include "td/telegram/files/FileDbId.h" 11 #include "td/telegram/files/FileEncryptionKey.h" 12 #include "td/telegram/files/FileGenerateManager.h" 13 #include "td/telegram/files/FileId.h" 14 #include "td/telegram/files/FileLoadManager.h" 15 #include "td/telegram/files/FileLocation.h" 16 #include "td/telegram/files/FileSourceId.h" 17 #include "td/telegram/files/FileType.h" 18 #include "td/telegram/Location.h" 19 #include "td/telegram/PhotoSizeSource.h" 20 #include "td/telegram/td_api.h" 21 #include "td/telegram/telegram_api.h" 22 23 #include "td/actor/actor.h" 24 #include "td/actor/PromiseFuture.h" 25 26 #include "td/utils/buffer.h" 27 #include "td/utils/common.h" 28 #include "td/utils/Container.h" 29 #include "td/utils/Enumerator.h" 30 #include "td/utils/logging.h" 31 #include "td/utils/optional.h" 32 #include "td/utils/Slice.h" 33 #include "td/utils/Status.h" 34 #include "td/utils/StringBuilder.h" 35 36 #include <map> 37 #include <memory> 38 #include <set> 39 #include <unordered_map> 40 #include <unordered_set> 41 #include <utility> 42 43 namespace td { 44 45 extern int VERBOSITY_NAME(update_file); 46 47 class FileData; 48 class FileDbInterface; 49 50 enum class FileLocationSource : int8 { None, FromUser, FromBinlog, FromDatabase, FromServer }; 51 52 struct NewRemoteFileLocation { 53 NewRemoteFileLocation() = default; 54 NewRemoteFileLocation(RemoteFileLocation remote, FileLocationSource source); 55 RemoteFileLocation partial_or_empty() const; 56 unique_ptr<PartialRemoteFileLocation> partial; 57 58 //TODO: use RemoteId 59 // hardest part is to determine whether we should flush this location to db. 60 // probably, will need some generation in RemoteInfo 61 optional<FullRemoteFileLocation> full; 62 bool is_full_alive{false}; // if false, then we may try to upload this file 63 FileLocationSource full_source{FileLocationSource::None}; 64 int64 ready_size = 0; 65 }; 66 67 class FileNode { 68 public: FileNode(LocalFileLocation local,NewRemoteFileLocation remote,unique_ptr<FullGenerateFileLocation> generate,int64 size,int64 expected_size,string remote_name,string url,DialogId owner_dialog_id,FileEncryptionKey key,FileId main_file_id,int8 main_file_id_priority)69 FileNode(LocalFileLocation local, NewRemoteFileLocation remote, unique_ptr<FullGenerateFileLocation> generate, 70 int64 size, int64 expected_size, string remote_name, string url, DialogId owner_dialog_id, 71 FileEncryptionKey key, FileId main_file_id, int8 main_file_id_priority) 72 : local_(std::move(local)) 73 , remote_(std::move(remote)) 74 , generate_(std::move(generate)) 75 , size_(size) 76 , expected_size_(expected_size) 77 , remote_name_(std::move(remote_name)) 78 , url_(std::move(url)) 79 , owner_dialog_id_(owner_dialog_id) 80 , encryption_key_(std::move(key)) 81 , main_file_id_(main_file_id) 82 , main_file_id_priority_(main_file_id_priority) { 83 init_ready_size(); 84 } 85 void drop_local_location(); 86 void set_local_location(const LocalFileLocation &local, int64 ready_size, int64 prefix_offset, 87 int64 ready_prefix_size); 88 void set_new_remote_location(NewRemoteFileLocation remote); 89 void delete_partial_remote_location(); 90 void set_partial_remote_location(PartialRemoteFileLocation remote, int64 ready_size); 91 92 bool delete_file_reference(Slice file_reference); 93 void set_generate_location(unique_ptr<FullGenerateFileLocation> &&generate); 94 void set_size(int64 size); 95 void set_expected_size(int64 expected_size); 96 void set_remote_name(string remote_name); 97 void set_url(string url); 98 void set_owner_dialog_id(DialogId owner_id); 99 void set_encryption_key(FileEncryptionKey key); 100 void set_upload_pause(FileId upload_pause); 101 102 void set_download_priority(int8 priority); 103 void set_upload_priority(int8 priority); 104 void set_generate_priority(int8 download_priority, int8 upload_priority); 105 106 void set_download_offset(int64 download_offset); 107 void set_download_limit(int64 download_limit); 108 109 void on_changed(); 110 void on_info_changed(); 111 void on_pmc_changed(); 112 113 bool need_info_flush() const; 114 bool need_pmc_flush() const; 115 116 void on_pmc_flushed(); 117 void on_info_flushed(); 118 119 string suggested_path() const; 120 121 private: 122 friend class FileView; 123 friend class FileManager; 124 125 static constexpr char PERSISTENT_ID_VERSION_OLD = 2; 126 static constexpr char PERSISTENT_ID_VERSION_MAP = 3; 127 static constexpr char PERSISTENT_ID_VERSION = 4; 128 129 LocalFileLocation local_; 130 FileLoadManager::QueryId upload_id_ = 0; 131 int64 download_offset_ = 0; 132 int64 download_limit_ = 0; 133 int64 local_ready_size_ = 0; // PartialLocal only 134 int64 local_ready_prefix_size_ = 0; // PartialLocal only 135 136 NewRemoteFileLocation remote_; 137 138 FileLoadManager::QueryId download_id_ = 0; 139 140 unique_ptr<FullGenerateFileLocation> generate_; 141 FileLoadManager::QueryId generate_id_ = 0; 142 143 int64 size_ = 0; 144 int64 expected_size_ = 0; 145 string remote_name_; 146 string url_; 147 DialogId owner_dialog_id_; 148 FileEncryptionKey encryption_key_; 149 FileDbId pmc_id_; 150 std::vector<FileId> file_ids_; 151 152 FileId main_file_id_; 153 154 double last_successful_force_reupload_time_ = -1e10; 155 156 FileId upload_pause_; 157 158 int8 upload_priority_ = 0; 159 int8 download_priority_ = 0; 160 int8 generate_priority_ = 0; 161 162 int8 generate_download_priority_ = 0; 163 int8 generate_upload_priority_ = 0; 164 165 int8 main_file_id_priority_ = 0; 166 167 bool is_download_offset_dirty_ = false; 168 bool is_download_limit_dirty_ = false; 169 170 bool get_by_hash_{false}; 171 bool can_search_locally_{true}; 172 bool need_reload_photo_{false}; 173 174 bool is_download_started_ = false; 175 bool generate_was_update_ = false; 176 177 bool need_load_from_pmc_ = false; 178 179 bool pmc_changed_flag_{false}; 180 bool info_changed_flag_{false}; 181 182 bool upload_was_update_file_reference_{false}; 183 bool download_was_update_file_reference_{false}; 184 185 bool upload_prefer_small_{false}; 186 187 void init_ready_size(); 188 189 void recalc_ready_prefix_size(int64 prefix_offset, int64 ready_prefix_size); 190 }; 191 192 class FileManager; 193 194 class FileNodePtr { 195 public: 196 FileNodePtr() = default; FileNodePtr(FileId file_id,FileManager * file_manager)197 FileNodePtr(FileId file_id, FileManager *file_manager) : file_id_(file_id), file_manager_(file_manager) { 198 } 199 200 FileNode *operator->() const; 201 FileNode &operator*() const; 202 FileNode *get() const; 203 FullRemoteFileLocation *get_remote() const; 204 explicit operator bool() const; 205 206 private: 207 FileId file_id_; 208 FileManager *file_manager_ = nullptr; 209 FileNode *get_unsafe() const; 210 }; 211 212 class ConstFileNodePtr { 213 public: 214 ConstFileNodePtr() = default; ConstFileNodePtr(FileNodePtr file_node_ptr)215 ConstFileNodePtr(FileNodePtr file_node_ptr) : file_node_ptr_(file_node_ptr) { 216 } 217 218 const FileNode *operator->() const { 219 return file_node_ptr_.operator->(); 220 } 221 const FileNode &operator*() const { 222 return file_node_ptr_.operator*(); 223 } 224 225 explicit operator bool() const { 226 return static_cast<bool>(file_node_ptr_); 227 } get_remote()228 const FullRemoteFileLocation *get_remote() const { 229 return file_node_ptr_.get_remote(); 230 } 231 232 private: 233 FileNodePtr file_node_ptr_; 234 }; 235 236 class FileView { 237 public: 238 FileView() = default; 239 explicit FileView(ConstFileNodePtr node); 240 241 bool empty() const; 242 243 bool has_local_location() const; 244 const FullLocalFileLocation &local_location() const; 245 bool has_remote_location() const; 246 bool has_alive_remote_location() const; 247 bool has_active_upload_remote_location() const; 248 bool has_active_download_remote_location() const; 249 const FullRemoteFileLocation &remote_location() const; 250 const FullRemoteFileLocation &main_remote_location() const; 251 bool has_generate_location() const; 252 const FullGenerateFileLocation &generate_location() const; 253 254 bool has_url() const; 255 const string &url() const; 256 257 const string &remote_name() const; 258 259 string suggested_path() const; 260 261 DialogId owner_dialog_id() const; 262 263 bool get_by_hash() const; 264 file_id()265 FileId file_id() const { 266 return node_->main_file_id_; 267 } 268 269 int64 size() const; 270 int64 expected_size(bool may_guess = false) const; 271 bool is_downloading() const; 272 int64 download_offset() const; 273 int64 downloaded_prefix(int64 offset) const; 274 int64 local_prefix_size() const; 275 int64 local_total_size() const; 276 bool is_uploading() const; 277 int64 remote_size() const; 278 string path() const; 279 280 int64 get_allocated_local_size() const; 281 282 bool can_download_from_server() const; 283 bool can_generate() const; 284 bool can_delete() const; 285 get_type()286 FileType get_type() const { 287 if (has_local_location()) { 288 return local_location().file_type_; 289 } 290 if (has_remote_location()) { 291 return remote_location().file_type_; 292 } 293 if (has_generate_location()) { 294 return generate_location().file_type_; 295 } 296 return FileType::Temp; 297 } is_encrypted_secret()298 bool is_encrypted_secret() const { 299 return get_type() == FileType::Encrypted; 300 } is_encrypted_secure()301 bool is_encrypted_secure() const { 302 return get_type() == FileType::Secure; 303 } is_secure()304 bool is_secure() const { 305 return get_type() == FileType::Secure || get_type() == FileType::SecureRaw; 306 } is_encrypted_any()307 bool is_encrypted_any() const { 308 return is_encrypted_secret() || is_encrypted_secure(); 309 } is_encrypted()310 bool is_encrypted() const { 311 return is_encrypted_secret() || is_secure(); 312 } encryption_key()313 const FileEncryptionKey &encryption_key() const { 314 return node_->encryption_key_; 315 } 316 may_reload_photo()317 bool may_reload_photo() const { 318 if (!has_remote_location()) { 319 return false; 320 } 321 if (!remote_location().is_photo()) { 322 return false; 323 } 324 auto type = remote_location().get_source().get_type("may_reload_photo"); 325 return type != PhotoSizeSource::Type::Legacy && type != PhotoSizeSource::Type::FullLegacy && 326 type != PhotoSizeSource::Type::Thumbnail; 327 } 328 329 string get_persistent_file_id() const; 330 331 string get_unique_file_id() const; 332 333 private: 334 ConstFileNodePtr node_{}; 335 336 static string get_unique_id(const FullGenerateFileLocation &location); 337 static string get_unique_id(const FullRemoteFileLocation &location); 338 339 static string get_persistent_id(const FullGenerateFileLocation &location); 340 static string get_persistent_id(const FullRemoteFileLocation &location); 341 }; 342 343 class FileManager final : public FileLoadManager::Callback { 344 public: 345 class DownloadCallback { 346 public: 347 DownloadCallback() = default; 348 DownloadCallback(const DownloadCallback &) = delete; 349 DownloadCallback &operator=(const DownloadCallback &) = delete; 350 virtual ~DownloadCallback() = default; on_progress(FileId file_id)351 virtual void on_progress(FileId file_id) { 352 } 353 354 virtual void on_download_ok(FileId file_id) = 0; 355 virtual void on_download_error(FileId file_id, Status error) = 0; 356 }; 357 358 class UploadCallback { 359 public: 360 UploadCallback() = default; 361 UploadCallback(const UploadCallback &) = delete; 362 UploadCallback &operator=(const UploadCallback &) = delete; 363 virtual ~UploadCallback() = default; 364 on_progress(FileId file_id)365 virtual void on_progress(FileId file_id) { 366 } 367 368 // After on_upload_ok all uploads of this file will be paused till merge, delete_partial_remote_location or 369 // explicit upload request with the same file_id. 370 // Also upload may be resumed after some other merges. 371 virtual void on_upload_ok(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file) = 0; 372 virtual void on_upload_encrypted_ok(FileId file_id, tl_object_ptr<telegram_api::InputEncryptedFile> input_file) = 0; 373 virtual void on_upload_secure_ok(FileId file_id, tl_object_ptr<telegram_api::InputSecureFile> input_file) = 0; 374 virtual void on_upload_error(FileId file_id, Status error) = 0; 375 }; 376 377 class Context { 378 public: 379 virtual void on_new_file(int64 size, int64 real_size, int32 cnt) = 0; 380 381 virtual void on_file_updated(FileId size) = 0; 382 383 virtual bool add_file_source(FileId file_id, FileSourceId file_source_id) = 0; 384 385 virtual bool remove_file_source(FileId file_id, FileSourceId file_source_id) = 0; 386 387 virtual void on_merge_files(FileId to_file_id, FileId from_file_id) = 0; 388 389 virtual vector<FileSourceId> get_some_file_sources(FileId file_id) = 0; 390 391 virtual void repair_file_reference(FileId file_id, Promise<Unit> promise) = 0; 392 393 virtual void reload_photo(PhotoSizeSource source, Promise<Unit> promise) = 0; 394 395 virtual ActorShared<> create_reference() = 0; 396 397 Context() = default; 398 Context(const Context &) = delete; 399 Context &operator=(const Context &) = delete; 400 virtual ~Context() = default; 401 }; 402 403 explicit FileManager(unique_ptr<Context> context); 404 FileManager(const FileManager &other) = delete; 405 FileManager &operator=(const FileManager &other) = delete; 406 FileManager(FileManager &&other) = delete; 407 FileManager &operator=(FileManager &&other) = delete; 408 ~FileManager() final; 409 410 static bool are_modification_times_equal(int64 old_mtime, int64 new_mtime); 411 412 void init_actor(); 413 414 FileId dup_file_id(FileId file_id); 415 416 void on_file_unlink(const FullLocalFileLocation &location); 417 418 FileId register_empty(FileType type); 419 Result<FileId> register_local(FullLocalFileLocation location, DialogId owner_dialog_id, int64 size, 420 bool get_by_hash = false, bool force = false, 421 bool skip_file_size_checks = false) TD_WARN_UNUSED_RESULT; 422 FileId register_remote(FullRemoteFileLocation location, FileLocationSource file_location_source, 423 DialogId owner_dialog_id, int64 size, int64 expected_size, 424 string remote_name) TD_WARN_UNUSED_RESULT; 425 Result<FileId> register_generate(FileType file_type, FileLocationSource file_location_source, string original_path, 426 string conversion, DialogId owner_dialog_id, 427 int64 expected_size) TD_WARN_UNUSED_RESULT; 428 429 Result<FileId> merge(FileId x_file_id, FileId y_file_id, bool no_sync = false) TD_WARN_UNUSED_RESULT; 430 431 void add_file_source(FileId file_id, FileSourceId file_source_id); 432 433 void remove_file_source(FileId file_id, FileSourceId file_source_id); 434 435 void change_files_source(FileSourceId file_source_id, const vector<FileId> &old_file_ids, 436 const vector<FileId> &new_file_ids); 437 438 void on_file_reference_repaired(FileId file_id, FileSourceId file_source_id, Result<Unit> &&result, 439 Promise<Unit> &&promise); 440 441 bool set_encryption_key(FileId file_id, FileEncryptionKey key); 442 bool set_content(FileId file_id, BufferSlice bytes); 443 444 void download(FileId file_id, std::shared_ptr<DownloadCallback> callback, int32 new_priority, int64 offset, 445 int64 limit); 446 void upload(FileId file_id, std::shared_ptr<UploadCallback> callback, int32 new_priority, uint64 upload_order); 447 void resume_upload(FileId file_id, std::vector<int> bad_parts, std::shared_ptr<UploadCallback> callback, 448 int32 new_priority, uint64 upload_order, bool force = false, bool prefer_small = false); 449 void cancel_upload(FileId file_id); 450 bool delete_partial_remote_location(FileId file_id); 451 void delete_file_reference(FileId file_id, Slice file_reference); 452 void get_content(FileId file_id, Promise<BufferSlice> promise); 453 454 Result<string> get_suggested_file_name(FileId file_id, const string &directory); 455 456 void read_file_part(FileId file_id, int32 offset, int32 count, int left_tries, 457 Promise<td_api::object_ptr<td_api::filePart>> promise); 458 459 void delete_file(FileId file_id, Promise<Unit> promise, const char *source); 460 461 void external_file_generate_write_part(int64 id, int32 offset, string data, Promise<> promise); 462 void external_file_generate_progress(int64 id, int32 expected_size, int32 local_prefix_size, Promise<> promise); 463 void external_file_generate_finish(int64 id, Status status, Promise<> promise); 464 465 Result<FileId> from_persistent_id(CSlice persistent_id, FileType file_type) TD_WARN_UNUSED_RESULT; 466 FileView get_file_view(FileId file_id) const; 467 FileView get_sync_file_view(FileId file_id); 468 td_api::object_ptr<td_api::file> get_file_object(FileId file_id, bool with_main_file_id = true); 469 vector<int32> get_file_ids_object(const vector<FileId> &file_ids, bool with_main_file_id = true); 470 471 Result<FileId> get_input_thumbnail_file_id(const tl_object_ptr<td_api::InputFile> &thumbnail_input_file, 472 DialogId owner_dialog_id, bool is_encrypted) TD_WARN_UNUSED_RESULT; 473 Result<FileId> get_input_file_id(FileType type, const tl_object_ptr<td_api::InputFile> &file, 474 DialogId owner_dialog_id, bool allow_zero, bool is_encrypted, 475 bool get_by_hash = false, bool is_secure = false) TD_WARN_UNUSED_RESULT; 476 477 Result<FileId> get_map_thumbnail_file_id(Location location, int32 zoom, int32 width, int32 height, int32 scale, 478 DialogId owner_dialog_id) TD_WARN_UNUSED_RESULT; 479 480 FileType guess_file_type(const tl_object_ptr<td_api::InputFile> &file); 481 482 vector<tl_object_ptr<telegram_api::InputDocument>> get_input_documents(const vector<FileId> &file_ids); 483 484 static bool extract_was_uploaded(const tl_object_ptr<telegram_api::InputMedia> &input_media); 485 static bool extract_was_thumbnail_uploaded(const tl_object_ptr<telegram_api::InputMedia> &input_media); 486 static string extract_file_reference(const tl_object_ptr<telegram_api::InputMedia> &input_media); 487 488 static string extract_file_reference(const tl_object_ptr<telegram_api::InputDocument> &input_document); 489 490 static string extract_file_reference(const tl_object_ptr<telegram_api::InputPhoto> &input_photo); 491 492 static bool extract_was_uploaded(const tl_object_ptr<telegram_api::InputChatPhoto> &input_chat_photo); 493 static string extract_file_reference(const tl_object_ptr<telegram_api::InputChatPhoto> &input_chat_photo); 494 495 template <class StorerT> 496 void store_file(FileId file_id, StorerT &storer, int32 ttl = 5) const; 497 498 template <class ParserT> 499 FileId parse_file(ParserT &parser); 500 501 private: 502 Result<FileId> check_input_file_id(FileType type, Result<FileId> result, bool is_encrypted, bool allow_zero, 503 bool is_secure) TD_WARN_UNUSED_RESULT; 504 505 FileId register_url(string url, FileType file_type, FileLocationSource file_location_source, 506 DialogId owner_dialog_id); 507 Result<FileId> register_file(FileData &&data, FileLocationSource file_location_source, const char *source, bool force, 508 bool skip_file_size_checks = false); 509 510 static constexpr int8 FROM_BYTES_PRIORITY = 10; 511 512 using FileNodeId = int32; 513 514 using QueryId = FileLoadManager::QueryId; 515 class Query { 516 public: 517 FileId file_id_; 518 enum class Type : int32 { 519 UploadByHash, 520 UploadWaitFileReference, 521 Upload, 522 DownloadWaitFileReference, 523 DownloadReloadDialog, 524 Download, 525 SetContent, 526 Generate 527 } type_; 528 }; 529 530 friend StringBuilder &operator<<(StringBuilder &string_builder, Query::Type type); 531 532 struct FileIdInfo { 533 FileNodeId node_id_{0}; 534 bool send_updates_flag_{false}; 535 bool pin_flag_{false}; 536 bool sent_file_id_flag_{false}; 537 538 int8 download_priority_{0}; 539 int8 upload_priority_{0}; 540 541 uint64 upload_order_{0}; 542 543 std::shared_ptr<DownloadCallback> download_callback_; 544 std::shared_ptr<UploadCallback> upload_callback_; 545 }; 546 547 class ForceUploadActor; 548 549 ActorShared<> parent_; 550 unique_ptr<Context> context_; 551 std::shared_ptr<FileDbInterface> file_db_; 552 553 FileIdInfo *get_file_id_info(FileId file_id); 554 555 struct RemoteInfo { 556 // mutable is set to to enable changing of access hash 557 mutable FullRemoteFileLocation remote_; 558 mutable FileLocationSource file_location_source_; 559 FileId file_id_; 560 bool operator==(const RemoteInfo &other) const { 561 return remote_ == other.remote_; 562 } 563 bool operator<(const RemoteInfo &other) const { 564 return remote_ < other.remote_; 565 } 566 }; 567 Enumerator<RemoteInfo> remote_location_info_; 568 569 std::unordered_map<string, FileId> file_hash_to_file_id_; 570 571 std::map<FullLocalFileLocation, FileId> local_location_to_file_id_; 572 std::map<FullGenerateFileLocation, FileId> generate_location_to_file_id_; 573 std::map<FileDbId, int32> pmc_id_to_file_node_id_; 574 575 vector<FileIdInfo> file_id_info_; 576 vector<int32> empty_file_ids_; 577 vector<unique_ptr<FileNode>> file_nodes_; 578 ActorOwn<FileLoadManager> file_load_manager_; 579 ActorOwn<FileGenerateManager> file_generate_manager_; 580 581 Container<Query> queries_container_; 582 583 bool is_closed_ = false; 584 585 std::set<std::string> bad_paths_; 586 587 FileId next_file_id(); 588 FileNodeId next_file_node_id(); 589 int32 next_pmc_file_id(); 590 FileId create_file_id(int32 file_node_id, FileNode *file_node); 591 void try_forget_file_id(FileId file_id); 592 593 void load_from_pmc(FileId file_id, FullLocalFileLocation full_local); 594 void load_from_pmc(FileId file_id, const FullRemoteFileLocation &full_remote); 595 void load_from_pmc(FileId file_id, const FullGenerateFileLocation &full_generate); 596 template <class LocationT> 597 void load_from_pmc_impl(FileId file_id, const LocationT &location); 598 void load_from_pmc_result(FileId file_id, Result<FileData> &&result); 599 FileId register_pmc_file_data(FileData &&data); 600 601 Status check_local_location(FileNodePtr node); 602 static bool try_fix_partial_local_location(FileNodePtr node); 603 Status check_local_location(FullLocalFileLocation &location, int64 &size, bool skip_file_size_checks); 604 void try_flush_node_full(FileNodePtr node, bool new_remote, bool new_local, bool new_generate, FileDbId other_pmc_id); 605 void try_flush_node(FileNodePtr node, const char *source); 606 void try_flush_node_info(FileNodePtr node, const char *source); 607 void try_flush_node_pmc(FileNodePtr node, const char *source); 608 void clear_from_pmc(FileNodePtr node); 609 void flush_to_pmc(FileNodePtr node, bool new_remote, bool new_local, bool new_generate, const char *source); 610 void load_from_pmc(FileNodePtr node, bool new_remote, bool new_local, bool new_generate); 611 612 Result<FileId> from_persistent_id_map(Slice binary, FileType file_type); 613 Result<FileId> from_persistent_id_v2(Slice binary, FileType file_type); 614 Result<FileId> from_persistent_id_v3(Slice binary, FileType file_type); 615 Result<FileId> from_persistent_id_v23(Slice binary, FileType file_type, int32 version); 616 617 static string fix_file_extension(Slice file_name, Slice file_type, Slice file_extension); 618 string get_file_name(FileType file_type, Slice path); 619 get_file_node(FileId file_id)620 ConstFileNodePtr get_file_node(FileId file_id) const { 621 return ConstFileNodePtr{FileNodePtr{file_id, const_cast<FileManager *>(this)}}; 622 } get_file_node(FileId file_id)623 FileNodePtr get_file_node(FileId file_id) { 624 return FileNodePtr{file_id, this}; 625 } 626 FileNode *get_file_node_raw(FileId file_id, FileNodeId *file_node_id = nullptr); 627 628 FileNodePtr get_sync_file_node(FileId file_id); 629 630 void on_force_reupload_success(FileId file_id); 631 632 // void release_file_node(FileNodeId id); 633 void do_cancel_download(FileNodePtr node); 634 void do_cancel_upload(FileNodePtr node); 635 void do_cancel_generate(FileNodePtr node); 636 void run_upload(FileNodePtr node, std::vector<int> bad_parts); 637 void run_download(FileNodePtr node, bool force_update_priority); 638 void run_generate(FileNodePtr node); 639 640 void on_start_download(QueryId query_id) final; 641 void on_partial_download(QueryId query_id, PartialLocalFileLocation partial_local, int64 ready_size, 642 int64 size) final; 643 void on_hash(QueryId query_id, string hash) final; 644 void on_partial_upload(QueryId query_id, PartialRemoteFileLocation partial_remote, int64 ready_size) final; 645 void on_download_ok(QueryId query_id, FullLocalFileLocation local, int64 size, bool is_new) final; 646 void on_upload_ok(QueryId query_id, FileType file_type, PartialRemoteFileLocation partial_remote, int64 size) final; 647 void on_upload_full_ok(QueryId query_id, FullRemoteFileLocation remote) final; 648 void on_error(QueryId query_id, Status status) final; 649 650 void on_error_impl(FileNodePtr node, Query::Type type, bool was_active, Status status); 651 652 void on_partial_generate(QueryId, PartialLocalFileLocation partial_local, int32 expected_size); 653 void on_generate_ok(QueryId, FullLocalFileLocation local); 654 655 std::pair<Query, bool> finish_query(QueryId query_id); 656 657 FullRemoteFileLocation *get_remote(int32 key); 658 659 std::unordered_set<FileId, FileIdHash> get_main_file_ids(const vector<FileId> &file_ids); 660 661 void hangup() final; 662 void tear_down() final; 663 664 friend class FileNodePtr; 665 }; 666 667 } // namespace td 668