LCOV - code coverage report
Current view: top level - co - connectionDescription.cpp (source / functions) Hit Total Coverage
Test: Collage Lines: 68 160 42.5 %
Date: 2018-01-09 16:37:03 Functions: 10 18 55.6 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2005-2016, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *
       4             :  * This file is part of Collage <https://github.com/Eyescale/Collage>
       5             :  *
       6             :  * This library is free software; you can redistribute it and/or modify it under
       7             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       8             :  * by the Free Software Foundation.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      11             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      12             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      13             :  * details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public License
      16             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      17             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             :  */
      19             : 
      20             : #include "connectionDescription.h"
      21             : 
      22             : #include <sstream>
      23             : 
      24             : namespace co
      25             : {
      26             : #define SEPARATOR '#'
      27             : 
      28             : namespace
      29             : {
      30          65 : static ConnectionType _getConnectionType(const std::string& string)
      31             : {
      32          65 :     if (string == "TCPIP")
      33          65 :         return CONNECTIONTYPE_TCPIP;
      34           0 :     if (string == "TCP")
      35           0 :         return CONNECTIONTYPE_TCPIP;
      36           0 :     if (string == "ANON_PIPE")
      37           0 :         return CONNECTIONTYPE_PIPE;
      38           0 :     if (string == "PIPE")
      39           0 :         return CONNECTIONTYPE_NAMEDPIPE;
      40           0 :     if (string == "RSP")
      41           0 :         return CONNECTIONTYPE_RSP;
      42           0 :     if (string == "RDMA")
      43           0 :         return CONNECTIONTYPE_RDMA;
      44           0 :     if (string == "UDT")
      45           0 :         return CONNECTIONTYPE_UDT;
      46             : 
      47           0 :     LBWARN << "Unknown connection type: " << string << std::endl;
      48           0 :     return CONNECTIONTYPE_NONE;
      49             : }
      50             : }
      51             : 
      52           0 : ConnectionDescription::ConnectionDescription(std::string& data)
      53             :     : type(CONNECTIONTYPE_TCPIP)
      54             :     , bandwidth(0)
      55             :     , port(0)
      56           0 :     , filename("default")
      57             : {
      58           0 :     fromString(data);
      59           0 :     LBASSERTINFO(data.empty(), data);
      60           0 : }
      61             : 
      62         747 : std::string ConnectionDescription::toString() const
      63             : {
      64        1494 :     std::ostringstream description;
      65         746 :     serialize(description);
      66        1494 :     return description.str();
      67             : }
      68             : 
      69         812 : void ConnectionDescription::serialize(std::ostream& os) const
      70             : {
      71         812 :     os << type << SEPARATOR << bandwidth << SEPARATOR << hostname << SEPARATOR
      72        1624 :        << interfacename << SEPARATOR << port << SEPARATOR << filename
      73        1623 :        << SEPARATOR;
      74         811 : }
      75             : 
      76          65 : bool ConnectionDescription::fromString(std::string& data)
      77             : {
      78             :     {
      79          65 :         size_t nextPos = data.find(SEPARATOR);
      80             :         // assume hostname[:port][:type] or filename:PIPE format
      81          65 :         if (nextPos == std::string::npos)
      82             :         {
      83           0 :             type = CONNECTIONTYPE_TCPIP;
      84           0 :             nextPos = data.find(':');
      85           0 :             if (nextPos == std::string::npos) // assume hostname format
      86             :             {
      87           0 :                 hostname = data;
      88           0 :                 data.clear();
      89           0 :                 return true;
      90             :             }
      91             : 
      92           0 :             hostname = data.substr(0, nextPos);
      93           0 :             data = data.substr(nextPos + 1);
      94             : 
      95           0 :             while (nextPos != std::string::npos)
      96             :             {
      97           0 :                 nextPos = data.find(':');
      98           0 :                 const std::string token = data.substr(0, nextPos);
      99           0 :                 data = data.substr(nextPos + 1);
     100             : 
     101           0 :                 if (!token.empty() && isdigit(token[0])) // port
     102           0 :                     port = atoi(token.c_str());
     103             :                 else
     104             :                 {
     105           0 :                     type = _getConnectionType(token);
     106           0 :                     if (type == CONNECTIONTYPE_NAMEDPIPE)
     107             :                     {
     108           0 :                         filename = hostname;
     109           0 :                         hostname.clear();
     110             :                     }
     111           0 :                     else if (type == CONNECTIONTYPE_NONE)
     112           0 :                         goto error;
     113             :                 }
     114             :             }
     115             : 
     116           0 :             data.clear();
     117           0 :             return true;
     118             :         }
     119             : 
     120             :         // else assume SEPARATOR-delimited list
     121         130 :         const std::string typeStr = data.substr(0, nextPos);
     122          65 :         data = data.substr(nextPos + 1);
     123             : 
     124          65 :         type = _getConnectionType(typeStr);
     125             : 
     126          65 :         nextPos = data.find(SEPARATOR);
     127          65 :         if (nextPos == std::string::npos)
     128           0 :             goto error;
     129             : 
     130         130 :         const std::string bandwidthStr = data.substr(0, nextPos);
     131          65 :         data = data.substr(nextPos + 1);
     132          65 :         bandwidth = atoi(bandwidthStr.c_str());
     133             : 
     134          65 :         nextPos = data.find(SEPARATOR);
     135          65 :         if (nextPos == std::string::npos)
     136           0 :             goto error;
     137             : 
     138          65 :         hostname = data.substr(0, nextPos);
     139          65 :         data = data.substr(nextPos + 1);
     140             : 
     141          65 :         nextPos = data.find(SEPARATOR);
     142          65 :         if (nextPos == std::string::npos)
     143           0 :             goto error;
     144             : 
     145          65 :         interfacename = data.substr(0, nextPos);
     146          65 :         data = data.substr(nextPos + 1);
     147             : 
     148          65 :         nextPos = data.find(SEPARATOR);
     149          65 :         if (nextPos == std::string::npos)
     150           0 :             goto error;
     151             : 
     152         130 :         const std::string portStr = data.substr(0, nextPos);
     153          65 :         data = data.substr(nextPos + 1);
     154          65 :         port = atoi(portStr.c_str());
     155             : 
     156          65 :         nextPos = data.find(SEPARATOR);
     157          65 :         if (nextPos == std::string::npos)
     158           0 :             goto error;
     159             : 
     160          65 :         filename = data.substr(0, nextPos);
     161          65 :         data = data.substr(nextPos + 1);
     162             :     }
     163          65 :     return true;
     164             : 
     165             : error:
     166           0 :     LBWARN << "Could not parse connection description: " << data << std::endl;
     167           0 :     return false;
     168             : }
     169             : 
     170         121 : void ConnectionDescription::setHostname(const std::string& hostname_)
     171             : {
     172         121 :     hostname = hostname_;
     173         121 : }
     174             : 
     175           0 : void ConnectionDescription::setInterface(const std::string& interface_)
     176             : {
     177           0 :     interfacename = interface_;
     178           0 : }
     179             : 
     180           0 : void ConnectionDescription::setFilename(const std::string& filename_)
     181             : {
     182           0 :     filename = filename_;
     183           0 : }
     184             : 
     185           0 : const std::string& ConnectionDescription::getFilename() const
     186             : {
     187           0 :     return filename;
     188             : }
     189             : 
     190         238 : const std::string& ConnectionDescription::getHostname() const
     191             : {
     192         238 :     return hostname;
     193             : }
     194             : 
     195           0 : const std::string& ConnectionDescription::getInterface() const
     196             : {
     197           0 :     return interfacename;
     198             : }
     199             : 
     200           0 : bool ConnectionDescription::isSameMulticastGroup(
     201             :     ConstConnectionDescriptionPtr rhs)
     202             : {
     203           0 :     return (type >= CONNECTIONTYPE_MULTICAST && type == rhs->type &&
     204           0 :             hostname == rhs->hostname && port == rhs->port);
     205             : }
     206             : 
     207           0 : bool ConnectionDescription::operator==(const ConnectionDescription& rhs) const
     208             : {
     209           0 :     return type == rhs.type && bandwidth == rhs.bandwidth && port == rhs.port &&
     210           0 :            hostname == rhs.hostname && interfacename == rhs.interfacename &&
     211           0 :            filename == rhs.filename;
     212             : }
     213             : 
     214          66 : std::string serialize(const ConnectionDescriptions& descriptions)
     215             : {
     216         132 :     std::ostringstream data;
     217          66 :     data << descriptions.size() << CO_SEPARATOR;
     218             : 
     219         393 :     for (ConnectionDescriptions::const_iterator i = descriptions.begin();
     220         262 :          i != descriptions.end(); ++i)
     221             :     {
     222         130 :         ConnectionDescriptionPtr desc = *i;
     223          65 :         desc->serialize(data);
     224             :     }
     225             : 
     226         132 :     return data.str();
     227             : }
     228             : 
     229          66 : bool deserialize(std::string& data, ConnectionDescriptions& descriptions)
     230             : {
     231          66 :     if (!descriptions.empty())
     232           0 :         LBWARN << "Connection descriptions already hold data before deserialize"
     233           0 :                << std::endl;
     234             : 
     235             :     // num connection descriptions
     236          66 :     size_t nextPos = data.find(CO_SEPARATOR);
     237          66 :     if (nextPos == std::string::npos || nextPos == 0)
     238             :     {
     239           0 :         LBERROR << "Could not parse number of connection descriptions"
     240           0 :                 << std::endl;
     241           0 :         return false;
     242             :     }
     243             : 
     244         132 :     const std::string sizeStr = data.substr(0, nextPos);
     245          66 :     if (!isdigit(sizeStr[0]))
     246             :     {
     247           0 :         LBERROR << "Could not parse number of connection descriptions"
     248           0 :                 << std::endl;
     249           0 :         return false;
     250             :     }
     251             : 
     252          66 :     const size_t nDesc = atoi(sizeStr.c_str());
     253          66 :     data = data.substr(nextPos + 1);
     254             : 
     255             :     // connection descriptions
     256         131 :     for (size_t i = 0; i < nDesc; ++i)
     257             :     {
     258         130 :         ConnectionDescriptionPtr desc = new ConnectionDescription;
     259          65 :         if (!desc->fromString(data))
     260             :         {
     261           0 :             LBERROR << "Error during connection description parsing"
     262           0 :                     << std::endl;
     263           0 :             return false;
     264             :         }
     265          65 :         descriptions.push_back(desc);
     266             :     }
     267             : 
     268          66 :     return true;
     269             : }
     270             : 
     271           0 : std::ostream& operator<<(std::ostream& os, const ConnectionDescription& desc)
     272             : {
     273           0 :     os << lunchbox::disableFlush << lunchbox::disableHeader << "connection"
     274           0 :        << std::endl
     275           0 :        << "{" << std::endl
     276           0 :        << lunchbox::indent << "type          " << desc.type << std::endl
     277           0 :        << "hostname      \"" << desc.getHostname() << "\"" << std::endl;
     278             : 
     279           0 :     if (!desc.getInterface().empty())
     280           0 :         os << "interface     \"" << desc.getInterface() << "\"" << std::endl;
     281             : 
     282           0 :     if (desc.port != 0)
     283           0 :         os << "port          " << desc.port << std::endl;
     284             : 
     285           0 :     if (!desc.getFilename().empty())
     286           0 :         os << "filename      \"" << desc.getFilename() << "\"" << std::endl;
     287             : 
     288           0 :     if (desc.bandwidth != 0)
     289           0 :         os << "bandwidth     " << desc.bandwidth << std::endl;
     290             : 
     291           0 :     return os << lunchbox::exdent << "}" << lunchbox::enableHeader
     292           0 :               << lunchbox::enableFlush << std::endl;
     293             : }
     294          63 : }

Generated by: LCOV version 1.11