Example #1
0
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();
}
Example #2
0
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();
}