1 #include "tao/Strategies/UIOP_Profile.h"
5 #include "tao/Strategies/uiop_endpointsC.h"
8 #include "tao/SystemException.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"
18 static const char prefix_
[] = "uiop";
20 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
22 const char TAO_UIOP_Profile::object_key_delimiter_
= '|';
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
,
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
,
57 TAO_UIOP_Profile::TAO_UIOP_Profile (TAO_ORB_Core
*orb_core
)
58 : TAO_Profile (TAO_TAG_UIOP_PROFILE
,
60 TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR
,
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 ();
83 TAO_UIOP_Profile::endpoint ()
85 return &this->endpoint_
;
89 TAO_UIOP_Profile::endpoint_count () const
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 (
103 CORBA::COMPLETED_NO
);
106 // Remove the "N.n@" version prefix, if it exists, and verify the
107 // version is one that we accept.
110 if (ACE_OS::ace_isdigit (string
[0]) &&
112 ACE_OS::ace_isdigit (string
[2]) &&
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'));
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 (
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_
);
143 throw ::CORBA::INV_OBJREF (
144 CORBA::SystemException::_tao_minor_code (
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 (
164 CORBA::COMPLETED_NO
);
167 start
= ++cp
; // increment past the object key separator
170 TAO::ObjectKey::decode_string_to_sequence (ok
,
173 (void) this->orb_core ()->object_key_table ().bind (ok
,
174 this->ref_object_key_
);
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
);
186 // Check endpoints equivalence.
187 const TAO_UIOP_Endpoint
*other_endp
= &op
->endpoint_
;
188 for (TAO_UIOP_Endpoint
*endp
= &this->endpoint_
;
192 if (endp
->is_equivalent (other_endp
))
193 other_endp
= other_endp
->next_
;
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_
;
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)
225 hashval
+= this->hash_service_i (max
);
227 return hashval
% max
;
231 TAO_UIOP_Profile::add_endpoint (TAO_UIOP_Endpoint
*endp
)
233 endp
->next_
= this->endpoint_
.next_
;
234 this->endpoint_
.next_
= endp
;
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",
266 digits
[this->version_
.major
],
267 digits
[this->version_
.minor
],
268 this->endpoint_
.rendezvous_point (),
269 this->object_key_delimiter_
,
275 TAO_UIOP_Profile::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"));
292 if (this->endpoint_
.object_addr_
.set (rendezvous
) == -1)
294 // In the case of an ACE_UNIX_Addr, this should call should
297 // If the call fails, allow the profile to be created, and rely
298 // on TAO's connection handling to throw the appropriate
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")));
309 delete [] rendezvous
;
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
);
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 ();
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
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
351 TAO_UIOPEndpointSequence endpoints
;
352 endpoints
.length (this->count_
);
354 TAO_UIOP_Endpoint
*endpoint
= &this->endpoint_
;
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)
371 this->set_tagged_components (out_cdr
);
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)
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)
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
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
413 for (CORBA::ULong i
= endpoints
.length () - 1;
417 TAO_UIOP_Endpoint
*endpoint
= 0;
418 ACE_NEW_RETURN (endpoint
,
421 this->add_endpoint (endpoint
);
422 if (endpoint
->object_addr_
.set
423 (endpoints
[i
].rendezvous_point
)
426 // In the case of an ACE_UNIX_Addr, this should call should
428 // If the call fails, allow the profile to be created, and rely
429 // on TAO's connection handling to throw the appropriate
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
);
446 TAO_END_VERSIONED_NAMESPACE_DECL
448 #endif /* TAO_HAS_UIOP == 1 */