void Tests::getHashesFromAFileEntry2() { qDebug() << "===== getHashesFromAFileEntry2() ====="; { QFile file1("sharedDirs/big2.bin"); file1.open(QIODevice::WriteOnly); QFile file2("sharedDirs/big3.bin"); file2.open(QIODevice::WriteOnly); file1.resize(128 * 1024 * 1024); // 128Mo file2.resize(128 * 1024 * 1024); // 128Mo } QTest::qWait(2000); // Begin the computing of the big2.bin hashes. Protos::Common::Entries sharedDirs = this->fileManager->getEntries(); const string sharedDirId = sharedDirs.entry(1).shared_dir().id().hash(); Protos::Common::Entry entry; entry.set_path("/"); entry.set_name("big3.bin"); entry.mutable_shared_dir()->mutable_id()->set_hash(sharedDirId); QSharedPointer<IGetHashesResult> result = this->fileManager->getHashes(entry); HashesReceiver hashesReceiver; connect(result.data(), SIGNAL(nextHash(Common::Hash)), &hashesReceiver, SLOT(nextHash(Common::Hash))); Protos::Core::GetHashesResult res = result->start(); // Should stop the computing of 'big2.bin' and switch to 'big3.bin'. QCOMPARE(res.status(), Protos::Core::GetHashesResult_Status_OK); QTest::qWait(4000); }
/** * Called from the main thread. */ Protos::Core::GetHashesResult GetHashesResult::start() { Protos::Core::GetHashesResult result; if (!(this->file = this->cache.getFile(this->fileEntry))) { result.set_status(Protos::Core::GetHashesResult_Status_DONT_HAVE); return result; } const QVector<QSharedPointer<Chunk>>& chunks = this->file->getChunks(); if (this->fileEntry.chunk_size() > chunks.size()) { L_ERRO("Impossible to known more hashes than the number of chunks."); result.set_status(Protos::Core::GetHashesResult_Status_ERROR_UNKNOWN); return result; } connect(&this->cache, SIGNAL(chunkHashKnown(QSharedPointer<Chunk>)), this, SLOT(chunkHashKnown(QSharedPointer<Chunk>)), Qt::DirectConnection); this->nbHash = chunks.size() - this->fileEntry.chunk_size(); this->lastHashNumSent = this->fileEntry.chunk_size() - 1; result.set_nb_hash(this->nbHash); for (QVectorIterator<QSharedPointer<Chunk>> i(chunks); i.hasNext();) { QSharedPointer<Chunk> chunk(i.next()); if (chunk->getNum() < this->fileEntry.chunk_size()) continue; if (chunk->hasHash()) { this->sendNextHash(chunk); } else // If only one hash is missing we tell the file updater to compute the remaining ones. { this->fileUpdater.prioritizeAFileToHash(this->file); break; } } result.set_status(Protos::Core::GetHashesResult_Status_OK); return result; }
void Tests::getHashesFromAFileEntry1() { qDebug() << "===== getHashesFromAFileEntry1() ====="; // Find the id of the first shared directory. Protos::Common::Entries sharedDirs = this->fileManager->getEntries(); const string sharedDirId = sharedDirs.entry(1).shared_dir().id().hash(); Protos::Common::Entry entry; entry.set_path("/share1/"); entry.set_name("r.txt"); entry.mutable_shared_dir()->mutable_id()->set_hash(sharedDirId); QSharedPointer<IGetHashesResult> result = this->fileManager->getHashes(entry); HashesReceiver hashesReceiver; connect(result.data(), SIGNAL(nextHash(Common::Hash)), &hashesReceiver, SLOT(nextHash(Common::Hash))); Protos::Core::GetHashesResult res = result->start(); QCOMPARE(res.status(), Protos::Core::GetHashesResult_Status_OK); QVERIFY(hashesReceiver.waitToReceive(QList<Common::Hash>() << Common::Hash::fromStr("97d464813598e2e4299b5fe7db29aefffdf2641d"), 500)); }
void ResultListener::hashesResult(const Protos::Core::GetHashesResult& result) { this->nbHashes = result.nb_hash(); this->currentHash = 0; qDebug() << "ResultListener::hashesResult : " << Common::ProtoHelper::getDebugStr(result); }
void PeerMessageSocket::onNewMessage(const Common::Message& message) { switch (message.getHeader().getType()) { case Common::MessageHeader::CORE_GET_ENTRIES: { if (!this->entriesResultsToReceive.isEmpty()) return; const Protos::Core::GetEntries& getEntries = message.getMessage<Protos::Core::GetEntries>(); for (int i = 0; i < getEntries.dirs().entry_size(); i++) { QSharedPointer<FM::IGetEntriesResult> entriesResult = this->fileManager->getScannedEntries(getEntries.dirs().entry(i)); connect(entriesResult.data(), SIGNAL(result(const Protos::Core::GetEntriesResult::EntryResult&)), this, SLOT(entriesResult(const Protos::Core::GetEntriesResult::EntryResult&)), Qt::DirectConnection); connect(entriesResult.data(), SIGNAL(timeout()), this, SLOT(entriesResultTimeout()), Qt::DirectConnection); this->entriesResultsToReceive << entriesResult; this->entriesResultMessage.add_result(); } // Add the root directories if asked. if (getEntries.dirs().entry_size() == 0 || getEntries.get_roots()) this->entriesResultMessage.add_result()->mutable_entries()->CopyFrom(this->fileManager->getEntries()); if (this->entriesResultsToReceive.isEmpty()) this->sendEntriesResultMessage(); else foreach (QSharedPointer<FM::IGetEntriesResult> entriesResult, this->entriesResultsToReceive) entriesResult->start(); } break; case Common::MessageHeader::CORE_GET_ENTRIES_RESULT: this->finished(); break; case Common::MessageHeader::CORE_GET_HASHES: { const Protos::Core::GetHashes& getHashes = message.getMessage<Protos::Core::GetHashes>(); this->currentHashesResult = this->fileManager->getHashes(getHashes.file()); connect(this->currentHashesResult.data(), SIGNAL(nextHash(Protos::Core::HashResult)), this, SLOT(nextAskedHash(Protos::Core::HashResult)), Qt::QueuedConnection); Protos::Core::GetHashesResult res = this->currentHashesResult->start(); this->nbHash = res.nb_hash(); this->send(Common::MessageHeader::CORE_GET_HASHES_RESULT, res); if (res.status() != Protos::Core::GetHashesResult_Status_OK) { this->currentHashesResult.clear(); this->finished(); } } break; case Common::MessageHeader::CORE_GET_HASHES_RESULT: { const Protos::Core::GetHashesResult& getHashesResult = message.getMessage<Protos::Core::GetHashesResult>(); this->nbHash = getHashesResult.nb_hash(); } break; case Common::MessageHeader::CORE_HASH_RESULT: { if (--this->nbHash == 0) this->finished(); } break; case Common::MessageHeader::CORE_GET_CHUNK: { const Protos::Core::GetChunk& getChunkMessage = message.getMessage<Protos::Core::GetChunk>(); const Common::Hash hash(getChunkMessage.chunk().hash()); if (hash.isNull()) { L_WARN("GET_CHUNK: Chunk null"); this->finished(true); break; } // TODO: implements 'GetChunkResult.ALREADY_DOWNLOADING', 'GetChunkResult.TOO_MANY_CONNECTIONS' and 'GetChunkResult.DONT_HAVE_DATA_FROM_OFFSET' QSharedPointer<FM::IChunk> chunk = this->fileManager->getChunk(hash); if (chunk.isNull()) { Protos::Core::GetChunkResult result; result.set_status(Protos::Core::GetChunkResult::DONT_HAVE); this->send(Common::MessageHeader::CORE_GET_CHUNK_RESULT, result); this->finished(); L_WARN(QString("GET_CHUNK: Chunk unknown : %1").arg(hash.toStr())); } else { Protos::Core::GetChunkResult result; result.set_status(Protos::Core::GetChunkResult::OK); result.set_chunk_size(chunk->getKnownBytes()); this->send(Common::MessageHeader::CORE_GET_CHUNK_RESULT, result); this->stopListening(); emit getChunk(chunk, getChunkMessage.offset(), this); } } break; default:; // Do nothing. } }
void Socket::onNewMessage(Common::MessageHeader::MessageType type, const google::protobuf::Message& message) { switch (type) { case Common::MessageHeader::CORE_GET_ENTRIES: { const Protos::Core::GetEntries& getEntries = static_cast<const Protos::Core::GetEntries&>(message); Protos::Core::GetEntriesResult result; for (int i = 0; i < getEntries.dirs().entry_size(); i++) result.add_entries()->CopyFrom(this->fileManager->getEntries(getEntries.dirs().entry(i))); // Add the root directories if asked. if (getEntries.dirs().entry_size() == 0 || getEntries.get_roots()) result.add_entries()->CopyFrom(this->fileManager->getEntries()); this->send(Common::MessageHeader::CORE_GET_ENTRIES_RESULT, result); this->finished(); } break; case Common::MessageHeader::CORE_GET_ENTRIES_RESULT: this->finished(); break; case Common::MessageHeader::CORE_GET_HASHES: { const Protos::Core::GetHashes& getHashes = static_cast<const Protos::Core::GetHashes&>(message); this->currentHashesResult = this->fileManager->getHashes(getHashes.file()); connect(this->currentHashesResult.data(), SIGNAL(nextHash(Common::Hash)), this, SLOT(nextAskedHash(Common::Hash)), Qt::QueuedConnection); Protos::Core::GetHashesResult res = this->currentHashesResult->start(); this->nbHash = res.nb_hash(); this->send(Common::MessageHeader::CORE_GET_HASHES_RESULT, res); if (res.status() != Protos::Core::GetHashesResult_Status_OK) { this->currentHashesResult.clear(); this->finished(); } } break; case Common::MessageHeader::CORE_GET_HASHES_RESULT: { const Protos::Core::GetHashesResult& getHashesResult = static_cast<const Protos::Core::GetHashesResult&>(message); this->nbHash = getHashesResult.nb_hash(); } break; case Common::MessageHeader::CORE_HASH: { if (--this->nbHash == 0) this->finished(); } break; case Common::MessageHeader::CORE_GET_CHUNK: { const Protos::Core::GetChunk& getChunkMessage = static_cast<const Protos::Core::GetChunk&>(message); const Common::Hash hash(getChunkMessage.chunk().hash()); if (hash.isNull()) { L_WARN("GET_CHUNK: Chunk null"); this->finished(ISocket::SFS_ERROR); break; } QSharedPointer<FM::IChunk> chunk = this->fileManager->getChunk(hash); if (chunk.isNull()) { Protos::Core::GetChunkResult result; result.set_status(Protos::Core::GetChunkResult_Status_DONT_HAVE); this->send(Common::MessageHeader::CORE_GET_CHUNK_RESULT, result); this->finished(); L_WARN(QString("GET_CHUNK: Chunk unknown : %1").arg(hash.toStr())); } else { Protos::Core::GetChunkResult result; result.set_status(Protos::Core::GetChunkResult_Status_OK); result.set_chunk_size(chunk->getKnownBytes()); this->send(Common::MessageHeader::CORE_GET_CHUNK_RESULT, result); this->stopListening(); emit getChunk(chunk, getChunkMessage.offset(), this); } } break; default:; // Do nothing. } }