void mtpFileLoader::localLoaded(const StorageImageSaved &result, const QByteArray &imageFormat, const QPixmap &imagePixmap) { _localTaskId = 0; if (result.type == StorageFileUnknown) { _localStatus = LocalFailed; start(true); return; } data = result.data; type = mtpFromStorageType(result.type); if (!imagePixmap.isNull()) { _imageFormat = imageFormat; _imagePixmap = imagePixmap; } _localStatus = LocalLoaded; if (!fname.isEmpty() && duplicateInData) { if (!fileIsOpen) fileIsOpen = file.open(QIODevice::WriteOnly); if (!fileIsOpen) { finishFail(); return; } if (file.write(data) != qint64(data.size())) { finishFail(); return; } } complete = true; if (fileIsOpen) { file.close(); fileIsOpen = false; psPostprocessFile(QFileInfo(file).absoluteFilePath()); } emit App::wnd()->imageLoaded(); emit progress(this); loadNext(); }
bool mtpFileLoader::tryLoadLocal() { if (_localStatus == LocalNotFound || _localStatus == LocalLoaded || _localStatus == LocalFailed) { return false; } if (_localStatus == LocalLoading) { return true; } if (_locationType == UnknownFileLocation) { _localTaskId = Local::startImageLoad(storageKey(dc, volume, local), this); if (_localTaskId) { _localStatus = LocalLoading; return true; } } else { if (duplicateInData) { MediaKey mkey = mediaKey(_locationType, dc, id); if (_locationType == DocumentFileLocation) { _localTaskId = Local::startStickerImageLoad(mkey, this); } else if (_locationType == AudioFileLocation) { _localTaskId = Local::startAudioLoad(mkey, this); } } } if (data.isEmpty()) { _localStatus = LocalNotFound; return false; } _localStatus = LocalLoaded; if (!fname.isEmpty() && duplicateInData) { if (!fileIsOpen) fileIsOpen = file.open(QIODevice::WriteOnly); if (!fileIsOpen) { finishFail(); return true; } if (file.write(data) != qint64(data.size())) { finishFail(); return true; } } complete = true; if (fileIsOpen) { file.close(); fileIsOpen = false; psPostprocessFile(QFileInfo(file).absoluteFilePath()); } emit App::wnd()->imageLoaded(); emit progress(this); loadNext(); return true; }
void mtpFileLoader::partLoaded(int32 offset, const MTPupload_File &result) { if (requestId) { --queue->queries; requestId = 0; } if (offset == currentOffset()) { int32 limit = locationType ? DocumentDownloadPartSize : DownloadPartSize; const MTPDupload_file &d(result.c_upload_file()); const string &bytes(d.vbytes.c_string().v); if (bytes.size()) { if (file.isOpen()) { if (file.write(bytes.data(), bytes.size()) != qint64(bytes.size())) { return finishFail(); } } else { data.append(bytes.data(), bytes.size()); } } if (bytes.size() && !(bytes.size() % 1024)) { // good next offset // offset += bytes.size(); } else { type = d.vtype; complete = true; if (file.isOpen()) { file.close(); psPostprocessFile(QFileInfo(file).absoluteFilePath()); } removeFromQueue(); App::wnd()->update(); App::wnd()->psUpdateNotifies(); } emit progress(this); } loadNext(); }
bool mtpFileLoader::loadPart() { if (complete || lastComplete || (!requests.isEmpty() && !size)) return false; if (size && nextRequestOffset >= size) return false; int32 limit = DocumentDownloadPartSize; MTPInputFileLocation loc; switch (_locationType) { case UnknownFileLocation: loc = MTP_inputFileLocation(MTP_long(volume), MTP_int(local), MTP_long(secret)); limit = DownloadPartSize; break; case VideoFileLocation: loc = MTP_inputVideoFileLocation(MTP_long(id), MTP_long(access)); break; case AudioFileLocation: loc = MTP_inputAudioFileLocation(MTP_long(id), MTP_long(access)); break; case DocumentFileLocation: loc = MTP_inputDocumentFileLocation(MTP_long(id), MTP_long(access)); break; default: finishFail(); return false; break; } int32 offset = nextRequestOffset, dcIndex = 0; DataRequested &dr(_dataRequested[dc]); if (size) { for (int32 i = 1; i < MTPDownloadSessionsCount; ++i) { if (dr.v[i] < dr.v[dcIndex]) { dcIndex = i; } } } App::app()->killDownloadSessionsStop(dc); mtpRequestId reqId = MTP::send(MTPupload_GetFile(MTPupload_getFile(loc, MTP_int(offset), MTP_int(limit))), rpcDone(&mtpFileLoader::partLoaded, offset), rpcFail(&mtpFileLoader::partFailed), MTP::dld[dcIndex] + dc, 50); ++queue->queries; dr.v[dcIndex] += limit; requests.insert(reqId, dcIndex); nextRequestOffset += limit; return true; }
bool mtpFileLoader::loadPart() { if (complete || requestId) return false; int32 limit = DocumentDownloadPartSize; MTPInputFileLocation loc; switch (locationType) { case 0: loc = MTP_inputFileLocation(MTP_long(volume), MTP_int(local), MTP_long(secret)); limit = DownloadPartSize; break; case mtpc_inputVideoFileLocation: loc = MTP_inputVideoFileLocation(MTP_long(id), MTP_long(access)); break; case mtpc_inputAudioFileLocation: loc = MTP_inputAudioFileLocation(MTP_long(id), MTP_long(access)); break; case mtpc_inputDocumentFileLocation: loc = MTP_inputDocumentFileLocation(MTP_long(id), MTP_long(access)); break; default: finishFail(); return false; break; } ++queue->queries; int32 offset = currentOffset(); MTPupload_GetFile request(MTPupload_getFile(loc, MTP_int(offset), MTP_int(limit))); requestId = MTP::send(request, rpcDone(&mtpFileLoader::partLoaded, offset), rpcFail(&mtpFileLoader::partFailed), MTP::dld + dc, 50); return true; }
void mtpFileLoader::start(bool loadFirst, bool prior) { if (complete || tryLoadLocal()) return; if (!fname.isEmpty() && !duplicateInData && !fileIsOpen) { fileIsOpen = file.open(QIODevice::WriteOnly); if (!fileIsOpen) { return finishFail(); } } mtpFileLoader *before = 0, *after = 0; if (prior) { if (inQueue && priority == _priority) { if (loadFirst) { if (!prev) return started(loadFirst, prior); before = queue->start; } else { if (!next || next->priority < _priority) return started(loadFirst, prior); after = next; while (after->next && after->next->priority == _priority) { after = after->next; } } } else { priority = _priority; if (loadFirst) { if (inQueue && !prev) return started(loadFirst, prior); before = queue->start; } else { if (inQueue) { if (next && next->priority == _priority) { after = next; } else if (prev && prev->priority < _priority) { before = prev; while (before->prev && before->prev->priority < _priority) { before = before->prev; } } else { return started(loadFirst, prior); } } else { if (queue->start && queue->start->priority == _priority) { after = queue->start; } else { before = queue->start; } } if (after) { while (after->next && after->next->priority == _priority) { after = after->next; } } } } } else { if (loadFirst) { if (inQueue && (!prev || prev->priority == _priority)) return started(loadFirst, prior); before = prev; while (before->prev && before->prev->priority != _priority) { before = before->prev; } } else { if (inQueue && !next) return started(loadFirst, prior); after = queue->end; } } removeFromQueue(); inQueue = true; if (!queue->start) { queue->start = queue->end = this; } else if (before) { if (before != next) { prev = before->prev; next = before; next->prev = this; if (prev) { prev->next = this; } if (queue->start->prev) queue->start = queue->start->prev; } } else if (after) { if (after != prev) { next = after->next; prev = after; after->next = this; if (next) { next->prev = this; } if (queue->end->next) queue->end = queue->end->next; } } else { LOG(("Queue Error: _start && !before && !after")); } return started(loadFirst, prior); }
bool mtpFileLoader::partFailed(const RPCError &error) { if (mtpIsFlood(error)) return false; finishFail(); return true; }
void mtpFileLoader::partLoaded(int32 offset, const MTPupload_File &result, mtpRequestId req) { // uint64 ms = getms(); Requests::iterator i = requests.find(req); if (i == requests.cend()) return loadNext(); int32 limit = (_locationType == UnknownFileLocation) ? DownloadPartSize : DocumentDownloadPartSize; int32 dcIndex = i.value(); _dataRequested[dc].v[dcIndex] -= limit; --queue->queries; requests.erase(i); const MTPDupload_file &d(result.c_upload_file()); const string &bytes(d.vbytes.c_string().v); if (bytes.size()) { if (fileIsOpen) { int64 fsize = file.size(); if (offset < fsize) { skippedBytes -= bytes.size(); } else if (offset > fsize) { skippedBytes += offset - fsize; } file.seek(offset); if (file.write(bytes.data(), bytes.size()) != qint64(bytes.size())) { return finishFail(); } } else { data.reserve(offset + bytes.size()); if (offset > data.size()) { skippedBytes += offset - data.size(); data.resize(offset); } if (offset == data.size()) { data.append(bytes.data(), bytes.size()); } else { skippedBytes -= bytes.size(); if (int64(offset + bytes.size()) > data.size()) { data.resize(offset + bytes.size()); } memcpy(data.data() + offset, bytes.data(), bytes.size()); } } } if (!bytes.size() || (bytes.size() % 1024)) { // bad next offset lastComplete = true; } if (requests.isEmpty() && (lastComplete || (size && nextRequestOffset >= size))) { if (!fname.isEmpty() && duplicateInData) { if (!fileIsOpen) fileIsOpen = file.open(QIODevice::WriteOnly); if (!fileIsOpen) { return finishFail(); } if (file.write(data) != qint64(data.size())) { return finishFail(); } } type = d.vtype.type(); complete = true; if (fileIsOpen) { file.close(); fileIsOpen = false; psPostprocessFile(QFileInfo(file).absoluteFilePath()); } removeFromQueue(); emit App::wnd()->imageLoaded(); if (!queue->queries) { App::app()->killDownloadSessionsStart(dc); } if (_localStatus == LocalNotFound || _localStatus == LocalFailed) { if (_locationType != UnknownFileLocation) { // audio, video, document MediaKey mkey = mediaKey(_locationType, dc, id); if (!fname.isEmpty()) { Local::writeFileLocation(mkey, FileLocation(mtpToStorageType(type), fname)); } if (duplicateInData) { if (_locationType == DocumentFileLocation) { Local::writeStickerImage(mkey, data); } else if (_locationType == AudioFileLocation) { Local::writeAudio(mkey, data); } } } else { Local::writeImage(storageKey(dc, volume, local), StorageImageSaved(mtpToStorageType(type), data)); } } } emit progress(this); loadNext(); }
bool mtpFileLoader::partFailed(const RPCError &error) { finishFail(); return true; }
bool mtpFileLoader::partFailed(const RPCError &error) { if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false; finishFail(); return true; }