2 #include "tao/DynamicAny/DynArray_i.h"
3 #include "tao/DynamicAny/DynAnyFactory.h"
4 #include "tao/DynamicAny/DynAnyUtils_T.h"
6 #include "tao/AnyTypeCode/Marshal.h"
7 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
8 #include "tao/AnyTypeCode/AnyTypeCode_methods.h"
12 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
14 TAO_DynArray_i::TAO_DynArray_i (CORBA::Boolean allow_truncation
)
15 : TAO_DynCommon (allow_truncation
)
19 TAO_DynArray_i::~TAO_DynArray_i (void)
24 TAO_DynArray_i::init_common (void)
26 this->ref_to_component_
= false;
27 this->container_is_destroying_
= false;
28 this->has_components_
= true;
29 this->destroyed_
= false;
30 this->current_position_
= 0;
31 this->component_count_
= static_cast<CORBA::ULong
> (this->da_members_
.size ());
35 TAO_DynArray_i::init (const CORBA::Any
& any
)
37 CORBA::TypeCode_var tc
= any
.type ();
39 CORBA::TCKind kind
= TAO_DynAnyFactory::unalias (tc
.in ());
41 if (kind
!= CORBA::tk_array
)
43 throw DynamicAny::DynAnyFactory::InconsistentTypeCode ();
48 CORBA::ULong numfields
= this->get_tc_length (tc
.in ());
50 this->da_members_
.size (numfields
);
54 // Get the CDR stream of the Any, if there isn't one, make one.
55 TAO::Any_Impl
*impl
= any
.impl ();
57 TAO_InputCDR
cdr (static_cast<ACE_Message_Block
*> (0));
61 TAO::Unknown_IDL_Type
* const unk
=
62 dynamic_cast<TAO::Unknown_IDL_Type
*> (impl
);
65 throw CORBA::INTERNAL ();
67 cdr
= unk
->_tao_get_cdr ();
71 impl
->marshal_value (out
);
72 TAO_InputCDR
tmp_in (out
);
76 CORBA::TypeCode_var field_tc
=
77 this->get_element_type ();
79 for (CORBA::ULong i
= 0; i
< numfields
; ++i
)
82 TAO::Unknown_IDL_Type
*field_unk
= 0;
83 TAO_InputCDR
unk_in (cdr
);
85 TAO::Unknown_IDL_Type (field_tc
.in (), unk_in
));
86 field_any
.replace (field_unk
);
88 // This recursive step will call the correct constructor
89 // based on the type of field_any.
90 this->da_members_
[i
] =
91 TAO::MakeDynAnyUtils::make_dyn_any_t
<const CORBA::Any
&> (
92 field_any
._tao_get_typecode (),
94 this->allow_truncation_
);
96 // Move to the next field in the CDR stream.
97 (void) TAO_Marshal_Object::perform_skip (field_tc
.in (), &cdr
);
102 TAO_DynArray_i::init (CORBA::TypeCode_ptr tc
)
104 CORBA::TCKind kind
= TAO_DynAnyFactory::unalias (tc
);
106 if (kind
!= CORBA::tk_array
)
108 throw DynamicAny::DynAnyFactory::InconsistentTypeCode ();
111 this->type_
= CORBA::TypeCode::_duplicate (tc
);
113 CORBA::ULong numfields
= this->get_tc_length (tc
);
116 this->da_members_
.size (numfields
);
118 this->init_common ();
120 CORBA::TypeCode_var elemtype
= this->get_element_type ();
122 for (CORBA::ULong i
= 0; i
< numfields
; ++i
)
124 // Recursively initialize each element.
125 this->da_members_
[i
] =
126 TAO::MakeDynAnyUtils::make_dyn_any_t
<CORBA::TypeCode_ptr
> (
129 this->allow_truncation_
);
134 TAO_DynArray_i::get_element_type (void)
136 CORBA::TypeCode_var element_type
=
137 CORBA::TypeCode::_duplicate (this->type_
.in ());
139 // Strip away aliases (if any) on top of the outer type
140 CORBA::TCKind kind
= element_type
->kind ();
142 while (kind
!= CORBA::tk_array
)
144 element_type
= element_type
->content_type ();
146 kind
= element_type
->kind ();
149 // Return the content type.
150 return element_type
->content_type ();
153 // Get the length from the (possibly aliased) typecode.
155 TAO_DynArray_i::get_tc_length (CORBA::TypeCode_ptr tc
)
157 CORBA::TypeCode_var tctmp
= CORBA::TypeCode::_duplicate (tc
);
158 CORBA::TCKind kind
= tctmp
->kind ();
160 while (kind
== CORBA::tk_alias
)
162 tctmp
= tctmp
->content_type ();
163 kind
= tctmp
->kind ();
166 return tctmp
->length ();
169 // ****************************************************************
172 TAO_DynArray_i::_narrow (CORBA::Object_ptr _tao_objref
)
174 if (CORBA::is_nil (_tao_objref
))
179 return dynamic_cast<TAO_DynArray_i
*> (_tao_objref
);
182 // ****************************************************************
185 TAO_DynArray_i::get_elements (void)
187 if (this->destroyed_
)
189 throw ::CORBA::OBJECT_NOT_EXIST ();
192 CORBA::ULong length
= static_cast<CORBA::ULong
> (this->da_members_
.size ());
194 DynamicAny::AnySeq
*elements
= 0;
195 ACE_NEW_THROW_EX (elements
,
196 DynamicAny::AnySeq (length
),
197 CORBA::NO_MEMORY ());
199 elements
->length (length
);
200 DynamicAny::AnySeq_var
safe_retval (elements
);
204 // Initialize each Any.
205 for (CORBA::ULong i
= 0; i
< length
; i
++)
207 tmp
= this->da_members_
[i
]->to_any ();
209 safe_retval
[i
] = tmp
.in ();
212 return safe_retval
._retn ();
216 TAO_DynArray_i::set_elements (const DynamicAny::AnySeq
& value
)
218 if (this->destroyed_
)
220 throw ::CORBA::OBJECT_NOT_EXIST ();
223 CORBA::ULong
const length
= value
.length ();
225 if (length
!= this->da_members_
.size ())
227 throw DynamicAny::DynAny::InvalidValue ();
230 CORBA::TypeCode_var value_tc
;
231 CORBA::TypeCode_var element_type
= this->get_element_type ();
233 for (CORBA::ULong i
= 0; i
< length
; i
++)
235 // Check each arg element for type match.
236 value_tc
= value
[i
].type ();
237 CORBA::Boolean equivalent
=
238 value_tc
->equivalent (element_type
.in ());
242 this->da_members_
[i
]->destroy ();
244 this->da_members_
[i
] =
245 TAO::MakeDynAnyUtils::make_dyn_any_t
<const CORBA::Any
&> (
246 value
[i
]._tao_get_typecode (),
248 this->allow_truncation_
);
252 throw DynamicAny::DynAny::TypeMismatch ();
257 DynamicAny::DynAnySeq
*
258 TAO_DynArray_i::get_elements_as_dyn_any (void)
260 if (this->destroyed_
)
262 throw ::CORBA::OBJECT_NOT_EXIST ();
265 DynamicAny::DynAnySeq
*retval
= 0;
266 ACE_NEW_THROW_EX (retval
,
267 DynamicAny::DynAnySeq (this->component_count_
),
268 CORBA::NO_MEMORY ());
270 retval
->length (this->component_count_
);
271 DynamicAny::DynAnySeq_var
safe_retval (retval
);
273 for (CORBA::ULong i
= 0; i
< this->component_count_
; ++i
)
275 // A deep copy is made only by copy() (CORBA 2.4.2 section 9.2.3.6).
276 // Set the flag so the caller can't destroy.
277 this->set_flag (this->da_members_
[i
].in (), 0);
280 DynamicAny::DynAny::_duplicate (this->da_members_
[i
].in ());
283 return safe_retval
._retn ();
287 TAO_DynArray_i::set_elements_as_dyn_any (
288 const DynamicAny::DynAnySeq
& values
292 if (this->destroyed_
)
294 throw ::CORBA::OBJECT_NOT_EXIST ();
297 CORBA::ULong length
= static_cast<CORBA::ULong
> (this->da_members_
.size ());
299 if (values
.length () != length
)
301 throw DynamicAny::DynAny::InvalidValue ();
304 CORBA::TypeCode_var element_type
= this->get_element_type ();
306 CORBA::TypeCode_var val_type
;
307 CORBA::Boolean equivalent
;
309 for (CORBA::ULong i
= 0; i
< length
; ++i
)
311 val_type
= values
[i
]->type ();
313 equivalent
= val_type
->equivalent (element_type
.in ());
318 this->da_members_
[i
] = values
[i
]->copy ();
322 throw DynamicAny::DynAny::TypeMismatch ();
327 // ****************************************************************
330 TAO_DynArray_i::from_any (const CORBA::Any
& any
)
332 if (this->destroyed_
)
334 throw ::CORBA::OBJECT_NOT_EXIST ();
337 CORBA::TypeCode_var tc
= any
.type ();
338 CORBA::Boolean equivalent
= this->type_
.in ()->equivalent (tc
.in ());
342 // Get the CDR stream of the Any,if there isn't one, make one.
343 TAO::Any_Impl
*impl
= any
.impl ();
345 TAO_InputCDR
cdr (static_cast<ACE_Message_Block
*> (0));
347 if (impl
->encoded ())
349 TAO::Unknown_IDL_Type
* const unk
=
350 dynamic_cast<TAO::Unknown_IDL_Type
*> (impl
);
353 throw CORBA::INTERNAL ();
355 cdr
= unk
->_tao_get_cdr ();
359 impl
->marshal_value (out
);
360 TAO_InputCDR
tmp_in (out
);
364 CORBA::ULong length
= static_cast<CORBA::ULong
> (this->da_members_
.size ());
365 CORBA::ULong arg_length
= this->get_tc_length (tc
.in ());
367 if (length
!= arg_length
)
369 throw DynamicAny::DynAny::TypeMismatch ();
372 CORBA::TypeCode_var field_tc
= this->get_element_type ();
374 for (CORBA::ULong i
= 0; i
< arg_length
; ++i
)
376 CORBA::Any field_any
;
377 TAO_InputCDR
unk_in (cdr
);
378 TAO::Unknown_IDL_Type
*field_unk
= 0;
380 TAO::Unknown_IDL_Type (field_tc
.in (), unk_in
));
381 field_any
.replace (field_unk
);
383 this->da_members_
[i
]->destroy ();
385 this->da_members_
[i
] =
386 TAO::MakeDynAnyUtils::make_dyn_any_t
<const CORBA::Any
&> (
387 field_any
._tao_get_typecode (),
389 this->allow_truncation_
);
391 // Move to the next field in the CDR stream.
392 (void) TAO_Marshal_Object::perform_skip (field_tc
.in (), &cdr
);
395 this->current_position_
= arg_length
? 0 : -1;
399 throw DynamicAny::DynAny::TypeMismatch ();
404 TAO_DynArray_i::to_any (void)
406 if (this->destroyed_
)
408 throw ::CORBA::OBJECT_NOT_EXIST ();
411 CORBA::TypeCode_var field_tc
= this->get_element_type ();
413 TAO_OutputCDR out_cdr
;
414 CORBA::Any_var field_any
;
415 size_t length
= this->da_members_
.size ();
417 for (size_t i
= 0; i
< length
; ++i
)
420 field_any
= this->da_members_
[i
]->to_any ();
422 TAO::Any_Impl
*field_impl
= field_any
->impl ();
423 TAO_OutputCDR field_out
;
424 TAO_InputCDR
field_cdr (static_cast<ACE_Message_Block
*> (0));
426 if (field_impl
->encoded ())
428 TAO::Unknown_IDL_Type
* const field_unk
=
429 dynamic_cast<TAO::Unknown_IDL_Type
*> (field_impl
);
432 throw CORBA::INTERNAL ();
434 field_cdr
= field_unk
->_tao_get_cdr ();
438 field_impl
->marshal_value (field_out
);
439 TAO_InputCDR
tmp_in (field_out
);
443 (void) TAO_Marshal_Object::perform_append (field_tc
.in (),
448 TAO_InputCDR
in_cdr (out_cdr
);
450 CORBA::Any_ptr retval
= 0;
451 ACE_NEW_THROW_EX (retval
,
453 CORBA::NO_MEMORY ());
455 TAO::Unknown_IDL_Type
*unk
= 0;
456 ACE_NEW_THROW_EX (unk
,
457 TAO::Unknown_IDL_Type (this->type_
.in (),
459 CORBA::NO_MEMORY ());
461 retval
->replace (unk
);
466 TAO_DynArray_i::equal (DynamicAny::DynAny_ptr rhs
)
468 if (this->destroyed_
)
470 throw ::CORBA::OBJECT_NOT_EXIST ();
473 CORBA::TypeCode_var tc
= rhs
->type ();
475 CORBA::Boolean equivalent
= tc
->equivalent (this->type_
.in ());
482 DynamicAny::DynAny_var tmp
;
483 CORBA::Boolean member_equal
;
485 for (CORBA::ULong i
= 0; i
< this->component_count_
; ++i
)
487 rhs
->seek (static_cast<CORBA::Long
> (i
));
489 tmp
= rhs
->current_component ();
492 member_equal
= tmp
->equal (this->da_members_
[i
].in ());
504 TAO_DynArray_i::destroy (void)
506 if (this->destroyed_
)
508 throw ::CORBA::OBJECT_NOT_EXIST ();
511 if (!this->ref_to_component_
|| this->container_is_destroying_
)
513 // Do a deep destroy.
514 for (CORBA::ULong i
= 0; i
< this->component_count_
; ++i
)
516 this->set_flag (da_members_
[i
].in (), 1);
518 this->da_members_
[i
]->destroy ();
521 this->destroyed_
= 1;
525 DynamicAny::DynAny_ptr
526 TAO_DynArray_i::current_component (void)
528 if (this->destroyed_
)
530 throw ::CORBA::OBJECT_NOT_EXIST ();
533 if (this->current_position_
== -1)
535 return DynamicAny::DynAny::_nil ();
538 CORBA::ULong index
= static_cast<CORBA::ULong
> (this->current_position_
);
540 this->set_flag (this->da_members_
[index
].in (), 0);
542 return DynamicAny::DynAny::_duplicate (this->da_members_
[index
].in ());
545 TAO_END_VERSIONED_NAMESPACE_DECL