init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
221
Telegram/SourceFiles/storage/file_download_mtproto.cpp
Normal file
221
Telegram/SourceFiles/storage/file_download_mtproto.cpp
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
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
|
||||
*/
|
||||
#include "storage/file_download_mtproto.h"
|
||||
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "storage/cache/storage_cache_types.h"
|
||||
#include "main/main_session.h"
|
||||
#include "apiwrap.h"
|
||||
#include "mtproto/mtp_instance.h"
|
||||
#include "mtproto/mtproto_config.h"
|
||||
#include "mtproto/mtproto_auth_key.h"
|
||||
|
||||
mtpFileLoader::mtpFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const StorageFileLocation &location,
|
||||
Data::FileOrigin origin,
|
||||
LocationType type,
|
||||
const QString &to,
|
||||
int64 loadSize,
|
||||
int64 fullSize,
|
||||
LoadToCacheSetting toCache,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading,
|
||||
uint8 cacheTag)
|
||||
: FileLoader(
|
||||
session,
|
||||
to,
|
||||
loadSize,
|
||||
fullSize,
|
||||
type,
|
||||
toCache,
|
||||
fromCloud,
|
||||
autoLoading,
|
||||
cacheTag)
|
||||
, DownloadMtprotoTask(&session->downloader(), location, origin) {
|
||||
}
|
||||
|
||||
mtpFileLoader::mtpFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const WebFileLocation &location,
|
||||
int64 loadSize,
|
||||
int64 fullSize,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading,
|
||||
uint8 cacheTag)
|
||||
: FileLoader(
|
||||
session,
|
||||
QString(),
|
||||
loadSize,
|
||||
fullSize,
|
||||
UnknownFileLocation,
|
||||
LoadToCacheAsWell,
|
||||
fromCloud,
|
||||
autoLoading,
|
||||
cacheTag)
|
||||
, DownloadMtprotoTask(
|
||||
&session->downloader(),
|
||||
session->serverConfig().webFileDcId,
|
||||
{ location }) {
|
||||
}
|
||||
|
||||
mtpFileLoader::mtpFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const GeoPointLocation &location,
|
||||
int64 loadSize,
|
||||
int64 fullSize,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading,
|
||||
uint8 cacheTag)
|
||||
: FileLoader(
|
||||
session,
|
||||
QString(),
|
||||
loadSize,
|
||||
fullSize,
|
||||
UnknownFileLocation,
|
||||
LoadToCacheAsWell,
|
||||
fromCloud,
|
||||
autoLoading,
|
||||
cacheTag)
|
||||
, DownloadMtprotoTask(
|
||||
&session->downloader(),
|
||||
session->serverConfig().webFileDcId,
|
||||
{ location }) {
|
||||
}
|
||||
|
||||
mtpFileLoader::mtpFileLoader(
|
||||
not_null<Main::Session*> session,
|
||||
const AudioAlbumThumbLocation &location,
|
||||
int64 loadSize,
|
||||
int64 fullSize,
|
||||
LoadFromCloudSetting fromCloud,
|
||||
bool autoLoading,
|
||||
uint8 cacheTag)
|
||||
: FileLoader(
|
||||
session,
|
||||
QString(),
|
||||
loadSize,
|
||||
fullSize,
|
||||
UnknownFileLocation,
|
||||
LoadToCacheAsWell,
|
||||
fromCloud,
|
||||
autoLoading,
|
||||
cacheTag)
|
||||
, DownloadMtprotoTask(
|
||||
&session->downloader(),
|
||||
session->serverConfig().webFileDcId,
|
||||
{ location }) {
|
||||
}
|
||||
|
||||
mtpFileLoader::~mtpFileLoader() {
|
||||
if (!_finished) {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
|
||||
Data::FileOrigin mtpFileLoader::fileOrigin() const {
|
||||
return DownloadMtprotoTask::fileOrigin();
|
||||
}
|
||||
|
||||
uint64 mtpFileLoader::objId() const {
|
||||
return DownloadMtprotoTask::objectId();
|
||||
}
|
||||
|
||||
bool mtpFileLoader::readyToRequest() const {
|
||||
return !_finished
|
||||
&& !_lastComplete
|
||||
&& (_fullSize != 0 || !haveSentRequests())
|
||||
&& (!_fullSize || _nextRequestOffset < _loadSize);
|
||||
}
|
||||
|
||||
int64 mtpFileLoader::takeNextRequestOffset() {
|
||||
Expects(readyToRequest());
|
||||
|
||||
const auto result = _nextRequestOffset;
|
||||
_nextRequestOffset += Storage::kDownloadPartSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool mtpFileLoader::feedPart(int64 offset, const QByteArray &bytes) {
|
||||
const auto buffer = bytes::make_span(bytes);
|
||||
if (!writeResultPart(offset, buffer)) {
|
||||
return false;
|
||||
}
|
||||
if (buffer.empty() || (buffer.size() % 1024)) { // bad next offset
|
||||
_lastComplete = true;
|
||||
}
|
||||
const auto finished = !haveSentRequests()
|
||||
&& (_lastComplete || (_fullSize && _nextRequestOffset >= _loadSize));
|
||||
if (finished) {
|
||||
removeFromQueue();
|
||||
if (!finalizeResult()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
notifyAboutProgress();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void mtpFileLoader::cancelOnFail() {
|
||||
cancel(FailureReason::OtherFailure);
|
||||
}
|
||||
|
||||
bool mtpFileLoader::setWebFileSizeHook(int64 size) {
|
||||
if (!_fullSize || _fullSize == size) {
|
||||
_fullSize = _loadSize = size;
|
||||
return true;
|
||||
}
|
||||
LOG(("MTP Error: "
|
||||
"Bad size provided by bot for webDocument: %1, real: %2"
|
||||
).arg(_fullSize
|
||||
).arg(size));
|
||||
cancel(FailureReason::OtherFailure);
|
||||
return false;
|
||||
}
|
||||
|
||||
void mtpFileLoader::startLoading() {
|
||||
addToQueue();
|
||||
}
|
||||
|
||||
void mtpFileLoader::startLoadingWithPartial(const QByteArray &data) {
|
||||
Expects(data.startsWith("partial:"));
|
||||
|
||||
constexpr auto kPrefix = 8;
|
||||
const auto parts = (data.size() - kPrefix) / Storage::kDownloadPartSize;
|
||||
const auto use = parts * int64(Storage::kDownloadPartSize);
|
||||
if (use > 0) {
|
||||
_nextRequestOffset = use;
|
||||
feedPart(0, QByteArray::fromRawData(data.data() + kPrefix, use));
|
||||
}
|
||||
startLoading();
|
||||
}
|
||||
|
||||
void mtpFileLoader::cancelHook() {
|
||||
cancelAllRequests();
|
||||
}
|
||||
|
||||
Storage::Cache::Key mtpFileLoader::cacheKey() const {
|
||||
return v::match(location().data, [&](const WebFileLocation &location) {
|
||||
return Data::WebDocumentCacheKey(location);
|
||||
}, [&](const GeoPointLocation &location) {
|
||||
return Data::GeoPointCacheKey(location);
|
||||
}, [&](const StorageFileLocation &location) {
|
||||
return location.cacheKey();
|
||||
}, [&](const AudioAlbumThumbLocation &location) {
|
||||
return Data::AudioAlbumThumbCacheKey(location);
|
||||
});
|
||||
}
|
||||
|
||||
std::optional<MediaKey> mtpFileLoader::fileLocationKey() const {
|
||||
if (_locationType != UnknownFileLocation) {
|
||||
return mediaKey(_locationType, dcId(), objId());
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
Reference in New Issue
Block a user