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 :
27 : #define SEPARATOR '#'
28 :
29 : namespace
30 : {
31 67 : static ConnectionType _getConnectionType( const std::string& string )
32 : {
33 67 : if( string == "TCPIP" )
34 67 : return CONNECTIONTYPE_TCPIP;
35 0 : if( string == "TCP" )
36 0 : return CONNECTIONTYPE_TCPIP;
37 0 : if( string == "ANON_PIPE" )
38 0 : return CONNECTIONTYPE_PIPE;
39 0 : if( string == "PIPE" )
40 0 : return CONNECTIONTYPE_NAMEDPIPE;
41 0 : if( string == "RSP" )
42 0 : return CONNECTIONTYPE_RSP;
43 0 : if( string == "RDMA" )
44 0 : return CONNECTIONTYPE_RDMA;
45 0 : if( string == "UDT" )
46 0 : return CONNECTIONTYPE_UDT;
47 :
48 0 : LBWARN << "Unknown connection type: " << string << std::endl;
49 0 : return CONNECTIONTYPE_NONE;
50 : }
51 : }
52 :
53 0 : ConnectionDescription::ConnectionDescription( std::string& data )
54 : : type( CONNECTIONTYPE_TCPIP )
55 : , bandwidth( 0 )
56 : , port( 0 )
57 0 : , filename( "default" )
58 : {
59 0 : fromString( data );
60 0 : LBASSERTINFO( data.empty(), data );
61 0 : }
62 :
63 1163 : std::string ConnectionDescription::toString() const
64 : {
65 1163 : std::ostringstream description;
66 1163 : serialize( description );
67 1163 : return description.str();
68 : }
69 :
70 1230 : void ConnectionDescription::serialize( std::ostream& os ) const
71 : {
72 1230 : os << type << SEPARATOR << bandwidth << SEPARATOR << hostname << SEPARATOR
73 2460 : << interfacename << SEPARATOR << port << SEPARATOR << filename
74 1230 : << SEPARATOR;
75 1230 : }
76 :
77 67 : bool ConnectionDescription::fromString( std::string& data )
78 : {
79 : {
80 67 : size_t nextPos = data.find( SEPARATOR );
81 : // assume hostname[:port][:type] or filename:PIPE format
82 67 : if( nextPos == std::string::npos )
83 : {
84 0 : type = CONNECTIONTYPE_TCPIP;
85 0 : nextPos = data.find( ':' );
86 0 : if( nextPos == std::string::npos ) // assume hostname format
87 : {
88 0 : hostname = data;
89 0 : data.clear();
90 0 : return true;
91 : }
92 :
93 0 : hostname = data.substr( 0, nextPos );
94 0 : data = data.substr( nextPos + 1 );
95 :
96 0 : while( nextPos != std::string::npos )
97 : {
98 0 : nextPos = data.find( ':' );
99 0 : const std::string token = data.substr( 0, nextPos );
100 0 : data = data.substr( nextPos + 1 );
101 :
102 0 : if( !token.empty() && isdigit( token[0] )) // port
103 0 : port = atoi( token.c_str( ));
104 : else
105 : {
106 0 : type = _getConnectionType( token );
107 0 : if( type == CONNECTIONTYPE_NAMEDPIPE )
108 : {
109 0 : filename = hostname;
110 0 : hostname.clear();
111 : }
112 0 : else if( type == CONNECTIONTYPE_NONE )
113 0 : goto error;
114 : }
115 0 : }
116 :
117 0 : data.clear();
118 0 : return true;
119 : }
120 :
121 : // else assume SEPARATOR-delimited list
122 67 : const std::string typeStr = data.substr( 0, nextPos );
123 67 : data = data.substr( nextPos + 1 );
124 :
125 67 : type = _getConnectionType( typeStr );
126 :
127 67 : nextPos = data.find( SEPARATOR );
128 67 : if( nextPos == std::string::npos )
129 0 : goto error;
130 :
131 134 : const std::string bandwidthStr = data.substr( 0, nextPos );
132 67 : data = data.substr( nextPos + 1 );
133 67 : bandwidth = atoi( bandwidthStr.c_str( ));
134 :
135 67 : nextPos = data.find( SEPARATOR );
136 67 : if( nextPos == std::string::npos )
137 0 : goto error;
138 :
139 67 : hostname = data.substr( 0, nextPos );
140 67 : data = data.substr( nextPos + 1 );
141 :
142 67 : nextPos = data.find( SEPARATOR );
143 67 : if( nextPos == std::string::npos )
144 0 : goto error;
145 :
146 67 : interfacename = data.substr( 0, nextPos );
147 67 : data = data.substr( nextPos + 1 );
148 :
149 67 : nextPos = data.find( SEPARATOR );
150 67 : if( nextPos == std::string::npos )
151 0 : goto error;
152 :
153 134 : const std::string portStr = data.substr( 0, nextPos );
154 67 : data = data.substr( nextPos + 1 );
155 67 : port = atoi( portStr.c_str( ));
156 :
157 67 : nextPos = data.find( SEPARATOR );
158 67 : if( nextPos == std::string::npos )
159 0 : goto error;
160 :
161 67 : filename = data.substr( 0, nextPos );
162 134 : data = data.substr( nextPos + 1 );
163 : }
164 67 : return true;
165 :
166 : error:
167 0 : LBWARN << "Could not parse connection description: " << data << std::endl;
168 0 : return false;
169 : }
170 :
171 128 : void ConnectionDescription::setHostname( const std::string& hostname_ )
172 : {
173 128 : hostname = hostname_;
174 128 : }
175 :
176 0 : void ConnectionDescription::setInterface( const std::string& interface_ )
177 : {
178 0 : interfacename = interface_;
179 0 : }
180 :
181 0 : void ConnectionDescription::setFilename( const std::string& filename_ )
182 : {
183 0 : filename = filename_;
184 0 : }
185 :
186 0 : const std::string& ConnectionDescription::getFilename() const
187 : {
188 0 : return filename;
189 : }
190 :
191 263 : const std::string& ConnectionDescription::getHostname() const
192 : {
193 263 : return hostname;
194 : }
195 :
196 0 : const std::string& ConnectionDescription::getInterface() const
197 : {
198 0 : return interfacename;
199 : }
200 :
201 0 : bool ConnectionDescription::isSameMulticastGroup(
202 : ConstConnectionDescriptionPtr rhs )
203 : {
204 0 : return( type >= CONNECTIONTYPE_MULTICAST && type == rhs->type &&
205 0 : hostname == rhs->hostname && port == rhs->port );
206 : }
207 :
208 0 : bool ConnectionDescription::operator == ( const ConnectionDescription& rhs )
209 : const
210 : {
211 0 : return type == rhs.type && bandwidth == rhs.bandwidth &&
212 0 : port == rhs.port && hostname == rhs.hostname &&
213 0 : interfacename == rhs.interfacename && filename == rhs.filename;
214 : }
215 :
216 68 : std::string serialize( const ConnectionDescriptions& descriptions )
217 : {
218 68 : std::ostringstream data;
219 68 : data << descriptions.size() << CO_SEPARATOR;
220 :
221 405 : for( ConnectionDescriptions::const_iterator i = descriptions.begin();
222 270 : i != descriptions.end(); ++i )
223 : {
224 67 : ConnectionDescriptionPtr desc = *i;
225 67 : desc->serialize( data );
226 67 : }
227 :
228 68 : return data.str();
229 : }
230 :
231 68 : bool deserialize( std::string& data, ConnectionDescriptions& descriptions )
232 : {
233 68 : if( !descriptions.empty( ))
234 0 : LBWARN << "Connection descriptions already hold data before deserialize"
235 0 : << std::endl;
236 :
237 : // num connection descriptions
238 68 : size_t nextPos = data.find( CO_SEPARATOR );
239 68 : if( nextPos == std::string::npos || nextPos == 0 )
240 : {
241 0 : LBERROR << "Could not parse number of connection descriptions"
242 0 : << std::endl;
243 0 : return false;
244 : }
245 :
246 68 : const std::string sizeStr = data.substr( 0, nextPos );
247 68 : if( !isdigit( sizeStr[0] ))
248 : {
249 0 : LBERROR << "Could not parse number of connection descriptions"
250 0 : << std::endl;
251 0 : return false;
252 : }
253 :
254 68 : const size_t nDesc = atoi( sizeStr.c_str( ));
255 68 : data = data.substr( nextPos + 1 );
256 :
257 : // connection descriptions
258 135 : for( size_t i = 0; i < nDesc; ++i )
259 : {
260 67 : ConnectionDescriptionPtr desc = new ConnectionDescription;
261 67 : if( !desc->fromString( data ))
262 : {
263 0 : LBERROR << "Error during connection description parsing"
264 0 : << std::endl;
265 0 : return false;
266 : }
267 67 : descriptions.push_back( desc );
268 67 : }
269 :
270 68 : return true;
271 : }
272 :
273 0 : std::ostream& operator << ( std::ostream& os,
274 : const ConnectionDescription& desc)
275 : {
276 0 : os << lunchbox::disableFlush << lunchbox::disableHeader << "connection"
277 0 : << std::endl
278 0 : << "{" << std::endl << lunchbox::indent
279 0 : << "type " << desc.type << std::endl
280 0 : << "hostname \"" << desc.getHostname() << "\"" << std::endl;
281 :
282 0 : if( !desc.getInterface().empty( ))
283 0 : os << "interface \"" << desc.getInterface() << "\"" << std::endl;
284 :
285 0 : if( desc.port != 0 )
286 0 : os << "port " << desc.port << std::endl;
287 :
288 0 : if( !desc.getFilename().empty( ))
289 0 : os << "filename \"" << desc.getFilename() << "\"" << std::endl;
290 :
291 0 : if( desc.bandwidth != 0 )
292 0 : os << "bandwidth " << desc.bandwidth << std::endl;
293 :
294 0 : return os << lunchbox::exdent << "}" << lunchbox::enableHeader
295 0 : << lunchbox::enableFlush << std::endl;
296 : }
297 :
298 66 : }
|