1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4
5 #include <Ice/OpaqueEndpointI.h>
6 #include <Ice/OutputStream.h>
7 #include <Ice/InputStream.h>
8 #include <Ice/Exception.h>
9 #include <Ice/DefaultsAndOverrides.h>
10 #include <Ice/Base64.h>
11 #include <Ice/HashUtil.h>
12 #include <Ice/LocalException.h>
13
14 using namespace std;
15 using namespace Ice;
16 using namespace IceInternal;
17
18 namespace
19 {
20
21 static string opaqueEndpointProtocol = "opaque";
22 static string opaqueEndpointConnectionId;
23
24 }
25
OpaqueEndpointI(vector<string> & args)26 IceInternal::OpaqueEndpointI::OpaqueEndpointI(vector<string>& args) :
27 _type(-1), _rawEncoding(Encoding_1_0)
28 {
29 initWithOptions(args);
30
31 if(_type < 0)
32 {
33 throw EndpointParseException(__FILE__, __LINE__, "no -t option in endpoint " + toString());
34 }
35 if(_rawBytes.empty())
36 {
37 throw EndpointParseException(__FILE__, __LINE__, "no -v option in endpoint " + toString());
38 }
39 }
40
OpaqueEndpointI(Short type,InputStream * s)41 IceInternal::OpaqueEndpointI::OpaqueEndpointI(Short type, InputStream* s) : _type(type)
42 {
43 _rawEncoding = s->getEncoding();
44 Int sz = s->getEncapsulationSize();
45 s->readBlob(const_cast<vector<Byte>&>(_rawBytes), sz);
46 }
47
48 namespace
49 {
50
51 class OpaqueEndpointInfoI : public Ice::OpaqueEndpointInfo
52 {
53 public:
54
55 OpaqueEndpointInfoI(Ice::Short type, const Ice::EncodingVersion& rawEncoding, const Ice::ByteSeq& rawBytes);
56
57 virtual Ice::Short
type() const58 type() const ICE_NOEXCEPT
59 {
60 return _type;
61 }
62
63 virtual bool
datagram() const64 datagram() const ICE_NOEXCEPT
65 {
66 return false;
67 }
68
69 virtual bool
secure() const70 secure() const ICE_NOEXCEPT
71 {
72 return false;
73 }
74
75 private:
76
77 Ice::Short _type;
78 };
79
80 }
81 //
82 // COMPILERFIX: inlining this constructor causes crashes with gcc 4.0.1.
83 //
OpaqueEndpointInfoI(Ice::Short type,const Ice::EncodingVersion & rawEncodingP,const Ice::ByteSeq & rawBytesP)84 OpaqueEndpointInfoI::OpaqueEndpointInfoI(Ice::Short type, const Ice::EncodingVersion& rawEncodingP,
85 const Ice::ByteSeq& rawBytesP) :
86 Ice::OpaqueEndpointInfo(ICE_NULLPTR, -1, false, rawEncodingP, rawBytesP),
87 _type(type)
88 {
89 }
90
91 void
streamWrite(OutputStream * s) const92 IceInternal::OpaqueEndpointI::streamWrite(OutputStream* s) const
93 {
94 s->startEncapsulation(_rawEncoding, ICE_ENUM(FormatType, DefaultFormat));
95 s->writeBlob(_rawBytes);
96 s->endEncapsulation();
97 }
98
99 Ice::EndpointInfoPtr
getInfo() const100 IceInternal::OpaqueEndpointI::getInfo() const ICE_NOEXCEPT
101 {
102 return ICE_MAKE_SHARED(OpaqueEndpointInfoI, _type, _rawEncoding, _rawBytes);
103 }
104
105 Short
type() const106 IceInternal::OpaqueEndpointI::type() const
107 {
108 return _type;
109 }
110
111 const string&
protocol() const112 IceInternal::OpaqueEndpointI::protocol() const
113 {
114 return opaqueEndpointProtocol;
115 }
116
117 Int
timeout() const118 IceInternal::OpaqueEndpointI::timeout() const
119 {
120 return -1;
121 }
122
123 EndpointIPtr
timeout(Int) const124 IceInternal::OpaqueEndpointI::timeout(Int) const
125 {
126 return ICE_SHARED_FROM_CONST_THIS(OpaqueEndpointI);
127 }
128
129 const string&
connectionId() const130 IceInternal::OpaqueEndpointI::connectionId() const
131 {
132 return opaqueEndpointConnectionId;
133 }
134
135 EndpointIPtr
connectionId(const string &) const136 IceInternal::OpaqueEndpointI::connectionId(const string&) const
137 {
138 return ICE_SHARED_FROM_CONST_THIS(OpaqueEndpointI);
139 }
140
141 bool
compress() const142 IceInternal::OpaqueEndpointI::compress() const
143 {
144 return false;
145 }
146
147 EndpointIPtr
compress(bool) const148 IceInternal::OpaqueEndpointI::compress(bool) const
149 {
150 return ICE_SHARED_FROM_CONST_THIS(OpaqueEndpointI);
151 }
152
153 bool
datagram() const154 IceInternal::OpaqueEndpointI::datagram() const
155 {
156 return false;
157 }
158
159 bool
secure() const160 IceInternal::OpaqueEndpointI::secure() const
161 {
162 return false;
163 }
164
165 TransceiverPtr
transceiver() const166 IceInternal::OpaqueEndpointI::transceiver() const
167 {
168 return ICE_NULLPTR;
169 }
170
171 void
connectors_async(Ice::EndpointSelectionType,const EndpointI_connectorsPtr & cb) const172 IceInternal::OpaqueEndpointI::connectors_async(Ice::EndpointSelectionType, const EndpointI_connectorsPtr& cb) const
173 {
174 cb->connectors(vector<ConnectorPtr>());
175 }
176
177 AcceptorPtr
acceptor(const string &) const178 IceInternal::OpaqueEndpointI::acceptor(const string&) const
179 {
180 return ICE_NULLPTR;
181 }
182
183 vector<EndpointIPtr>
expandIfWildcard() const184 IceInternal::OpaqueEndpointI::expandIfWildcard() const
185 {
186 vector<EndpointIPtr> endps;
187 endps.push_back(ICE_SHARED_FROM_CONST_THIS(OpaqueEndpointI));
188 return endps;
189 }
190
191 vector<EndpointIPtr>
expandHost(EndpointIPtr &) const192 IceInternal::OpaqueEndpointI::expandHost(EndpointIPtr&) const
193 {
194 vector<EndpointIPtr> endps;
195 endps.push_back(ICE_SHARED_FROM_CONST_THIS(OpaqueEndpointI));
196 return endps;
197 }
198
199 bool
equivalent(const EndpointIPtr &) const200 IceInternal::OpaqueEndpointI::equivalent(const EndpointIPtr&) const
201 {
202 return false;
203 }
204
205 Int
hash() const206 IceInternal::OpaqueEndpointI::hash() const
207 {
208 Int h = 5381;
209 hashAdd(h, type());
210 hashAdd(h, _rawEncoding.major);
211 hashAdd(h, _rawEncoding.minor);
212 hashAdd(h, _rawBytes);
213 return h;
214 }
215
216 string
options() const217 IceInternal::OpaqueEndpointI::options() const
218 {
219 ostringstream s;
220 if(_type > -1)
221 {
222 s << " -t " << _type;
223 }
224 s << " -e " << _rawEncoding;
225 if(!_rawBytes.empty())
226 {
227 s << " -v " << Base64::encode(_rawBytes);
228 }
229 return s.str();
230 }
231
232 bool
233 #ifdef ICE_CPP11_MAPPING
operator ==(const Endpoint & r) const234 IceInternal::OpaqueEndpointI::operator==(const Endpoint& r) const
235 #else
236 IceInternal::OpaqueEndpointI::operator==(const LocalObject& r) const
237 #endif
238 {
239 const OpaqueEndpointI* p = dynamic_cast<const OpaqueEndpointI*>(&r);
240 if(!p)
241 {
242 return false;
243 }
244
245 if(this == p)
246 {
247 return true;
248 }
249
250 if(_type != p->_type)
251 {
252 return false;
253 }
254
255 if(_rawEncoding != p->_rawEncoding)
256 {
257 return false;
258 }
259
260 if(_rawBytes != p->_rawBytes)
261 {
262 return false;
263 }
264
265 return true;
266 }
267
268 bool
269 #ifdef ICE_CPP11_MAPPING
operator <(const Endpoint & r) const270 IceInternal::OpaqueEndpointI::operator<(const Endpoint& r) const
271 #else
272 IceInternal::OpaqueEndpointI::operator<(const LocalObject& r) const
273 #endif
274 {
275 const OpaqueEndpointI* p = dynamic_cast<const OpaqueEndpointI*>(&r);
276 if(!p)
277 {
278 const EndpointI* e = dynamic_cast<const EndpointI*>(&r);
279 if(!e)
280 {
281 return false;
282 }
283 return type() < e->type();
284 }
285
286 if(this == p)
287 {
288 return false;
289 }
290
291 if(_type < p->_type)
292 {
293 return true;
294 }
295 else if(p->_type < _type)
296 {
297 return false;
298 }
299
300 if(_rawEncoding < p->_rawEncoding)
301 {
302 return true;
303 }
304 else if(p->_rawEncoding < _rawEncoding)
305 {
306 return false;
307 }
308
309 if(_rawBytes < p->_rawBytes)
310 {
311 return true;
312 }
313 else if(p->_rawBytes < _rawBytes)
314 {
315 return false;
316 }
317
318 return false;
319 }
320
321 void
streamWriteImpl(Ice::OutputStream *) const322 IceInternal::OpaqueEndpointI::streamWriteImpl(Ice::OutputStream*) const
323 {
324 assert(false);
325 }
326
327 bool
checkOption(const string & option,const string & argument,const string & endpoint)328 IceInternal::OpaqueEndpointI::checkOption(const string& option, const string& argument, const string& endpoint)
329 {
330 switch(option[1])
331 {
332 case 't':
333 {
334 if(_type > -1)
335 {
336 throw EndpointParseException(__FILE__, __LINE__, "multiple -t options in endpoint " + endpoint);
337 }
338 if(argument.empty())
339 {
340 throw EndpointParseException(__FILE__, __LINE__, "no argument provided for -t option in endpoint " +
341 endpoint);
342 }
343 istringstream p(argument);
344 Ice::Int t;
345 if(!(p >> t) || !p.eof())
346 {
347 throw EndpointParseException(__FILE__, __LINE__, "invalid type value `" + argument + "' in endpoint " +
348 endpoint);
349 }
350 else if(t < 0 || t > 65535)
351 {
352 throw EndpointParseException(__FILE__, __LINE__, "type value `" + argument + "' out of range in endpoint " +
353 endpoint);
354 }
355 _type = static_cast<Ice::Short>(t);
356 return true;
357 }
358
359 case 'v':
360 {
361 if(!_rawBytes.empty())
362 {
363 throw EndpointParseException(__FILE__, __LINE__, "multiple -v options in endpoint " + endpoint);
364 }
365 if(argument.empty())
366 {
367 throw EndpointParseException(__FILE__, __LINE__, "no argument provided for -v option in endpoint " + endpoint);
368 }
369 for(string::size_type i = 0; i < argument.size(); ++i)
370 {
371 if(!Base64::isBase64(argument[i]))
372 {
373 ostringstream os;
374 os << "invalid base64 character `" << argument[i] << "' (ordinal " << static_cast<int>(argument[i])
375 << ") in endpoint " << endpoint;
376 throw EndpointParseException(__FILE__, __LINE__, os.str());
377 }
378 }
379 const_cast<vector<Byte>&>(_rawBytes) = Base64::decode(argument);
380 return true;
381 }
382
383 case 'e':
384 {
385 if(argument.empty())
386 {
387 throw Ice::EndpointParseException(__FILE__, __LINE__, "no argument provided for -e option in endpoint " +
388 endpoint);
389 }
390
391 try
392 {
393 _rawEncoding = Ice::stringToEncodingVersion(argument);
394 }
395 catch(const Ice::VersionParseException& ex)
396 {
397 throw Ice::EndpointParseException(__FILE__, __LINE__, "invalid encoding version `" + argument +
398 "' in endpoint " + endpoint + ":\n" + ex.str);
399 }
400 return true;
401 }
402
403 default:
404 {
405 return false;
406 }
407 }
408 }
409