示例#1
0
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();
}
示例#2
0
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;
}
示例#3
0
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();
}
示例#4
0
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;
}
示例#5
0
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;
}
示例#6
0
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);
}
示例#7
0
bool mtpFileLoader::partFailed(const RPCError &error) {
	if (mtpIsFlood(error)) return false;

	finishFail();
	return true;
}
示例#8
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();
}
示例#9
0
bool mtpFileLoader::partFailed(const RPCError &error) {
	finishFail();
	return true;
}
示例#10
0
bool mtpFileLoader::partFailed(const RPCError &error) {
	if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;

	finishFail();
	return true;
}