file_download.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "base/binary_guard.h"
  9. #include "base/weak_ptr.h"
  10. #include <QtNetwork/QNetworkReply>
  11. namespace Data {
  12. struct FileOrigin;
  13. } // namespace Data
  14. namespace Main {
  15. class Session;
  16. } // namespace Main
  17. namespace Storage {
  18. namespace Cache {
  19. struct Key;
  20. } // namespace Cache
  21. // 10 MB max file could be hold in memory
  22. // This value is used in local cache database settings!
  23. constexpr auto kMaxFileInMemory = 10 * 1024 * 1024;
  24. // 2 MB stickers hold in memory, auto loaded and displayed inline
  25. constexpr auto kMaxStickerBytesSize = 2 * 1024 * 1024;
  26. // 10 MB GIF and mp4 animations held in memory while playing
  27. constexpr auto kMaxWallPaperInMemory = kMaxFileInMemory;
  28. constexpr auto kMaxAnimationInMemory = kMaxFileInMemory;
  29. // 4096x4096 is max area.
  30. constexpr auto kMaxWallPaperDimension = 4096;
  31. } // namespace Storage
  32. struct StorageImageSaved {
  33. StorageImageSaved() = default;
  34. explicit StorageImageSaved(const QByteArray &data) : data(data) {
  35. }
  36. QByteArray data;
  37. };
  38. class FileLoader : public base::has_weak_ptr {
  39. public:
  40. enum class FailureReason {
  41. NoFailure,
  42. FileWriteFailure,
  43. OtherFailure,
  44. };
  45. struct Error {
  46. FailureReason failureReason = FailureReason::NoFailure;
  47. bool started = false;
  48. };
  49. FileLoader(
  50. not_null<Main::Session*> session,
  51. const QString &toFile,
  52. int64 loadSize,
  53. int64 fullSize,
  54. LocationType locationType,
  55. LoadToCacheSetting toCache,
  56. LoadFromCloudSetting fromCloud,
  57. bool autoLoading,
  58. uint8 cacheTag);
  59. virtual ~FileLoader();
  60. [[nodiscard]] Main::Session &session() const;
  61. [[nodiscard]] bool finished() const {
  62. return _finished;
  63. }
  64. void finishWithBytes(const QByteArray &data);
  65. [[nodiscard]] bool cancelled() const {
  66. return _cancelled;
  67. }
  68. [[nodiscard]] const QByteArray &bytes() const {
  69. return _data;
  70. }
  71. [[nodiscard]] virtual uint64 objId() const {
  72. return 0;
  73. }
  74. [[nodiscard]] QImage imageData(int progressiveSizeLimit = 0) const;
  75. [[nodiscard]] QString fileName() const {
  76. return _filename;
  77. }
  78. // Used in MainWidget::documentLoadFailed.
  79. [[nodiscard]] virtual Data::FileOrigin fileOrigin() const;
  80. [[nodiscard]] float64 currentProgress() const;
  81. [[nodiscard]] virtual int64 currentOffset() const;
  82. [[nodiscard]] int64 fullSize() const {
  83. return _fullSize;
  84. }
  85. [[nodiscard]] int64 loadSize() const {
  86. return _loadSize;
  87. }
  88. bool setFileName(const QString &filename); // set filename for loaders to cache
  89. void permitLoadFromCloud();
  90. void increaseLoadSize(int64 size, bool autoLoading);
  91. void start();
  92. void cancel();
  93. [[nodiscard]] bool loadingLocal() const {
  94. return (_localStatus == LocalStatus::Loading);
  95. }
  96. [[nodiscard]] bool autoLoading() const {
  97. return _autoLoading;
  98. }
  99. void localLoaded(
  100. const StorageImageSaved &result,
  101. const QByteArray &imageFormat,
  102. const QImage &imageData);
  103. [[nodiscard]] rpl::producer<rpl::empty_value, Error> updates() const {
  104. return _updates.events();
  105. }
  106. [[nodiscard]] rpl::lifetime &lifetime() {
  107. return _lifetime;
  108. }
  109. protected:
  110. enum class LocalStatus {
  111. NotTried,
  112. NotFound,
  113. Loading,
  114. Loaded,
  115. };
  116. void readImage(int progressiveSizeLimit) const;
  117. bool checkForOpen();
  118. bool tryLoadLocal();
  119. void loadLocal(const Storage::Cache::Key &key);
  120. virtual Storage::Cache::Key cacheKey() const = 0;
  121. virtual std::optional<MediaKey> fileLocationKey() const = 0;
  122. virtual void cancelHook() = 0;
  123. virtual void startLoading() = 0;
  124. virtual void startLoadingWithPartial(const QByteArray &data) {
  125. startLoading();
  126. }
  127. void cancel(FailureReason failed);
  128. void notifyAboutProgress();
  129. bool writeResultPart(int64 offset, bytes::const_span buffer);
  130. bool finalizeResult();
  131. [[nodiscard]] QByteArray readLoadedPartBack(int64 offset, int size);
  132. const not_null<Main::Session*> _session;
  133. bool _autoLoading = false;
  134. uint8 _cacheTag = 0;
  135. bool _finished = false;
  136. bool _cancelled = false;
  137. mutable LocalStatus _localStatus = LocalStatus::NotTried;
  138. QString _filename;
  139. QFile _file;
  140. bool _fileIsOpen = false;
  141. LoadToCacheSetting _toCache;
  142. LoadFromCloudSetting _fromCloud;
  143. QByteArray _data;
  144. int64 _loadSize = 0;
  145. int64 _fullSize = 0;
  146. int64 _skippedBytes = 0;
  147. LocationType _locationType = LocationType();
  148. base::binary_guard _localLoading;
  149. mutable QByteArray _imageFormat;
  150. mutable QImage _imageData;
  151. rpl::lifetime _lifetime;
  152. rpl::event_stream<rpl::empty_value, Error> _updates;
  153. };
  154. [[nodiscard]] std::unique_ptr<FileLoader> CreateFileLoader(
  155. not_null<Main::Session*> session,
  156. const DownloadLocation &location,
  157. Data::FileOrigin origin,
  158. const QString &toFile,
  159. int64 loadSize,
  160. int64 fullSize,
  161. LocationType locationType,
  162. LoadToCacheSetting toCache,
  163. LoadFromCloudSetting fromCloud,
  164. bool autoLoading,
  165. uint8 cacheTag);