예제 #1
0
파일: Tests.cpp 프로젝트: PowerKiKi/D-LAN
void Tests::compareExpectedResult(const Protos::Common::FindResult& result, const FindResult& expectedResult)
{
   for (int i = 0; i < result.entry_size(); i++)
   {
      QVERIFY(expectedResult.contains(result.entry(i).level()));
      QVERIFY(expectedResult[result.entry(i).level()].contains(Common::ProtoHelper::getStr(result.entry(i).entry(), &Protos::Common::Entry::name)));
   }
}
예제 #2
0
/**
  * Function called when data is recevied by the socket : The corresponding proto is created and the coresponding event is rised.
  */
void UDPListener::processPendingUnicastDatagrams()
{
   while (this->unicastSocket.hasPendingDatagrams())
   {
      QHostAddress peerAddress;
      const Common::MessageHeader& header =  UDPListener::readDatagramToBuffer(this->unicastSocket, peerAddress);
      if (header.isNull())
         continue;

      switch (header.getType())
      {
      case Common::MessageHeader::CORE_CHUNKS_OWNED:
         {
            Protos::Core::ChunksOwned chunksOwnedMessage;
            chunksOwnedMessage.ParseFromArray(this->bodyBuffer, header.getSize());

            if (chunksOwnedMessage.tag() != this->currentIMAliveTag)
            {
               L_WARN(QString("ChunksOwned : tag (%1) doesn't match current tag (%2)").arg(chunksOwnedMessage.tag()).arg(currentIMAliveTag));
               continue;
            }

            if (chunksOwnedMessage.chunk_state_size() != this->currentChunkDownloads.size())
            {
               L_WARN(QString("ChunksOwned : The size (%1) doesn't match the expected one (%2)").arg(chunksOwnedMessage.chunk_state_size()).arg(this->currentChunkDownloads.size()));
               continue;
            }

            for (int i = 0; i < chunksOwnedMessage.chunk_state_size(); i++)
            {
               if (chunksOwnedMessage.chunk_state(i))
                  this->currentChunkDownloads[i]->addPeerID(header.getSenderID());
               else
                  this->currentChunkDownloads[i]->rmPeerID(header.getSenderID());
            }
         }
         break;

      case Common::MessageHeader::CORE_FIND_RESULT:
         {
            Protos::Common::FindResult findResultMessage;
            findResultMessage.ParseFromArray(this->bodyBuffer, header.getSize());
            findResultMessage.mutable_peer_id()->set_hash(header.getSenderID().getData(), Common::Hash::HASH_SIZE);
            emit newFindResultMessage(findResultMessage);
         }
         break;

      default:
         L_WARN(QString("Unkown header type from unicast socket : %1").arg(header.getType(), 0, 16));
      }
   }
}
예제 #3
0
파일: Tests.cpp 프로젝트: PowerKiKi/D-LAN
void Tests::printSearch(const QString& terms, const Protos::Common::FindResult& result)
{
   qDebug() << "Search : " << terms;
   for (int i = 0; i < result.entry_size(); i++)
      qDebug() << "[" << result.entry(i).level() << "] " << Common::ProtoHelper::getStr(result.entry(i).entry(), &Protos::Common::Entry::name);
}
예제 #4
0
/**
  * Function called when data is recevied by the socket : The corresponding proto is created and the coresponding event is rised.
  */
void UDPListener::processPendingUnicastDatagrams()
{
   while (this->unicastSocket.hasPendingDatagrams())
   {
      QHostAddress peerAddress;
      const Common::MessageHeader& header =  UDPListener::readDatagramToBuffer(this->unicastSocket, peerAddress);
      if (header.isNull())
         continue;

      try
      {
         const Common::Message& message = Common::Message::readMessageBody(header, this->bodyBuffer);

         switch (header.getType())
         {
         case Common::MessageHeader::CORE_CHUNKS_OWNED:
            {
               const Protos::Core::ChunksOwned& chunksOwnedMessage = message.getMessage<Protos::Core::ChunksOwned>();

               if (chunksOwnedMessage.tag() != this->currentIMAliveTag)
               {
                  L_WARN(QString("ChunksOwned : tag (%1) doesn't match current tag (%2)").arg(chunksOwnedMessage.tag()).arg(currentIMAliveTag));
                  continue;
               }

               if (chunksOwnedMessage.chunk_state_size() != this->currentChunkDownloaders.size())
               {
                  L_WARN(QString("ChunksOwned : The size (%1) doesn't match the expected one (%2)").arg(chunksOwnedMessage.chunk_state_size()).arg(this->currentChunkDownloaders.size()));
                  continue;
               }

               for (int i = 0; i < chunksOwnedMessage.chunk_state_size(); i++)
                  if (PM::IPeer* peer = this->peerManager->getPeer(header.getSenderID()))
                  {
                     if (chunksOwnedMessage.chunk_state(i))
                        this->currentChunkDownloaders[i]->addPeer(peer);
                     else
                        this->currentChunkDownloaders[i]->rmPeer(peer);
                  }
            }
            break;

         case Common::MessageHeader::CORE_FIND_RESULT:
            {
               Protos::Common::FindResult findResultMessage = message.getMessage<Protos::Common::FindResult>();
               findResultMessage.mutable_peer_id()->set_hash(header.getSenderID().getData(), Common::Hash::HASH_SIZE);
               emit newFindResultMessage(findResultMessage);
            }
            break;

         default:; // Ignore other messages.
         }

         emit received(message);
      }
      catch(Common::ReadErrorException&)
      {
         L_WARN(QString("Unable to read an unicast message from peer %1 %2").arg(header.getSenderID().toStr()).arg(peerAddress.toString()));
      }
   }
}
예제 #5
0
/**
  * This method is called several times, one by received entries. The entries are inserted into the model.
  * The given entries are sorted by their level, we will keep the sort when inserting the entry but with some modifications :
  * - The directories are put first.
  * - All entries with the same level are sorted first by their path (prefixed with the shared directory name) and then by their name.
  * - All file entries with the same chunks (identical data) are grouped. They can be owned by different peer.
  */
void SearchModel::result(const Protos::Common::FindResult& findResult)
{
   if (findResult.entry_size() == 0)
      return;

   QList<const Protos::Common::FindResult_EntryLevel*> sortedEntries;
   for (int i = 0; i < findResult.entry_size(); i++)
      sortedEntries << &findResult.entry(i);
   qSort(sortedEntries.begin(), sortedEntries.end(), &findEntryLessThan);

   int currentIndex = 0;

   bool maxLevelChange = false;

   for (QListIterator<const Protos::Common::FindResult_EntryLevel*> i(sortedEntries); i.hasNext();)
   {
      const Protos::Common::FindResult_EntryLevel* entry = i.next();
      if (this->setMaxLevel(entry->level()))
         maxLevelChange = true;

      // Search if a similar entry already exists. If so then insert the new tree as child.
      if (entry->entry().type() == Protos::Common::Entry_Type_FILE && entry->entry().chunk_size() > 0)
      {
         Common::Hash firstChunk = entry->entry().chunk(0).hash();
         SearchTree* similarTree = 0;
         if ((similarTree = this->indexedFile.value(firstChunk)) && similarTree->isSameAs(entry->entry()))
         {
            if (similarTree->getNbChildren() == 0)
            {
               this->beginInsertRows(this->createIndex(0, 0, similarTree), 0, 0);
               similarTree->insertChild(similarTree);
               this->endInsertRows();
            }

            // Search the better name (tree with the lowest level) to display it on the top.
            for (int i = 0; i <= similarTree->getNbChildren(); i++)
            {
               if (i == similarTree->getNbChildren() || static_cast<SearchTree*>(similarTree->getChild(i))->getLevel() > static_cast<int>(entry->level()))
               {
                  this->beginInsertRows(this->createIndex(0, 0, similarTree), i, i);
                  Common::Hash peerID = findResult.peer_id().hash();
                  SearchTree* newTree = similarTree->insertChild(i, *entry, peerID, this->peerListModel.getNick(peerID, tr("<unknown>")));
                  this->endInsertRows();

                  if (static_cast<int>(entry->level()) < similarTree->getLevel())
                  {
                     const int row = similarTree->getOwnPosition();
                     similarTree->copyFrom(newTree);
                     emit dataChanged(this->createIndex(row, 0, similarTree), this->createIndex(row, 3, similarTree));
                  }

                  break;
               }
            }

            continue;
         }
      }

      currentIndex = this->insertTree(*entry, findResult.peer_id().hash(), currentIndex);
   }

   if (maxLevelChange && this->rowCount() > 0)
      emit dataChanged(this->createIndex(0, 2), this->createIndex(this->rowCount() - 1, 2));
}