lib/net/connectionDescription.cpp

00001 
00002 /* Copyright (c) 2005-2009, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #include "connectionDescription.h"
00019 
00020 #include <sstream>
00021 
00022 using namespace std;
00023 
00024 namespace eq
00025 {
00026 namespace net
00027 {
00028 
00029 #define SEPARATOR '#'
00030 
00031 string ConnectionDescription::toString() const
00032 {
00033     ostringstream description;
00034     serialize( description );
00035     return description.str();
00036 }
00037 
00038 void ConnectionDescription::serialize( std::ostream& os ) const
00039 {
00040     switch( type )
00041     {
00042         case CONNECTIONTYPE_TCPIP:
00043             os << "TCPIP";
00044             break;
00045 
00046         case CONNECTIONTYPE_SDP:
00047             os << "SDP";
00048             break;
00049 
00050         case CONNECTIONTYPE_PIPE:
00051             os << "ANON_PIPE";
00052             break;
00053 
00054         case CONNECTIONTYPE_NAMEDPIPE:
00055             os << "PIPE";
00056             break;
00057     }        
00058 
00059     os << SEPARATOR << bandwidth << SEPARATOR << _launchCommand 
00060        << SEPARATOR << static_cast<int>( launchCommandQuote )
00061        << SEPARATOR << launchTimeout << SEPARATOR << _hostname ;
00062     
00063     switch( type )
00064     {
00065         case CONNECTIONTYPE_TCPIP:
00066         case CONNECTIONTYPE_SDP:
00067             os << SEPARATOR << TCPIP.port;
00068             break;
00069         case CONNECTIONTYPE_NAMEDPIPE:
00070             os << SEPARATOR << _filename;
00071             break;
00072 
00073         default:
00074             break;
00075     }
00076     os << SEPARATOR;
00077 }
00078 
00079 bool ConnectionDescription::fromString( std::string& data )
00080 {
00081     {
00082         size_t nextPos = data.find( SEPARATOR );
00083         // assume hostname[:port[:type]|:type] or filename:PIPE format
00084         if( nextPos == string::npos )
00085         {
00086             type     = CONNECTIONTYPE_TCPIP;
00087             nextPos = data.find( ':' );
00088             if( nextPos == string::npos ) // assume hostname format
00089             {
00090                 _hostname = data;
00091                 data.clear();
00092                 return true;
00093             }
00094 
00095             _hostname = data.substr( 0, nextPos );
00096             data      = data.substr( nextPos + 1 );
00097 
00098             while( nextPos != string::npos )
00099             {
00100                 nextPos            = data.find( ':' );
00101                 const string token = data.substr( 0, nextPos );
00102                 data               = data.substr( nextPos + 1 );
00103                 
00104                 if( !token.empty() && isdigit( token[0] )) // port
00105                     TCPIP.port = atoi( token.c_str( ));
00106                 else if( token == "TCPIP" )
00107                     type = CONNECTIONTYPE_TCPIP;
00108                 else if( token == "SDP" )
00109                     type = CONNECTIONTYPE_SDP;
00110                 else if( token == "PIPE" )
00111                 {
00112                     type = CONNECTIONTYPE_NAMEDPIPE;
00113                     setFilename( _hostname );
00114                     _hostname ="";
00115                 }
00116                 else
00117                     goto error;
00118             }
00119 
00120             data.clear();
00121             return true;
00122         }
00123 
00124         // else assume SEPARATOR-delimeted list
00125         const string typeStr = data.substr( 0, nextPos );
00126         data                 = data.substr( nextPos + 1 );
00127 
00128         if( typeStr == "TCPIP" )
00129             type = CONNECTIONTYPE_TCPIP;
00130         else if( typeStr == "SDP" )
00131             type = CONNECTIONTYPE_SDP;
00132         else if( typeStr == "ANON_PIPE" )
00133             type = CONNECTIONTYPE_PIPE;
00134         else if( typeStr == "PIPE" )
00135             type = CONNECTIONTYPE_NAMEDPIPE;
00136         else
00137             goto error;
00138 
00139         nextPos = data.find( SEPARATOR );
00140         if( nextPos == string::npos )
00141             goto error;
00142 
00143         const string bandwidthStr = data.substr( 0, nextPos );
00144         data                      = data.substr( nextPos + 1 );
00145         bandwidth = atoi( bandwidthStr.c_str( ));
00146     
00147         nextPos = data.find( SEPARATOR );
00148         if( nextPos == string::npos )
00149             goto error;
00150         _launchCommand = data.substr( 0, nextPos );
00151         data           = data.substr( nextPos + 1 );
00152 
00153         nextPos = data.find( SEPARATOR );
00154         if( nextPos == string::npos )
00155             goto error;
00156         const string quoteStr = data.substr( 0, nextPos );
00157         launchCommandQuote = static_cast< char >( atoi( quoteStr.c_str( )));
00158         data               = data.substr( nextPos + 1 );
00159 
00160         nextPos = data.find( SEPARATOR );
00161         if( nextPos == string::npos )
00162             goto error;
00163 
00164         const string launchTimeoutStr = data.substr( 0, nextPos );
00165         data                          = data.substr( nextPos + 1 );
00166         launchTimeout = atoi( launchTimeoutStr.c_str( ));
00167 
00168         nextPos = data.find( SEPARATOR );
00169         if( nextPos == string::npos )
00170             goto error;
00171 
00172         _hostname = data.substr( 0, nextPos );
00173         data      = data.substr( nextPos + 1 );
00174 
00175         switch( this->type )
00176         {
00177             case CONNECTIONTYPE_TCPIP:
00178             case CONNECTIONTYPE_SDP:
00179             {
00180                 nextPos = data.find( SEPARATOR );
00181                 if( nextPos == string::npos )
00182                     goto error;
00183             
00184                 const string port = data.substr( 0, nextPos );
00185                 data              = data.substr( nextPos + 1 );
00186                 TCPIP.port        = atoi( port.c_str( ));
00187                 break;
00188             }
00189             case CONNECTIONTYPE_NAMEDPIPE:
00190             {
00191                 nextPos = data.find( SEPARATOR );
00192                 if( nextPos == string::npos )
00193                     goto error;
00194                 
00195                 _filename         = data.substr( 0, nextPos );
00196                 data              = data.substr( nextPos + 1 );
00197                 break;
00198             }
00199             default:
00200                 break;
00201         }
00202     }
00203     return true;
00204 
00205   error:
00206     EQWARN << "Could not parse connection description: " << data << endl;
00207     return false;
00208 }
00209 
00210 void ConnectionDescription::setHostname( const std::string& hostname )
00211 {
00212     _hostname = hostname;
00213 }
00214 
00215 void ConnectionDescription::setFilename( const std::string& filename )
00216 {
00217     _filename = filename;
00218 }
00219 
00220 const std::string& ConnectionDescription::getFilename() const
00221 {
00222     return _filename;
00223 }
00224 const string& ConnectionDescription::getHostname() const
00225 {
00226     return _hostname;
00227 }
00228 
00229 void ConnectionDescription::setLaunchCommand( const std::string& launchCommand )
00230 {
00231     _launchCommand = launchCommand;
00232 }
00233 
00234 const string& ConnectionDescription::getLaunchCommand() const
00235 {
00236     return _launchCommand;
00237 }
00238 
00239 EQ_EXPORT std::ostream& operator << ( std::ostream& os, 
00240                                       const ConnectionDescription* desc)
00241 {
00242     if( !desc )
00243     {
00244         os << "NULL connection description";
00245         return os;
00246     }
00247 
00248     os << "connection " << ( desc->type == CONNECTIONTYPE_TCPIP ? "tcp/ip":
00249                              desc->type == CONNECTIONTYPE_SDP   ? "sdp"   :
00250                              desc->type == CONNECTIONTYPE_PIPE  ? "anonpipe" :
00251                              desc->type == CONNECTIONTYPE_NAMEDPIPE  ? "pipe" :
00252                              "ERROR" ) 
00253        << ' ' << desc->getHostname() << ':';
00254 
00255     switch( desc->type )
00256     {
00257         case CONNECTIONTYPE_TCPIP:
00258         case CONNECTIONTYPE_SDP:
00259             os << desc->TCPIP.port;
00260             break;
00261 
00262         case CONNECTIONTYPE_NAMEDPIPE:
00263             os << desc->getFilename();
00264             break;
00265 
00266         default:
00267         case CONNECTIONTYPE_PIPE:
00268             break;
00269     }
00270 
00271     return os;
00272 }
00273 
00274 
00275 }
00276 }
Generated on Mon Aug 10 18:58:32 2009 for Equalizer 0.9 by  doxygen 1.5.8