2014-05-30 08:53:19 +00:00
|
|
|
/*
|
|
|
|
This file is part of Telegram Desktop,
|
2018-01-03 10:23:14 +00:00
|
|
|
the official desktop application for the Telegram messaging service.
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2018-01-03 10:23:14 +00:00
|
|
|
For license and copyright information please follow this link:
|
|
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
2014-05-30 08:53:19 +00:00
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
|
2017-04-06 14:38:10 +00:00
|
|
|
#include "base/observer.h"
|
2019-01-21 13:42:21 +00:00
|
|
|
#include "base/timer.h"
|
2018-08-27 11:35:58 +00:00
|
|
|
#include "base/binary_guard.h"
|
2020-04-10 11:17:10 +00:00
|
|
|
#include "base/weak_ptr.h"
|
2016-05-25 17:59:21 +00:00
|
|
|
|
2019-09-04 07:19:15 +00:00
|
|
|
#include <QtNetwork/QNetworkReply>
|
|
|
|
|
2019-12-05 08:32:33 +00:00
|
|
|
namespace Data {
|
|
|
|
struct FileOrigin;
|
|
|
|
} // namespace Data
|
2019-07-24 11:45:24 +00:00
|
|
|
|
|
|
|
namespace Main {
|
|
|
|
class Session;
|
|
|
|
} // namespace Main
|
2019-04-12 10:50:41 +00:00
|
|
|
|
2017-03-04 19:36:59 +00:00
|
|
|
namespace Storage {
|
2018-08-27 11:35:58 +00:00
|
|
|
namespace Cache {
|
|
|
|
struct Key;
|
|
|
|
} // namespace Cache
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2019-12-05 08:32:33 +00:00
|
|
|
// 10 MB max file could be hold in memory
|
2019-06-27 16:57:32 +00:00
|
|
|
// This value is used in local cache database settings!
|
2019-12-05 08:32:33 +00:00
|
|
|
constexpr auto kMaxFileInMemory = 10 * 1024 * 1024;
|
2019-06-27 16:57:32 +00:00
|
|
|
|
2019-12-05 08:32:33 +00:00
|
|
|
// 2 MB stickers hold in memory, auto loaded and displayed inline
|
2020-04-09 12:27:53 +00:00
|
|
|
constexpr auto kMaxStickerBytesSize = 2 * 1024 * 1024;
|
2019-12-02 07:28:33 +00:00
|
|
|
|
2019-12-05 08:32:33 +00:00
|
|
|
// 10 MB GIF and mp4 animations held in memory while playing
|
|
|
|
constexpr auto kMaxWallPaperInMemory = kMaxFileInMemory;
|
|
|
|
constexpr auto kMaxAnimationInMemory = kMaxFileInMemory;
|
2019-04-11 07:59:18 +00:00
|
|
|
|
2019-12-05 08:32:33 +00:00
|
|
|
// 4096x4096 is max area.
|
|
|
|
constexpr auto kMaxWallPaperDimension = 4096;
|
2015-09-29 15:29:21 +00:00
|
|
|
|
2017-03-04 19:36:59 +00:00
|
|
|
} // namespace Storage
|
|
|
|
|
2015-09-29 18:44:31 +00:00
|
|
|
struct StorageImageSaved {
|
2017-03-04 11:28:21 +00:00
|
|
|
StorageImageSaved() = default;
|
|
|
|
explicit StorageImageSaved(const QByteArray &data) : data(data) {
|
2015-09-29 18:44:31 +00:00
|
|
|
}
|
2017-03-04 11:28:21 +00:00
|
|
|
|
2015-09-29 18:44:31 +00:00
|
|
|
QByteArray data;
|
2017-03-04 11:28:21 +00:00
|
|
|
|
2015-09-29 18:44:31 +00:00
|
|
|
};
|
|
|
|
|
2020-04-10 11:17:10 +00:00
|
|
|
class FileLoader : public base::has_weak_ptr {
|
2014-05-30 08:53:19 +00:00
|
|
|
public:
|
2018-08-28 21:09:55 +00:00
|
|
|
FileLoader(
|
2020-06-08 15:17:33 +00:00
|
|
|
not_null<Main::Session*> session,
|
2018-08-28 21:09:55 +00:00
|
|
|
const QString &toFile,
|
2022-05-10 14:22:28 +00:00
|
|
|
int64 loadSize,
|
|
|
|
int64 fullSize,
|
2018-08-28 21:09:55 +00:00
|
|
|
LocationType locationType,
|
|
|
|
LoadToCacheSetting toCache,
|
|
|
|
LoadFromCloudSetting fromCloud,
|
|
|
|
bool autoLoading,
|
|
|
|
uint8 cacheTag);
|
2019-12-05 08:32:33 +00:00
|
|
|
virtual ~FileLoader();
|
2018-08-28 21:09:55 +00:00
|
|
|
|
2019-12-05 08:32:33 +00:00
|
|
|
[[nodiscard]] Main::Session &session() const;
|
2019-06-17 11:54:00 +00:00
|
|
|
|
2020-05-25 14:16:04 +00:00
|
|
|
[[nodiscard]] bool finished() const {
|
2017-03-04 11:28:21 +00:00
|
|
|
return _finished;
|
2015-09-29 18:44:31 +00:00
|
|
|
}
|
2018-10-12 16:41:51 +00:00
|
|
|
void finishWithBytes(const QByteArray &data);
|
2020-05-25 14:16:04 +00:00
|
|
|
[[nodiscard]] bool cancelled() const {
|
2017-03-04 11:28:21 +00:00
|
|
|
return _cancelled;
|
2015-09-29 18:44:31 +00:00
|
|
|
}
|
2020-05-25 14:16:04 +00:00
|
|
|
[[nodiscard]] const QByteArray &bytes() const {
|
2015-12-24 19:26:28 +00:00
|
|
|
return _data;
|
2015-09-29 18:44:31 +00:00
|
|
|
}
|
2020-05-25 14:16:04 +00:00
|
|
|
[[nodiscard]] virtual uint64 objId() const {
|
2017-03-03 16:59:57 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2020-08-25 18:03:41 +00:00
|
|
|
[[nodiscard]] QImage imageData(int progressiveSizeLimit = 0) const;
|
2020-05-25 14:16:04 +00:00
|
|
|
[[nodiscard]] QString fileName() const {
|
2017-08-15 15:59:40 +00:00
|
|
|
return _filename;
|
2015-09-29 18:44:31 +00:00
|
|
|
}
|
2019-12-05 08:32:33 +00:00
|
|
|
// Used in MainWidget::documentLoadFailed.
|
|
|
|
[[nodiscard]] virtual Data::FileOrigin fileOrigin() const;
|
2020-05-25 14:16:04 +00:00
|
|
|
[[nodiscard]] float64 currentProgress() const;
|
2022-05-10 14:22:28 +00:00
|
|
|
[[nodiscard]] virtual int64 currentOffset() const;
|
|
|
|
[[nodiscard]] int64 fullSize() const {
|
2020-08-26 13:28:56 +00:00
|
|
|
return _fullSize;
|
|
|
|
}
|
2022-05-10 14:22:28 +00:00
|
|
|
[[nodiscard]] int64 loadSize() const {
|
2020-08-26 13:28:56 +00:00
|
|
|
return _loadSize;
|
|
|
|
}
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2015-12-24 19:26:28 +00:00
|
|
|
bool setFileName(const QString &filename); // set filename for loaders to cache
|
|
|
|
void permitLoadFromCloud();
|
2022-05-10 14:22:28 +00:00
|
|
|
void increaseLoadSize(int64 size, bool autoLoading);
|
2014-09-04 07:33:44 +00:00
|
|
|
|
2019-04-12 11:52:39 +00:00
|
|
|
void start();
|
2014-05-30 08:53:19 +00:00
|
|
|
void cancel();
|
2015-12-23 19:23:14 +00:00
|
|
|
|
2020-05-25 14:16:04 +00:00
|
|
|
[[nodiscard]] bool loadingLocal() const {
|
2018-08-27 11:35:58 +00:00
|
|
|
return (_localStatus == LocalStatus::Loading);
|
2015-12-23 19:23:14 +00:00
|
|
|
}
|
2020-05-25 14:16:04 +00:00
|
|
|
[[nodiscard]] bool autoLoading() const {
|
2015-12-24 19:26:28 +00:00
|
|
|
return _autoLoading;
|
|
|
|
}
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2018-08-27 11:35:58 +00:00
|
|
|
void localLoaded(
|
|
|
|
const StorageImageSaved &result,
|
2018-10-12 16:41:51 +00:00
|
|
|
const QByteArray &imageFormat,
|
|
|
|
const QImage &imageData);
|
2015-09-29 18:44:31 +00:00
|
|
|
|
2020-04-10 11:17:10 +00:00
|
|
|
[[nodiscard]] rpl::producer<rpl::empty_value, bool> updates() const {
|
|
|
|
return _updates.events();
|
|
|
|
}
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2020-05-25 14:16:04 +00:00
|
|
|
[[nodiscard]] rpl::lifetime &lifetime() {
|
2020-05-21 12:49:47 +00:00
|
|
|
return _lifetime;
|
|
|
|
}
|
|
|
|
|
2015-12-30 19:09:20 +00:00
|
|
|
protected:
|
2018-08-27 11:35:58 +00:00
|
|
|
enum class LocalStatus {
|
|
|
|
NotTried,
|
|
|
|
NotFound,
|
|
|
|
Loading,
|
|
|
|
Loaded,
|
|
|
|
};
|
|
|
|
|
2020-08-25 18:03:41 +00:00
|
|
|
void readImage(int progressiveSizeLimit) const;
|
2015-12-30 19:09:20 +00:00
|
|
|
|
2020-08-25 18:03:41 +00:00
|
|
|
bool checkForOpen();
|
2018-08-27 11:35:58 +00:00
|
|
|
bool tryLoadLocal();
|
|
|
|
void loadLocal(const Storage::Cache::Key &key);
|
2019-04-12 07:34:39 +00:00
|
|
|
virtual Storage::Cache::Key cacheKey() const = 0;
|
2019-04-11 07:59:18 +00:00
|
|
|
virtual std::optional<MediaKey> fileLocationKey() const = 0;
|
2019-12-05 08:32:33 +00:00
|
|
|
virtual void cancelHook() = 0;
|
2019-12-04 12:15:58 +00:00
|
|
|
virtual void startLoading() = 0;
|
2020-08-26 13:28:56 +00:00
|
|
|
virtual void startLoadingWithPartial(const QByteArray &data) {
|
2020-08-25 18:03:41 +00:00
|
|
|
startLoading();
|
|
|
|
}
|
2018-08-27 11:35:58 +00:00
|
|
|
|
|
|
|
void cancel(bool failed);
|
|
|
|
|
2018-11-23 14:39:14 +00:00
|
|
|
void notifyAboutProgress();
|
2018-08-27 11:35:58 +00:00
|
|
|
|
2022-05-10 14:22:28 +00:00
|
|
|
bool writeResultPart(int64 offset, bytes::const_span buffer);
|
2019-04-11 07:59:18 +00:00
|
|
|
bool finalizeResult();
|
2022-05-10 14:22:28 +00:00
|
|
|
[[nodiscard]] QByteArray readLoadedPartBack(int64 offset, int size);
|
2019-04-11 07:59:18 +00:00
|
|
|
|
2019-12-04 12:15:58 +00:00
|
|
|
const not_null<Main::Session*> _session;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2016-10-12 19:34:25 +00:00
|
|
|
bool _autoLoading = false;
|
2018-08-28 21:09:55 +00:00
|
|
|
uint8 _cacheTag = 0;
|
2017-03-04 11:28:21 +00:00
|
|
|
bool _finished = false;
|
|
|
|
bool _cancelled = false;
|
2018-08-27 11:35:58 +00:00
|
|
|
mutable LocalStatus _localStatus = LocalStatus::NotTried;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2017-08-15 15:59:40 +00:00
|
|
|
QString _filename;
|
2015-12-24 19:26:28 +00:00
|
|
|
QFile _file;
|
2016-10-12 19:34:25 +00:00
|
|
|
bool _fileIsOpen = false;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2015-12-24 19:26:28 +00:00
|
|
|
LoadToCacheSetting _toCache;
|
|
|
|
LoadFromCloudSetting _fromCloud;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2015-12-24 19:26:28 +00:00
|
|
|
QByteArray _data;
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2022-05-10 14:22:28 +00:00
|
|
|
int64 _loadSize = 0;
|
|
|
|
int64 _fullSize = 0;
|
|
|
|
int64 _skippedBytes = 0;
|
2019-04-10 11:26:15 +00:00
|
|
|
LocationType _locationType = LocationType();
|
2014-05-30 08:53:19 +00:00
|
|
|
|
2018-08-27 11:35:58 +00:00
|
|
|
base::binary_guard _localLoading;
|
2015-09-29 18:44:31 +00:00
|
|
|
mutable QByteArray _imageFormat;
|
2018-10-12 16:41:51 +00:00
|
|
|
mutable QImage _imageData;
|
2015-09-29 18:44:31 +00:00
|
|
|
|
2020-05-21 12:49:47 +00:00
|
|
|
rpl::lifetime _lifetime;
|
|
|
|
rpl::event_stream<rpl::empty_value, bool> _updates;
|
|
|
|
|
2014-05-30 08:53:19 +00:00
|
|
|
};
|
2020-04-16 12:37:26 +00:00
|
|
|
|
|
|
|
[[nodiscard]] std::unique_ptr<FileLoader> CreateFileLoader(
|
2020-06-08 15:17:33 +00:00
|
|
|
not_null<Main::Session*> session,
|
2020-04-16 12:37:26 +00:00
|
|
|
const DownloadLocation &location,
|
|
|
|
Data::FileOrigin origin,
|
|
|
|
const QString &toFile,
|
2022-05-10 14:22:28 +00:00
|
|
|
int64 loadSize,
|
|
|
|
int64 fullSize,
|
2020-04-16 12:37:26 +00:00
|
|
|
LocationType locationType,
|
|
|
|
LoadToCacheSetting toCache,
|
|
|
|
LoadFromCloudSetting fromCloud,
|
|
|
|
bool autoLoading,
|
|
|
|
uint8 cacheTag);
|