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(); }
void mtpFileLoader::partLoaded(int32 offset, const MTPupload_File &result, mtpRequestId req) { Requests::iterator i = _requests.find(req); if (i == _requests.cend()) { if (DebugLogging::FileLoader() && _id) DEBUG_LOG(("FileLoader(%1): request req=%2 for offset=%3 not found in _requests=%4").arg(_id).arg(req).arg(offset).arg(serializereqs(_requests))); return loadNext(); } if (result.type() != mtpc_upload_file) { if (DebugLogging::FileLoader() && _id) DEBUG_LOG(("FileLoader(%1): bad cons received! %2").arg(_id).arg(result.type())); return cancel(true); } int32 limit = (_locationType == UnknownFileLocation) ? DownloadPartSize : DocumentDownloadPartSize; int32 dcIndex = i.value(); DataRequestedMap[_dc].v[dcIndex] -= limit; --_queue->queries; _requests.erase(i); auto &d = result.c_upload_file(); auto &bytes = d.vbytes.c_string().v; if (DebugLogging::FileLoader() && _id) DEBUG_LOG(("FileLoader(%1): got part with offset=%2, bytes=%3, _queue->queries=%4, _nextRequestOffset=%5, _requests=%6").arg(_id).arg(offset).arg(bytes.size()).arg(_queue->queries).arg(_nextRequestOffset).arg(serializereqs(_requests))); 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 cancel(true); } } 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() && (_toCache == LoadToCacheAsWell)) { if (!_fileIsOpen) _fileIsOpen = _file.open(QIODevice::WriteOnly); if (!_fileIsOpen) { return cancel(true); } if (_file.write(_data) != qint64(_data.size())) { return cancel(true); } } _type = d.vtype.type(); _complete = true; if (_fileIsOpen) { _file.close(); _fileIsOpen = false; psPostprocessFile(QFileInfo(_file).absoluteFilePath()); } removeFromQueue(); if (!_queue->queries) { App::app()->killDownloadSessionsStart(_dc); } if (_localStatus == LocalNotFound || _localStatus == LocalFailed) { if (_locationType != UnknownFileLocation) { // audio, video, document MediaKey mkey = mediaKey(_locationType, _dc, _id, _version); if (!_fname.isEmpty()) { Local::writeFileLocation(mkey, FileLocation(mtpToStorageType(_type), _fname)); } if (_toCache == LoadToCacheAsWell) { if (_locationType == DocumentFileLocation) { Local::writeStickerImage(mkey, _data); } else if (_locationType == AudioFileLocation) { Local::writeAudio(mkey, _data); } } } else { Local::writeImage(storageKey(*_location), StorageImageSaved(mtpToStorageType(_type), _data)); } } } else { if (DebugLogging::FileLoader() && _id) DEBUG_LOG(("FileLoader(%1): not done yet, _lastComplete=%2, _size=%3, _nextRequestOffset=%4, _requests=%5").arg(_id).arg(Logs::b(_lastComplete)).arg(_size).arg(_nextRequestOffset).arg(serializereqs(_requests))); } emit progress(this); if (_complete) { FileDownload::ImageLoaded().notify(); } loadNext(); }