| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- /*
- This file is part of Telegram Desktop,
- the official desktop application for the Telegram messaging service.
- For license and copyright information please follow this link:
- https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
- */
- #pragma once
- #include "base/binary_guard.h"
- #include "base/weak_ptr.h"
- #include <QtNetwork/QNetworkReply>
- namespace Data {
- struct FileOrigin;
- } // namespace Data
- namespace Main {
- class Session;
- } // namespace Main
- namespace Storage {
- namespace Cache {
- struct Key;
- } // namespace Cache
- // 10 MB max file could be hold in memory
- // This value is used in local cache database settings!
- constexpr auto kMaxFileInMemory = 10 * 1024 * 1024;
- // 2 MB stickers hold in memory, auto loaded and displayed inline
- constexpr auto kMaxStickerBytesSize = 2 * 1024 * 1024;
- // 10 MB GIF and mp4 animations held in memory while playing
- constexpr auto kMaxWallPaperInMemory = kMaxFileInMemory;
- constexpr auto kMaxAnimationInMemory = kMaxFileInMemory;
- // 4096x4096 is max area.
- constexpr auto kMaxWallPaperDimension = 4096;
- } // namespace Storage
- struct StorageImageSaved {
- StorageImageSaved() = default;
- explicit StorageImageSaved(const QByteArray &data) : data(data) {
- }
- QByteArray data;
- };
- class FileLoader : public base::has_weak_ptr {
- public:
- enum class FailureReason {
- NoFailure,
- FileWriteFailure,
- OtherFailure,
- };
- struct Error {
- FailureReason failureReason = FailureReason::NoFailure;
- bool started = false;
- };
- FileLoader(
- not_null<Main::Session*> session,
- const QString &toFile,
- int64 loadSize,
- int64 fullSize,
- LocationType locationType,
- LoadToCacheSetting toCache,
- LoadFromCloudSetting fromCloud,
- bool autoLoading,
- uint8 cacheTag);
- virtual ~FileLoader();
- [[nodiscard]] Main::Session &session() const;
- [[nodiscard]] bool finished() const {
- return _finished;
- }
- void finishWithBytes(const QByteArray &data);
- [[nodiscard]] bool cancelled() const {
- return _cancelled;
- }
- [[nodiscard]] const QByteArray &bytes() const {
- return _data;
- }
- [[nodiscard]] virtual uint64 objId() const {
- return 0;
- }
- [[nodiscard]] QImage imageData(int progressiveSizeLimit = 0) const;
- [[nodiscard]] QString fileName() const {
- return _filename;
- }
- // Used in MainWidget::documentLoadFailed.
- [[nodiscard]] virtual Data::FileOrigin fileOrigin() const;
- [[nodiscard]] float64 currentProgress() const;
- [[nodiscard]] virtual int64 currentOffset() const;
- [[nodiscard]] int64 fullSize() const {
- return _fullSize;
- }
- [[nodiscard]] int64 loadSize() const {
- return _loadSize;
- }
- bool setFileName(const QString &filename); // set filename for loaders to cache
- void permitLoadFromCloud();
- void increaseLoadSize(int64 size, bool autoLoading);
- void start();
- void cancel();
- [[nodiscard]] bool loadingLocal() const {
- return (_localStatus == LocalStatus::Loading);
- }
- [[nodiscard]] bool autoLoading() const {
- return _autoLoading;
- }
- void localLoaded(
- const StorageImageSaved &result,
- const QByteArray &imageFormat,
- const QImage &imageData);
- [[nodiscard]] rpl::producer<rpl::empty_value, Error> updates() const {
- return _updates.events();
- }
- [[nodiscard]] rpl::lifetime &lifetime() {
- return _lifetime;
- }
- protected:
- enum class LocalStatus {
- NotTried,
- NotFound,
- Loading,
- Loaded,
- };
- void readImage(int progressiveSizeLimit) const;
- bool checkForOpen();
- bool tryLoadLocal();
- void loadLocal(const Storage::Cache::Key &key);
- virtual Storage::Cache::Key cacheKey() const = 0;
- virtual std::optional<MediaKey> fileLocationKey() const = 0;
- virtual void cancelHook() = 0;
- virtual void startLoading() = 0;
- virtual void startLoadingWithPartial(const QByteArray &data) {
- startLoading();
- }
- void cancel(FailureReason failed);
- void notifyAboutProgress();
- bool writeResultPart(int64 offset, bytes::const_span buffer);
- bool finalizeResult();
- [[nodiscard]] QByteArray readLoadedPartBack(int64 offset, int size);
- const not_null<Main::Session*> _session;
- bool _autoLoading = false;
- uint8 _cacheTag = 0;
- bool _finished = false;
- bool _cancelled = false;
- mutable LocalStatus _localStatus = LocalStatus::NotTried;
- QString _filename;
- QFile _file;
- bool _fileIsOpen = false;
- LoadToCacheSetting _toCache;
- LoadFromCloudSetting _fromCloud;
- QByteArray _data;
- int64 _loadSize = 0;
- int64 _fullSize = 0;
- int64 _skippedBytes = 0;
- LocationType _locationType = LocationType();
- base::binary_guard _localLoading;
- mutable QByteArray _imageFormat;
- mutable QImage _imageData;
- rpl::lifetime _lifetime;
- rpl::event_stream<rpl::empty_value, Error> _updates;
- };
- [[nodiscard]] std::unique_ptr<FileLoader> CreateFileLoader(
- not_null<Main::Session*> session,
- const DownloadLocation &location,
- Data::FileOrigin origin,
- const QString &toFile,
- int64 loadSize,
- int64 fullSize,
- LocationType locationType,
- LoadToCacheSetting toCache,
- LoadFromCloudSetting fromCloud,
- bool autoLoading,
- uint8 cacheTag);
|