2 #include "tao/DynamicAny/DynValueBox_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_DynValueBox_i::TAO_DynValueBox_i (CORBA::Boolean allow_truncation
)
15 : TAO_DynCommon (allow_truncation
)
16 , TAO_DynAny_i (allow_truncation
)
17 , TAO_DynValueCommon_i (allow_truncation
)
21 TAO_DynValueBox_i::~TAO_DynValueBox_i (void)
26 TAO_DynValueBox_i::set_to_value (void)
28 if (CORBA::is_nil (this->boxed_
.in ()))
34 this->is_null_
= false;
35 this->component_count_
= 1u;
36 this->current_position_
= 0;
41 TAO_DynValueBox_i::check_typecode (CORBA::TypeCode_ptr tc
)
43 CORBA::TCKind kind
= TAO_DynAnyFactory::unalias (tc
);
44 if (kind
== CORBA::tk_value_box
)
49 throw DynamicAny::DynAnyFactory::InconsistentTypeCode ();
53 TAO_DynValueBox_i::init (CORBA::TypeCode_ptr tc
)
55 this->check_typecode (tc
);
56 this->type_
= CORBA::TypeCode::_duplicate (tc
);
58 // member_type() does not work with aliased type codes.
59 CORBA::TypeCode_var unaliased_tc
=
60 TAO_DynAnyFactory::strip_alias (this->type_
.in ());
62 mtype (unaliased_tc
->content_type ());
64 TAO::MakeDynAnyUtils::make_dyn_any_t
<CORBA::TypeCode_ptr
>
65 (mtype
.in (), mtype
.in (), this->allow_truncation_
);
73 TAO_DynValueBox_i::init (const CORBA::Any
& any
)
75 CORBA::TypeCode_ptr tc
= any
._tao_get_typecode ();
76 this->check_typecode (tc
);
77 this->type_
= CORBA::TypeCode::_duplicate (tc
);
78 this->set_from_any (any
);
82 TAO_DynValueBox_i::_narrow (CORBA::Object_ptr _tao_objref
)
84 return (CORBA::is_nil (_tao_objref
)) ?
86 dynamic_cast<TAO_DynValueBox_i
*> (_tao_objref
);
90 TAO_DynValueBox_i::get_boxed_value (void)
94 throw ::CORBA::OBJECT_NOT_EXIST ();
97 if (CORBA::is_nil (this->boxed_
.in ()))
99 throw DynamicAny::DynAny::InvalidValue ();
102 return this->boxed_
->to_any ();
106 TAO_DynValueBox_i::set_boxed_value (const CORBA::Any
& boxed
)
108 if (this->destroyed_
)
110 throw ::CORBA::OBJECT_NOT_EXIST ();
113 // content_type() does not work with aliased type codes.
114 CORBA::TypeCode_var unaliased_tc
=
115 TAO_DynAnyFactory::strip_alias (this->type_
.in ());
116 CORBA::TypeCode_var my_tc
= unaliased_tc
->content_type ();
117 CORBA::TypeCode_var value_tc
= boxed
._tao_get_typecode ();
118 if (!my_tc
->equivalent (value_tc
.in ()))
120 throw DynamicAny::DynAny::TypeMismatch ();
124 TAO::MakeDynAnyUtils::make_dyn_any_t
<const CORBA::Any
&>
125 (boxed
._tao_get_typecode (), boxed
, this->allow_truncation_
);
126 this->set_to_value ();
129 DynamicAny::DynAny_ptr
130 TAO_DynValueBox_i::get_boxed_value_as_dyn_any (void)
132 if (this->destroyed_
)
134 throw ::CORBA::OBJECT_NOT_EXIST ();
137 if (CORBA::is_nil (this->boxed_
.in ()))
139 throw DynamicAny::DynAny::InvalidValue ();
142 // A deep copy is made only by copy() (CORBA 2.4.2 section 9.2.3.6).
143 // Set the flag so the caller can't destroy.
144 this->set_flag (this->boxed_
.in (), 0);
146 return DynamicAny::DynAny::_duplicate (this->boxed_
.in ());
150 TAO_DynValueBox_i::set_boxed_value_as_dyn_any (DynamicAny::DynAny_ptr boxed
)
152 if (this->destroyed_
)
154 throw ::CORBA::OBJECT_NOT_EXIST ();
157 // content_type() does not work with aliased type codes.
158 CORBA::TypeCode_var unaliased_tc
=
159 TAO_DynAnyFactory::strip_alias (this->type_
.in ());
160 CORBA::TypeCode_var my_tc
= unaliased_tc
->content_type ();
161 CORBA::TypeCode_var value_tc
= boxed
->type ();
162 if (!my_tc
->equivalent (value_tc
.in ()))
164 throw DynamicAny::DynAny::TypeMismatch ();
166 this->boxed_
= boxed
->copy ();
167 this->set_to_value ();
171 TAO_DynValueBox_i::from_any (const CORBA::Any
& any
)
173 if (this->destroyed_
)
175 throw ::CORBA::OBJECT_NOT_EXIST ();
178 CORBA::TypeCode_var tc
= any
.type ();
179 if (!this->type_
->equivalent (tc
.in ()))
181 throw DynamicAny::DynAny::TypeMismatch ();
184 this->set_from_any (any
);
188 TAO_DynValueBox_i::equal (DynamicAny::DynAny_ptr rhs
)
190 if (this->destroyed_
)
192 throw ::CORBA::OBJECT_NOT_EXIST ();
195 CORBA::TypeCode_var tc
= rhs
->type ();
196 if (!tc
->equivalent (this->type_
.in ()))
201 DynamicAny::DynValueBox_ptr rhs_v
=
202 dynamic_cast<DynamicAny::DynValueBox_ptr
> (rhs
);
203 if (!rhs_v
|| this->is_null () != rhs_v
->is_null ())
208 if (!this->is_null ())
210 DynamicAny::DynAny_var
211 tmp (rhs
->current_component ());
212 return tmp
->equal (this->boxed_
.in ());
219 TAO_DynValueBox_i::destroy (void)
221 if (this->destroyed_
)
223 throw ::CORBA::OBJECT_NOT_EXIST ();
226 if (!this->ref_to_component_
|| this->container_is_destroying_
)
228 // Do a deep destroy.
229 if (!CORBA::is_nil (this->boxed_
.in ()))
231 this->set_flag (this->boxed_
.in (), 1);
232 this->boxed_
.in ()->destroy ();
235 this->destroyed_
= 1;
239 DynamicAny::DynAny_ptr
240 TAO_DynValueBox_i::current_component (void)
242 if (this->destroyed_
)
244 throw ::CORBA::OBJECT_NOT_EXIST ();
247 // Is this an NULL ValueBoxtype?
250 return DynamicAny::DynAny::_nil ();
253 this->set_flag (this->boxed_
.in (), 0);
254 return DynamicAny::DynAny::_duplicate (this->boxed_
.in ());
257 // This code is common to from_any() and the init() overload that takes
260 TAO_DynValueBox_i::set_from_any (const CORBA::Any
& any
)
262 // Get the CDR stream of the Any, if there isn't one, make one.
264 TAO_InputCDR
in (static_cast<ACE_Message_Block
*> (0));
265 TAO::Any_Impl
*impl
= any
.impl ();
266 if (impl
->encoded ())
268 TAO::Unknown_IDL_Type
*unk
=
269 dynamic_cast<TAO::Unknown_IDL_Type
*> (impl
);
271 throw CORBA::INTERNAL ();
273 in
= unk
->_tao_get_cdr ();
277 impl
->marshal_value (out
);
278 TAO_InputCDR
tmp_in (out
);
284 TAO_InputCDR
indrected_strm ((size_t) 0);
285 CORBA::Boolean is_indirected
= false;
286 CORBA::Boolean is_null_object
= false;
288 // Read in the ValueBox header (to skip over it) and check
289 // for the null type.
290 if (!CORBA::ValueBase::_tao_validate_box_type (
293 this->type_
.in ()->id (),
298 this->set_to_null ();
310 // content_type() does not work with aliased type codes.
311 CORBA::TypeCode_var unaliased_tc
=
312 TAO_DynAnyFactory::strip_alias (this->type_
.in ());
313 CORBA::TypeCode_var
boxed_tc (unaliased_tc
->content_type ());
314 TAO::Unknown_IDL_Type
* unk
= 0;
315 ACE_NEW_THROW_EX (unk
,
316 TAO::Unknown_IDL_Type (boxed_tc
.in (), in
),
317 CORBA::NO_MEMORY ());
318 CORBA::Any boxed_any
;
319 boxed_any
.replace (unk
);
321 TAO::MakeDynAnyUtils::make_dyn_any_t
<const CORBA::Any
&>
322 (boxed_any
._tao_get_typecode (), boxed_any
, this->allow_truncation_
);
323 this->init_common ();
327 TAO_DynValueBox_i::to_any (void)
329 if (this->destroyed_
)
331 throw ::CORBA::OBJECT_NOT_EXIST ();
334 TAO_OutputCDR out_cdr
;
336 // Is this an NULL Valuetype?
337 if (!CORBA::ValueBase::_tao_write_special_value (
338 out_cdr
, reinterpret_cast <CORBA::ValueBase
*> (
339 this->is_null_
? 0 : this)))
341 // Build <value-tag>, which states if chunking is used
342 // and if type information ((list of) repository id(s))
344 CORBA::Long valuetag
=
345 TAO_OBV_GIOP_Flags::Value_tag_base
|
346 TAO_OBV_GIOP_Flags::Type_info_single
;
348 ACE_CString
type_id (this->type_
->id ());
350 // Write <value-tag> & Marshal type information.
351 if (!out_cdr
.write_long (valuetag
) ||
352 !CORBA::ValueBase::_tao_write_repository_id (out_cdr
, type_id
))
354 throw CORBA::INTERNAL ();
357 // Now write the boxed value itself
359 TAO_InputCDR
boxed_in_cdr (static_cast<ACE_Message_Block
*> (0));
360 CORBA::Any_var
boxed_any (this->boxed_
->to_any ());
361 TAO::Any_Impl
* boxed_impl
= boxed_any
->impl ();
362 if (boxed_impl
->encoded ())
364 TAO::Unknown_IDL_Type
* boxed_unk
=
365 dynamic_cast<TAO::Unknown_IDL_Type
*> (boxed_impl
);
368 throw CORBA::INTERNAL ();
370 boxed_in_cdr
= boxed_unk
->_tao_get_cdr ();
374 TAO_OutputCDR boxed_out_cdr
;
375 boxed_impl
->marshal_value (boxed_out_cdr
);
376 TAO_InputCDR
tmp (boxed_out_cdr
);
380 CORBA::TypeCode_var boxed_tc
= this->boxed_
->type ();
381 (void) TAO_Marshal_Object::perform_append (boxed_tc
.in (),
386 // Convert the out_cdr into a new any.
387 TAO_InputCDR
in_cdr (out_cdr
);
388 TAO::Unknown_IDL_Type
* unk
= 0;
389 ACE_NEW_THROW_EX (unk
,
390 TAO::Unknown_IDL_Type (this->type_
.in (), in_cdr
),
391 CORBA::NO_MEMORY ());
392 CORBA::Any_ptr retval
= 0;
393 ACE_NEW_THROW_EX (retval
, CORBA::Any
, CORBA::NO_MEMORY ());
394 retval
->replace (unk
);
398 TAO_END_VERSIONED_NAMESPACE_DECL