예제 #1
0
파일: Tests.cpp 프로젝트: PowerKiKi/D-LAN
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);
}
예제 #2
0
/**
  * 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;
}
예제 #3
0
파일: Tests.cpp 프로젝트: PowerKiKi/D-LAN
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));
}
예제 #4
0
void ResultListener::hashesResult(const Protos::Core::GetHashesResult& result)
{
   this->nbHashes = result.nb_hash();
   this->currentHash = 0;
   qDebug() << "ResultListener::hashesResult : " << Common::ProtoHelper::getDebugStr(result);
}
예제 #5
0
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.
   }
}
예제 #6
0
파일: Socket.cpp 프로젝트: Zorvalt/D-LAN
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.
   }
}