Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / Strategies / UIOP_Profile.cpp
blob0280b6ee4e74ac55e0624aedfe04f97857fc25f9
1 #include "tao/Strategies/UIOP_Profile.h"
3 #if TAO_HAS_UIOP == 1
5 #include "tao/Strategies/uiop_endpointsC.h"
7 #include "tao/CDR.h"
8 #include "tao/SystemException.h"
9 #include "tao/ORB.h"
10 #include "tao/ORB_Core.h"
11 #include "tao/debug.h"
13 #include "ace/OS_NS_stdio.h"
14 #include "ace/OS_NS_string.h"
15 #include "ace/OS_NS_ctype.h"
16 #include <cstring>
18 static const char prefix_[] = "uiop";
20 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
22 const char TAO_UIOP_Profile::object_key_delimiter_ = '|';
24 char
25 TAO_UIOP_Profile::object_key_delimiter () const
27 return TAO_UIOP_Profile::object_key_delimiter_;
30 TAO_UIOP_Profile::TAO_UIOP_Profile (const ACE_UNIX_Addr &addr,
31 const TAO::ObjectKey &object_key,
32 const TAO_GIOP_Message_Version &version,
33 TAO_ORB_Core *orb_core)
34 : TAO_Profile (TAO_TAG_UIOP_PROFILE,
35 orb_core,
36 object_key,
37 version),
38 endpoint_ (addr),
39 count_ (1)
43 TAO_UIOP_Profile::TAO_UIOP_Profile (const char *,
44 const TAO::ObjectKey &object_key,
45 const ACE_UNIX_Addr &addr,
46 const TAO_GIOP_Message_Version &version,
47 TAO_ORB_Core *orb_core)
48 : TAO_Profile (TAO_TAG_UIOP_PROFILE,
49 orb_core,
50 object_key,
51 version),
52 endpoint_ (addr),
53 count_ (1)
57 TAO_UIOP_Profile::TAO_UIOP_Profile (TAO_ORB_Core *orb_core)
58 : TAO_Profile (TAO_TAG_UIOP_PROFILE,
59 orb_core,
60 TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR,
61 TAO_DEF_GIOP_MINOR)),
62 endpoint_ (),
63 count_ (1)
67 TAO_UIOP_Profile::~TAO_UIOP_Profile ()
69 // Clean up the list of endpoints since we own it.
70 // Skip the head, since it is not dynamically allocated.
71 TAO_Endpoint *tmp = 0;
73 for (TAO_Endpoint *next = this->endpoint ()->next ();
74 next != 0;
75 next = tmp)
77 tmp = next->next ();
78 delete next;
82 TAO_Endpoint*
83 TAO_UIOP_Profile::endpoint ()
85 return &this->endpoint_;
88 CORBA::ULong
89 TAO_UIOP_Profile::endpoint_count () const
91 return this->count_;
94 void
95 TAO_UIOP_Profile::parse_string_i (const char *string)
97 if (!string || !*string)
99 throw ::CORBA::INV_OBJREF (
100 CORBA::SystemException::_tao_minor_code (
102 EINVAL),
103 CORBA::COMPLETED_NO);
106 // Remove the "N.n@" version prefix, if it exists, and verify the
107 // version is one that we accept.
109 // Check for version
110 if (ACE_OS::ace_isdigit (string [0]) &&
111 string[1] == '.' &&
112 ACE_OS::ace_isdigit (string [2]) &&
113 string[3] == '@')
115 // @@ This may fail for non-ascii character sets [but take that
116 // with a grain of salt]
117 this->version_.set_version ((char) (string [0] - '0'),
118 (char) (string [2] - '0'));
119 string += 4;
120 // Skip over the "N.n@"
123 if (this->version_.major != TAO_DEF_GIOP_MAJOR ||
124 this->version_.minor > TAO_DEF_GIOP_MINOR)
126 throw ::CORBA::INV_OBJREF (
127 CORBA::SystemException::_tao_minor_code (
129 EINVAL),
130 CORBA::COMPLETED_NO);
134 // Pull off the "rendezvous point" part of the objref
135 // Copy the string because we are going to modify it...
136 CORBA::String_var copy (string);
138 char *start = copy.inout ();
139 char *cp = std::strchr (start, this->object_key_delimiter_);
141 if (cp == 0)
143 throw ::CORBA::INV_OBJREF (
144 CORBA::SystemException::_tao_minor_code (
145 TAO::VMCID,
146 EINVAL),
147 CORBA::COMPLETED_NO);
148 // No rendezvous point specified
151 CORBA::ULong length = cp - start;
153 CORBA::String_var rendezvous = CORBA::string_alloc (length);
155 ACE_OS::strncpy (rendezvous.inout (), start, length);
156 rendezvous[length] = '\0';
158 if (this->endpoint_.object_addr_.set (rendezvous.in ()) != 0)
160 throw ::CORBA::INV_OBJREF (
161 CORBA::SystemException::_tao_minor_code (
162 TAO::VMCID,
163 EINVAL),
164 CORBA::COMPLETED_NO);
167 start = ++cp; // increment past the object key separator
169 TAO::ObjectKey ok;
170 TAO::ObjectKey::decode_string_to_sequence (ok,
171 start);
173 (void) this->orb_core ()->object_key_table ().bind (ok,
174 this->ref_object_key_);
177 CORBA::Boolean
178 TAO_UIOP_Profile::do_is_equivalent (const TAO_Profile *other_profile)
180 const TAO_UIOP_Profile *op =
181 dynamic_cast <const TAO_UIOP_Profile *> (other_profile);
183 if (op == 0)
184 return false;
186 // Check endpoints equivalence.
187 const TAO_UIOP_Endpoint *other_endp = &op->endpoint_;
188 for (TAO_UIOP_Endpoint *endp = &this->endpoint_;
189 endp != 0;
190 endp = endp->next_)
192 if (endp->is_equivalent (other_endp))
193 other_endp = other_endp->next_;
194 else
195 return false;
198 return true;
201 CORBA::ULong
202 TAO_UIOP_Profile::hash (CORBA::ULong max)
204 // Get the hashvalue for all endpoints.
205 CORBA::ULong hashval = 0;
206 for (TAO_UIOP_Endpoint *endp = &this->endpoint_;
207 endp != 0;
208 endp = endp->next_)
210 hashval += endp->hash ();
213 hashval += this->version_.minor;
214 hashval += this->tag ();
216 const TAO::ObjectKey &ok =
217 this->ref_object_key_->object_key ();
219 if (ok.length () >= 4)
221 hashval += ok[1];
222 hashval += ok[3];
225 hashval += this->hash_service_i (max);
227 return hashval % max;
230 void
231 TAO_UIOP_Profile::add_endpoint (TAO_UIOP_Endpoint *endp)
233 endp->next_ = this->endpoint_.next_;
234 this->endpoint_.next_ = endp;
236 this->count_++;
240 char *
241 TAO_UIOP_Profile::to_string () const
243 CORBA::String_var key;
244 TAO::ObjectKey::encode_sequence_to_string (key.inout(),
245 this->ref_object_key_->object_key ());
247 u_int buflen = (8 /* "corbaloc" */ +
248 1 /* colon separator */ +
249 ACE_OS::strlen (::prefix_) +
250 1 /* colon separator */ +
251 1 /* major version */ +
252 1 /* decimal point */ +
253 1 /* minor version */ +
254 1 /* `@' character */ +
255 ACE_OS::strlen (this->endpoint_.rendezvous_point ()) +
256 1 /* object key separator */ +
257 ACE_OS::strlen (key.in ()));
259 char * buf = CORBA::string_alloc (buflen);
261 static const char digits [] = "0123456789";
263 ACE_OS::sprintf (buf,
264 "corbaloc:%s:%c.%c@%s%c%s",
265 ::prefix_,
266 digits [this->version_.major],
267 digits [this->version_.minor],
268 this->endpoint_.rendezvous_point (),
269 this->object_key_delimiter_,
270 key.in ());
271 return buf;
274 const char *
275 TAO_UIOP_Profile::prefix ()
277 return ::prefix_;
281 TAO_UIOP_Profile::decode_profile (TAO_InputCDR& cdr)
283 char *rendezvous = 0;
285 // Get rendezvous_point
286 if (cdr.read_string (rendezvous) == 0)
288 TAOLIB_DEBUG ((LM_DEBUG, "error decoding UIOP rendezvous_point"));
289 return -1;
292 if (this->endpoint_.object_addr_.set (rendezvous) == -1)
294 // In the case of an ACE_UNIX_Addr, this should call should
295 // never fail!
297 // If the call fails, allow the profile to be created, and rely
298 // on TAO's connection handling to throw the appropriate
299 // exception.
300 if (TAO_debug_level > 0)
302 TAOLIB_DEBUG ((LM_DEBUG,
303 ACE_TEXT ("TAO (%P|%t) UIOP_Profile::decode - ")
304 ACE_TEXT ("ACE_UNIX_Addr::set() failed\n")));
308 // Clean up
309 delete [] rendezvous;
311 return 1;
314 void
315 TAO_UIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
317 // CHAR describing byte order, starting the encapsulation
318 encap.write_octet (TAO_ENCAP_BYTE_ORDER);
320 // The GIOP version
321 encap.write_octet (this->version_.major);
322 encap.write_octet (this->version_.minor);
324 // STRING rendezvous_pointname from profile
325 encap.write_string (this->endpoint_.rendezvous_point ());
327 // OCTET SEQUENCE for object key
328 if (this->ref_object_key_)
329 encap << this->ref_object_key_->object_key ();
330 else
332 TAOLIB_ERROR ((LM_ERROR,
333 "(%P|%t) TAO - UIOP_Profile::create_profile_body "
334 "no object key marshalled\n"));
337 if (this->version_.major > 1
338 || this->version_.minor > 0)
339 this->tagged_components ().encode (encap);
343 TAO_UIOP_Profile::encode_endpoints ()
345 // Create a data structure and fill it with endpoint info for wire
346 // transfer.
347 // We include information for the head of the list
348 // together with other endpoints because even though its addressing
349 // info is transmitted using standard ProfileBody components, its
350 // priority is not!
351 TAO_UIOPEndpointSequence endpoints;
352 endpoints.length (this->count_);
354 TAO_UIOP_Endpoint *endpoint = &this->endpoint_;
355 for (size_t i = 0;
356 i < this->count_;
357 ++i)
359 endpoints[i].rendezvous_point = endpoint->rendezvous_point ();
360 endpoints[i].priority = endpoint->priority ();
362 endpoint = endpoint->next_;
365 // Encode the data structure.
366 TAO_OutputCDR out_cdr;
367 if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)) == 0
368 || (out_cdr << endpoints) == 0)
369 return -1;
371 this->set_tagged_components (out_cdr);
373 return 0;
377 TAO_UIOP_Profile::decode_endpoints ()
379 IOP::TaggedComponent tagged_component;
380 tagged_component.tag = TAO_TAG_ENDPOINTS;
382 if (this->tagged_components_.get_component (tagged_component))
384 const CORBA::Octet *buf =
385 tagged_component.component_data.get_buffer ();
387 TAO_InputCDR in_cdr (reinterpret_cast <const char*>(buf),
388 tagged_component.component_data.length ());
390 // Extract the Byte Order.
391 CORBA::Boolean byte_order;
392 if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
393 return -1;
394 in_cdr.reset_byte_order (static_cast<int>(byte_order));
396 // Extract endpoints sequence.
397 TAO_UIOPEndpointSequence endpoints;
399 if ((in_cdr >> endpoints) == 0)
400 return -1;
402 // Get the priority of the first endpoint (head of the list.
403 // It's other data is extracted as part of the standard profile
404 // decoding.
405 this->endpoint_.priority (endpoints[0].priority);
407 // Use information extracted from the tagged component to
408 // populate the profile. Skip the first endpoint, since it is
409 // always extracted through standard profile body. Also, begin
410 // from the end of the sequence to preserve endpoint order,
411 // since <add_endpoint> method reverses the order of endpoints
412 // in the list.
413 for (CORBA::ULong i = endpoints.length () - 1;
414 i > 0;
415 --i)
417 TAO_UIOP_Endpoint *endpoint = 0;
418 ACE_NEW_RETURN (endpoint,
419 TAO_UIOP_Endpoint,
420 -1);
421 this->add_endpoint (endpoint);
422 if (endpoint->object_addr_.set
423 (endpoints[i].rendezvous_point)
424 == -1)
426 // In the case of an ACE_UNIX_Addr, this should call should
427 // never fail!
428 // If the call fails, allow the profile to be created, and rely
429 // on TAO's connection handling to throw the appropriate
430 // exception.
431 if (TAO_debug_level > 0)
433 TAOLIB_DEBUG ((LM_DEBUG,
434 ACE_TEXT ("TAO (%P|%t) UIOP_Profile::decode_endpoints - ")
435 ACE_TEXT ("ACE_UNIX_Addr::set() failed\n")));
439 endpoint->priority (endpoints[i].priority);
443 return 0;
446 TAO_END_VERSIONED_NAMESPACE_DECL
448 #endif /* TAO_HAS_UIOP == 1 */