1 #include "tao/Strategies/COIOP_Profile.h"
3 #if defined (TAO_HAS_COIOP) && (TAO_HAS_COIOP != 0)
6 #include "tao/SystemException.h"
8 #include "tao/ORB_Core.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_
= '/';
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
,
40 TAO_COIOP_Profile::TAO_COIOP_Profile (TAO_ORB_Core
*orb_core
)
41 : TAO_Profile (TAO_TAG_COIOP_PROFILE
,
43 TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR
, TAO_DEF_GIOP_MINOR
)),
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 ();
66 // 0 -> can't understand this version
70 TAO_COIOP_Profile::decode_profile (TAO_InputCDR
& cdr
)
72 // @@ NOTE: This code is repeated thrice. Need to factor out in a
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")));
87 this->endpoint_
.uuid_
.from_string (uuid
.in());
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...
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 (
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 ());
125 TAO::ObjectKey::decode_string_to_sequence (ok
,
128 (void) this->orb_core ()->object_key_table ().bind (ok
,
129 this->ref_object_key_
);
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_
;
144 if (endp
->is_equivalent (other_endp
))
145 other_endp
= other_endp
->next_
;
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_
;
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)
177 hashval
+= this->hash_service_i (max
);
179 return hashval
% max
;
183 TAO_COIOP_Profile::endpoint ()
185 return &this->endpoint_
;
189 TAO_COIOP_Profile::endpoint_count () const
195 TAO_COIOP_Profile::add_endpoint (TAO_COIOP_Endpoint
*endp
)
197 endp
->next_
= this->endpoint_
.next_
;
198 this->endpoint_
.next_
= endp
;
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 */ +
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",
232 digits
[this->version_
.major
],
233 digits
[this->version_
.minor
],
235 this->object_key_delimiter_
,
242 TAO_COIOP_Profile::prefix ()
248 TAO_COIOP_Profile::create_profile_body (TAO_OutputCDR
&encap
) const
250 encap
.write_octet (TAO_ENCAP_BYTE_ORDER
);
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 ();
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
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
285 TAO::COIOPEndpointSequence endpoints
;
286 endpoints
.length (this->count_
);
288 const TAO_COIOP_Endpoint
*endpoint
= &this->endpoint_
;
289 for (CORBA::ULong i
= 0;
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
)
305 || (out_cdr
<< endpoints
) == 0)
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
));
313 tagged_component
.component_data
.get_buffer ();
315 for (const ACE_Message_Block
*iterator
= out_cdr
.begin ();
317 iterator
= iterator
->cont ())
319 size_t i_length
= iterator
->length ();
320 ACE_OS::memcpy (buf
, iterator
->rd_ptr (), i_length
);
325 // Add component with encoded endpoint data to this profile's
327 tagged_components_
.set_component (tagged_component
);
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)
350 in_cdr
.reset_byte_order (static_cast<int> (byte_order
));
352 // Extract endpoints sequence.
353 TAO::COIOPEndpointSequence endpoints
;
355 if (! (in_cdr
>> endpoints
))
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
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
369 for (CORBA::ULong i
= endpoints
.length () - 1;
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
),
380 this->add_endpoint (endpoint
);
387 TAO_END_VERSIONED_NAMESPACE_DECL
389 #endif /* TAO_HAS_COIOP && TAO_HAS_COIOP != 0 */