Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / TAO / tao / Strategies / COIOP_Profile.cpp
blobac5e6d6b0cdfe5f045d074a2036638a31cd2b876
1 #include "tao/Strategies/COIOP_Profile.h"
3 #if defined (TAO_HAS_COIOP) && (TAO_HAS_COIOP != 0)
5 #include "tao/CDR.h"
6 #include "tao/SystemException.h"
7 #include "tao/ORB.h"
8 #include "tao/ORB_Core.h"
9 #include "tao/debug.h"
10 #include "tao/Strategies/COIOP_EndpointsC.h"
12 #include "ace/OS_NS_stdio.h"
13 #include "ace/OS_NS_string.h"
15 static const char the_prefix[] = "niop";
17 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
19 const char TAO_COIOP_Profile::object_key_delimiter_ = '/';
21 char
22 TAO_COIOP_Profile::object_key_delimiter () const
24 return TAO_COIOP_Profile::object_key_delimiter_;
27 TAO_COIOP_Profile::TAO_COIOP_Profile (const ACE_Utils::UUID& uuid,
28 const TAO::ObjectKey &object_key,
29 const TAO_GIOP_Message_Version &version,
30 TAO_ORB_Core *orb_core)
31 : TAO_Profile (TAO_TAG_COIOP_PROFILE,
32 orb_core,
33 object_key,
34 version),
35 endpoint_ (uuid),
36 count_ (1)
40 TAO_COIOP_Profile::TAO_COIOP_Profile (TAO_ORB_Core *orb_core)
41 : TAO_Profile (TAO_TAG_COIOP_PROFILE,
42 orb_core,
43 TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR)),
44 endpoint_ (),
45 count_ (1)
49 TAO_COIOP_Profile::~TAO_COIOP_Profile ()
51 // Clean up the list of endpoints since we own it.
52 // Skip the head, since it is not dynamically allocated.
53 TAO_Endpoint *tmp = 0;
55 for (TAO_Endpoint *next = this->endpoint ()->next ();
56 next != 0;
57 next = tmp)
59 tmp = next->next ();
60 delete next;
64 // return codes:
65 // -1 -> error
66 // 0 -> can't understand this version
67 // 1 -> success.
69 int
70 TAO_COIOP_Profile::decode_profile (TAO_InputCDR& cdr)
72 // @@ NOTE: This code is repeated thrice. Need to factor out in a
73 // better manner.
74 // Decode uuid into the <endpoint_>.
75 CORBA::String_var uuid;
76 if (cdr.read_string (uuid.out ()) == 0)
78 if (TAO_debug_level > 0)
79 TAOLIB_DEBUG ((LM_DEBUG,
80 ACE_TEXT ("TAO (%P|%t) COIOP_Profile::decode - ")
81 ACE_TEXT ("error while uuid")));
82 return -1;
85 if (cdr.good_bit ())
87 this->endpoint_.uuid_.from_string (uuid.in());
89 return 1;
92 return -1;
95 void
96 TAO_COIOP_Profile::parse_string_i (const char *ior)
98 // Pull off the "hostname:port/" part of the objref
99 // Copy the string because we are going to modify it...
100 const char *okd =
101 std::strchr (ior, this->object_key_delimiter_);
103 if (okd == 0 || okd == ior)
105 // No object key delimiter or no hostname specified.
106 throw ::CORBA::INV_OBJREF (
107 CORBA::SystemException::_tao_minor_code (
108 TAO::VMCID,
109 EINVAL),
110 CORBA::COMPLETED_NO);
113 // Length of host string.
114 CORBA::ULong length_host = okd - ior;
116 CORBA::String_var tmp = CORBA::string_alloc (length_host);
118 // Skip the trailing '/'
119 ACE_OS::strncpy (tmp.inout (), ior, length_host);
120 tmp[length_host] = '\0';
122 this->endpoint_.uuid_.from_string (tmp._retn ());
124 TAO::ObjectKey ok;
125 TAO::ObjectKey::decode_string_to_sequence (ok,
126 okd + 1);
128 (void) this->orb_core ()->object_key_table ().bind (ok,
129 this->ref_object_key_);
132 CORBA::Boolean
133 TAO_COIOP_Profile::do_is_equivalent (const TAO_Profile *other_profile)
135 const TAO_COIOP_Profile *op =
136 dynamic_cast<const TAO_COIOP_Profile *> (other_profile);
138 // Check endpoints equivalence.
139 const TAO_COIOP_Endpoint *other_endp = &op->endpoint_;
140 for (TAO_COIOP_Endpoint *endp = &this->endpoint_;
141 endp != 0;
142 endp = endp->next_)
144 if (endp->is_equivalent (other_endp))
145 other_endp = other_endp->next_;
146 else
147 return false;
150 return true;
153 CORBA::ULong
154 TAO_COIOP_Profile::hash (CORBA::ULong max)
156 // Get the hashvalue for all endpoints.
157 CORBA::ULong hashval = 0;
158 for (TAO_COIOP_Endpoint *endp = &this->endpoint_;
159 endp != 0;
160 endp = endp->next_)
162 hashval += endp->hash ();
165 hashval += this->version_.minor;
166 hashval += this->tag ();
168 const TAO::ObjectKey &ok =
169 this->ref_object_key_->object_key ();
171 if (ok.length () >= 4)
173 hashval += ok[1];
174 hashval += ok[3];
177 hashval += this->hash_service_i (max);
179 return hashval % max;
182 TAO_Endpoint*
183 TAO_COIOP_Profile::endpoint ()
185 return &this->endpoint_;
188 CORBA::ULong
189 TAO_COIOP_Profile::endpoint_count () const
191 return this->count_;
194 void
195 TAO_COIOP_Profile::add_endpoint (TAO_COIOP_Endpoint *endp)
197 endp->next_ = this->endpoint_.next_;
198 this->endpoint_.next_ = endp;
200 this->count_++;
203 char *
204 TAO_COIOP_Profile::to_string () const
206 CORBA::String_var key;
207 TAO::ObjectKey::encode_sequence_to_string (key.inout(),
208 this->ref_object_key_->object_key ());
210 const ACE_CString * uuidstr = this->endpoint_.uuid_.to_string ();
211 size_t buflen = (8 /* "corbaloc" */ +
212 1 /* colon separator */ +
213 ACE_OS::strlen (::the_prefix) +
214 1 /* colon separator */ +
215 1 /* major version */ +
216 1 /* decimal point */ +
217 1 /* minor version */ +
218 1 /* `@' character */ +
219 uuidstr->length() +
220 1 /* colon separator */ +
221 5 /* port number */ +
222 1 /* object key separator */ +
223 ACE_OS::strlen (key.in ()));
225 char * buf = CORBA::string_alloc (static_cast<CORBA::ULong> (buflen));
227 static const char digits [] = "0123456789";
229 ACE_OS::sprintf (buf,
230 "corbaloc:%s:%c.%c@%s%c%s",
231 ::the_prefix,
232 digits [this->version_.major],
233 digits [this->version_.minor],
234 uuidstr->c_str (),
235 this->object_key_delimiter_,
236 key.in ());
238 return buf;
241 const char *
242 TAO_COIOP_Profile::prefix ()
244 return ::the_prefix;
247 void
248 TAO_COIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
250 encap.write_octet (TAO_ENCAP_BYTE_ORDER);
252 // The GIOP version
253 encap.write_octet (this->version_.major);
254 encap.write_octet (this->version_.minor);
256 // STRING hostname from profile
257 const ACE_CString * uuid_str = this->endpoint_.uuid_.to_string();
258 encap.write_string (uuid_str->c_str ());
260 // OCTET SEQUENCE for object key
261 if (this->ref_object_key_)
262 encap << this->ref_object_key_->object_key ();
263 else
265 TAOLIB_ERROR ((LM_ERROR,
266 "(%P|%t) TAO - COIOP_Profile::create_profile_body "
267 "no object key marshalled\n"));
270 if (this->version_.major > 1
271 || this->version_.minor > 0)
272 this->tagged_components ().encode (encap);
276 TAO_COIOP_Profile::encode_endpoints ()
278 // Create a data structure and fill it with endpoint info for wire
279 // transfer.
280 // We include information for the head of the list
281 // together with other endpoints because even though its addressing
282 // info is transmitted using standard ProfileBody components, its
283 // priority is not!
285 TAO::COIOPEndpointSequence endpoints;
286 endpoints.length (this->count_);
288 const TAO_COIOP_Endpoint *endpoint = &this->endpoint_;
289 for (CORBA::ULong i = 0;
290 i < this->count_;
291 ++i)
293 const ACE_CString* uuidstr = endpoint->uuid_.to_string();
294 CORBA::String_var uuid (uuidstr->c_str());
295 endpoints[i].uuid = uuid;
296 endpoints[i].priority = endpoint->priority ();
298 endpoint = endpoint->next_;
301 // Encode the data structure.
302 TAO_OutputCDR out_cdr;
303 if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)
304 == 0)
305 || (out_cdr << endpoints) == 0)
306 return -1;
307 size_t length = out_cdr.total_length ();
309 IOP::TaggedComponent tagged_component;
310 tagged_component.tag = TAO_TAG_ENDPOINTS;
311 tagged_component.component_data.length (static_cast<CORBA::ULong> (length));
312 CORBA::Octet *buf =
313 tagged_component.component_data.get_buffer ();
315 for (const ACE_Message_Block *iterator = out_cdr.begin ();
316 iterator != 0;
317 iterator = iterator->cont ())
319 size_t i_length = iterator->length ();
320 ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
322 buf += i_length;
325 // Add component with encoded endpoint data to this profile's
326 // TaggedComponents.
327 tagged_components_.set_component (tagged_component);
329 return 0;
333 TAO_COIOP_Profile::decode_endpoints ()
335 IOP::TaggedComponent tagged_component;
336 tagged_component.tag = TAO_TAG_ENDPOINTS;
338 if (this->tagged_components_.get_component (tagged_component))
340 const CORBA::Octet *buf =
341 tagged_component.component_data.get_buffer ();
343 TAO_InputCDR in_cdr (reinterpret_cast<const char*> (buf),
344 tagged_component.component_data.length ());
346 // Extract the Byte Order.
347 CORBA::Boolean byte_order;
348 if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
349 return -1;
350 in_cdr.reset_byte_order (static_cast<int> (byte_order));
352 // Extract endpoints sequence.
353 TAO::COIOPEndpointSequence endpoints;
355 if (! (in_cdr >> endpoints))
356 return -1;
358 // Get the priority of the first endpoint (head of the list.
359 // It's other data is extracted as part of the standard profile
360 // decoding.
361 this->endpoint_.priority (endpoints[0].priority);
363 // Use information extracted from the tagged component to
364 // populate the profile. Skip the first endpoint, since it is
365 // always extracted through standard profile body. Also, begin
366 // from the end of the sequence to preserve endpoint order,
367 // since <add_endpoint> method reverses the order of endpoints
368 // in the list.
369 for (CORBA::ULong i = endpoints.length () - 1;
370 i > 0;
371 --i)
373 TAO_COIOP_Endpoint *endpoint = 0;
374 CORBA::String_var strvar = CORBA::string_dup (endpoints[i].uuid);
375 ACE_Utils::UUID uuid1 (strvar.in());
376 ACE_NEW_RETURN (endpoint,
377 TAO_COIOP_Endpoint (uuid1),
378 -1);
380 this->add_endpoint (endpoint);
384 return 0;
387 TAO_END_VERSIONED_NAMESPACE_DECL
389 #endif /* TAO_HAS_COIOP && TAO_HAS_COIOP != 0 */