LCOV - code coverage report
Current view: top level - shared - Binary.cpp (source / functions) Hit Total Coverage
Test: code-coverage.info.cleaned Lines: 40 51 78.4 %
Date: 2023-01-28 00:08:57 Functions: 18 18 100.0 %

          Line data    Source code
       1             : #include <shared.hpp>
       2             : #include <iostream>
       3             : #include <sstream>
       4             : 
       5             : #include <boost/asio.hpp>
       6             : #include <boost/asio/ip/tcp.hpp>
       7             : #include <boost/archive/binary_oarchive.hpp>
       8             : #include <boost/archive/binary_iarchive.hpp>
       9             : #include "Serialization.cpp"
      10             : 
      11             : using namespace shared;
      12             : 
      13           2 : void Binary::send(std::shared_ptr<shared::Player> player, std::string serializedData, bool answerRequired)
      14             : {
      15           2 :     std::string header;
      16           2 :     if (answerRequired)
      17             :     {
      18           2 :         header = "binary " + std::to_string(serializedData.size()) + "\n";
      19             :     }
      20             :     else
      21             :     {
      22           0 :         header = "rulesturn " + std::to_string(serializedData.size()) + "\n";
      23             :     }
      24           2 :     std::lock_guard<std::mutex> lock(player->socketWriteMutex);
      25           2 :     boost::asio::write(player->getSocket(), boost::asio::buffer(header));
      26           2 :     boost::asio::write(player->getSocket(), boost::asio::buffer(serializedData));
      27           2 : }
      28             : 
      29           2 : std::string Binary::receive(std::shared_ptr<shared::Player> player, std::istream &alreadyReceived, size_t totalSize)
      30             : {
      31           2 :     std::stringstream buffer;
      32           2 :     buffer << alreadyReceived.rdbuf();
      33           2 :     std::string fullMessage = buffer.str();
      34             : 
      35           2 :     boost::system::error_code error;
      36           2 :     boost::asio::streambuf receiveBuffer;
      37             : 
      38           2 :     if (fullMessage.size() > totalSize)
      39             :     {
      40           0 :         for (size_t i = fullMessage.size(); i > totalSize; i--)
      41             :         {
      42           0 :             alreadyReceived.unget();
      43             :         }
      44             : 
      45           0 :         return fullMessage.substr(0, totalSize);
      46             :     }
      47           2 :     else if (fullMessage.size() == totalSize)
      48             :     {
      49           0 :         return fullMessage;
      50             :     }
      51           2 :     size_t size = totalSize - fullMessage.size();
      52             : 
      53             :     try
      54             :     {
      55           2 :         std::lock_guard<std::mutex> lock(player->socketReadMutex);
      56           2 :         boost::asio::read(player->getSocket(), receiveBuffer, boost::asio::transfer_exactly(size), error);
      57           2 :     }
      58           0 :     catch (const boost::system::system_error &e)
      59             :     {
      60           0 :         std::cerr << "Error: " << e.what() << std::endl;
      61           0 :     }
      62             : 
      63           2 :     if (error == boost::asio::error::operation_aborted || error == boost::asio::error::eof)
      64             :     {
      65           0 :         player->disconnectPlayer();
      66             :     }
      67           2 :     else if (error)
      68             :     {
      69           0 :         std::cerr << "Error: " << error.message() << std::endl;
      70           0 :         player->disconnectPlayer();
      71             :     }
      72             : 
      73             :     std::string messageReceived(
      74           2 :         boost::asio::buffers_begin(receiveBuffer.data()),
      75           4 :         boost::asio::buffers_end(receiveBuffer.data()));
      76             : 
      77           2 :     if (fullMessage.size() == 0)
      78             :     {
      79           1 :         return messageReceived;
      80             :     }
      81             :     else
      82             :     {
      83           1 :         fullMessage += messageReceived;
      84           1 :         return fullMessage;
      85             :     }
      86           2 : }
      87             : 
      88             : template <typename T>
      89          10 : void Binary::castToObject(std::string receivedData, T &data)
      90             : {
      91          10 :     std::stringstream receivedStream(receivedData);
      92          10 :     boost::archive::binary_iarchive ia(receivedStream);
      93          10 :     ia >> data;
      94          10 : }
      95             : 
      96             : template <typename T>
      97          10 : void Binary::castToBinary(T &data, std::string &serializedData)
      98             : {
      99          10 :     std::stringstream stream;
     100          10 :     boost::archive::binary_oarchive oa(stream);
     101          10 :     oa << data;
     102          10 :     serializedData = stream.str();
     103          10 : }
     104             : 
     105             : // We need to instantiate the templates for the types we use in other library than shared
     106             : template void Binary::castToBinary<Map>(Map &data, std::string &serializedData);
     107             : template void Binary::castToObject<Map>(std::string receivedData, Map &data);
     108             : 
     109             : template void Binary::castToBinary<RuleArgsStruct>(RuleArgsStruct &data, std::string &serializedData);
     110             : template void Binary::castToObject<RuleArgsStruct>(std::string receivedData, RuleArgsStruct &data);
     111             : 
     112             : template void Binary::castToBinary<Barbarian>(Barbarian &data, std::string &serializedData);
     113             : template void Binary::castToObject<Barbarian>(std::string receivedData, Barbarian &data);
     114             : 
     115             : template void Binary::castToBinary<BarbarianVillage>(BarbarianVillage &data, std::string &serializedData);
     116             : template void Binary::castToObject<BarbarianVillage>(std::string receivedData, BarbarianVillage &data);
     117             : 
     118             : template void Binary::castToBinary<City>(City &data, std::string &serializedData);
     119             : template void Binary::castToObject<City>(std::string receivedData, City &data);
     120             : 
     121             : template void Binary::castToBinary<Caravan>(Caravan &data, std::string &serializedData);
     122             : template void Binary::castToObject<Caravan>(std::string receivedData, Caravan &data);
     123             : 
     124             : template void Binary::castToBinary<ControlPawn>(ControlPawn &data, std::string &serializedData);
     125             : template void Binary::castToObject<ControlPawn>(std::string receivedData, ControlPawn &data);
     126             : 
     127             : template void Binary::castToBinary<Hexagon>(Hexagon &data, std::string &serializedData);
     128             : template void Binary::castToObject<Hexagon>(std::string receivedData, Hexagon &data);

Generated by: LCOV version 1.14