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 ()
26 TAO_DynValueBox_i::set_to_value ()
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_
);
72 TAO_DynValueBox_i::init (const CORBA::Any
& any
)
74 CORBA::TypeCode_ptr tc
= any
._tao_get_typecode ();
75 this->check_typecode (tc
);
76 this->type_
= CORBA::TypeCode::_duplicate (tc
);
77 this->set_from_any (any
);
81 TAO_DynValueBox_i::_narrow (CORBA::Object_ptr _tao_objref
)
83 return (CORBA::is_nil (_tao_objref
)) ?
85 dynamic_cast<TAO_DynValueBox_i
*> (_tao_objref
);
89 TAO_DynValueBox_i::get_boxed_value ()
93 throw ::CORBA::OBJECT_NOT_EXIST ();
96 if (CORBA::is_nil (this->boxed_
.in ()))
98 throw DynamicAny::DynAny::InvalidValue ();
101 return this->boxed_
->to_any ();
105 TAO_DynValueBox_i::set_boxed_value (const CORBA::Any
& boxed
)
107 if (this->destroyed_
)
109 throw ::CORBA::OBJECT_NOT_EXIST ();
112 // content_type() does not work with aliased type codes.
113 CORBA::TypeCode_var unaliased_tc
=
114 TAO_DynAnyFactory::strip_alias (this->type_
.in ());
115 CORBA::TypeCode_var my_tc
= unaliased_tc
->content_type ();
116 CORBA::TypeCode_var value_tc
= boxed
._tao_get_typecode ();
117 if (!my_tc
->equivalent (value_tc
.in ()))
119 throw DynamicAny::DynAny::TypeMismatch ();
123 TAO::MakeDynAnyUtils::make_dyn_any_t
<const CORBA::Any
&>
124 (boxed
._tao_get_typecode (), boxed
, this->allow_truncation_
);
125 this->set_to_value ();
128 DynamicAny::DynAny_ptr
129 TAO_DynValueBox_i::get_boxed_value_as_dyn_any ()
131 if (this->destroyed_
)
133 throw ::CORBA::OBJECT_NOT_EXIST ();
136 if (CORBA::is_nil (this->boxed_
.in ()))
138 throw DynamicAny::DynAny::InvalidValue ();
141 // A deep copy is made only by copy() (CORBA 2.4.2 section 9.2.3.6).
142 // Set the flag so the caller can't destroy.
143 this->set_flag (this->boxed_
.in (), 0);
145 return DynamicAny::DynAny::_duplicate (this->boxed_
.in ());
149 TAO_DynValueBox_i::set_boxed_value_as_dyn_any (DynamicAny::DynAny_ptr boxed
)
151 if (this->destroyed_
)
153 throw ::CORBA::OBJECT_NOT_EXIST ();
156 // content_type() does not work with aliased type codes.
157 CORBA::TypeCode_var unaliased_tc
=
158 TAO_DynAnyFactory::strip_alias (this->type_
.in ());
159 CORBA::TypeCode_var my_tc
= unaliased_tc
->content_type ();
160 CORBA::TypeCode_var value_tc
= boxed
->type ();
161 if (!my_tc
->equivalent (value_tc
.in ()))
163 throw DynamicAny::DynAny::TypeMismatch ();
165 this->boxed_
= boxed
->copy ();
166 this->set_to_value ();
170 TAO_DynValueBox_i::from_any (const CORBA::Any
& any
)
172 if (this->destroyed_
)
174 throw ::CORBA::OBJECT_NOT_EXIST ();
177 CORBA::TypeCode_var tc
= any
.type ();
178 if (!this->type_
->equivalent (tc
.in ()))
180 throw DynamicAny::DynAny::TypeMismatch ();
183 this->set_from_any (any
);
187 TAO_DynValueBox_i::equal (DynamicAny::DynAny_ptr rhs
)
189 if (this->destroyed_
)
191 throw ::CORBA::OBJECT_NOT_EXIST ();
194 CORBA::TypeCode_var tc
= rhs
->type ();
195 if (!tc
->equivalent (this->type_
.in ()))
200 DynamicAny::DynValueBox_ptr rhs_v
=
201 dynamic_cast<DynamicAny::DynValueBox_ptr
> (rhs
);
202 if (!rhs_v
|| this->is_null () != rhs_v
->is_null ())
207 if (!this->is_null ())
209 DynamicAny::DynAny_var
210 tmp (rhs
->current_component ());
211 return tmp
->equal (this->boxed_
.in ());
218 TAO_DynValueBox_i::destroy ()
220 if (this->destroyed_
)
222 throw ::CORBA::OBJECT_NOT_EXIST ();
225 if (!this->ref_to_component_
|| this->container_is_destroying_
)
227 // Do a deep destroy.
228 if (!CORBA::is_nil (this->boxed_
.in ()))
230 this->set_flag (this->boxed_
.in (), 1);
231 this->boxed_
.in ()->destroy ();
234 this->destroyed_
= 1;
238 DynamicAny::DynAny_ptr
239 TAO_DynValueBox_i::current_component ()
241 if (this->destroyed_
)
243 throw ::CORBA::OBJECT_NOT_EXIST ();
246 // Is this an NULL ValueBoxtype?
249 return DynamicAny::DynAny::_nil ();
252 this->set_flag (this->boxed_
.in (), 0);
253 return DynamicAny::DynAny::_duplicate (this->boxed_
.in ());
256 // This code is common to from_any() and the init() overload that takes
259 TAO_DynValueBox_i::set_from_any (const CORBA::Any
& any
)
261 // Get the CDR stream of the Any, if there isn't one, make one.
263 TAO_InputCDR
in (static_cast<ACE_Message_Block
*> (0));
264 TAO::Any_Impl
*impl
= any
.impl ();
265 if (impl
->encoded ())
267 TAO::Unknown_IDL_Type
*unk
=
268 dynamic_cast<TAO::Unknown_IDL_Type
*> (impl
);
270 throw CORBA::INTERNAL ();
272 in
= unk
->_tao_get_cdr ();
276 impl
->marshal_value (out
);
277 TAO_InputCDR
tmp_in (out
);
283 TAO_InputCDR
indrected_strm ((size_t) 0);
284 CORBA::Boolean is_indirected
= false;
285 CORBA::Boolean is_null_object
= false;
287 // Read in the ValueBox header (to skip over it) and check
288 // for the null type.
289 if (!CORBA::ValueBase::_tao_validate_box_type (
292 this->type_
.in ()->id (),
297 this->set_to_null ();
309 // content_type() does not work with aliased type codes.
310 CORBA::TypeCode_var unaliased_tc
=
311 TAO_DynAnyFactory::strip_alias (this->type_
.in ());
312 CORBA::TypeCode_var
boxed_tc (unaliased_tc
->content_type ());
313 TAO::Unknown_IDL_Type
* unk
= 0;
314 ACE_NEW_THROW_EX (unk
,
315 TAO::Unknown_IDL_Type (boxed_tc
.in (), in
),
316 CORBA::NO_MEMORY ());
317 CORBA::Any boxed_any
;
318 boxed_any
.replace (unk
);
320 TAO::MakeDynAnyUtils::make_dyn_any_t
<const CORBA::Any
&>
321 (boxed_any
._tao_get_typecode (), boxed_any
, this->allow_truncation_
);
322 this->init_common ();
326 TAO_DynValueBox_i::to_any ()
328 if (this->destroyed_
)
330 throw ::CORBA::OBJECT_NOT_EXIST ();
333 TAO_OutputCDR out_cdr
;
335 // Is this an NULL Valuetype?
336 if (!CORBA::ValueBase::_tao_write_special_value (
337 out_cdr
, reinterpret_cast <CORBA::ValueBase
*> (
338 this->is_null_
? 0 : this)))
340 // Build <value-tag>, which states if chunking is used
341 // and if type information ((list of) repository id(s))
343 CORBA::Long valuetag
=
344 TAO_OBV_GIOP_Flags::Value_tag_base
|
345 TAO_OBV_GIOP_Flags::Type_info_single
;
347 ACE_CString
type_id (this->type_
->id ());
349 // Write <value-tag> & Marshal type information.
350 if (!out_cdr
.write_long (valuetag
) ||
351 !CORBA::ValueBase::_tao_write_repository_id (out_cdr
, type_id
))
353 throw CORBA::INTERNAL ();
356 // Now write the boxed value itself
358 TAO_InputCDR
boxed_in_cdr (static_cast<ACE_Message_Block
*> (0));
359 CORBA::Any_var
boxed_any (this->boxed_
->to_any ());
360 TAO::Any_Impl
* boxed_impl
= boxed_any
->impl ();
361 if (boxed_impl
->encoded ())
363 TAO::Unknown_IDL_Type
* boxed_unk
=
364 dynamic_cast<TAO::Unknown_IDL_Type
*> (boxed_impl
);
367 throw CORBA::INTERNAL ();
369 boxed_in_cdr
= boxed_unk
->_tao_get_cdr ();
373 TAO_OutputCDR boxed_out_cdr
;
374 boxed_impl
->marshal_value (boxed_out_cdr
);
375 TAO_InputCDR
tmp (boxed_out_cdr
);
379 CORBA::TypeCode_var boxed_tc
= this->boxed_
->type ();
380 (void) TAO_Marshal_Object::perform_append (boxed_tc
.in (),
385 // Convert the out_cdr into a new any.
386 TAO_InputCDR
in_cdr (out_cdr
);
387 TAO::Unknown_IDL_Type
* unk
= 0;
388 ACE_NEW_THROW_EX (unk
,
389 TAO::Unknown_IDL_Type (this->type_
.in (), in_cdr
),
390 CORBA::NO_MEMORY ());
391 CORBA::Any_ptr retval
= 0;
392 ACE_NEW_THROW_EX (retval
, CORBA::Any
, CORBA::NO_MEMORY ());
393 retval
->replace (unk
);
397 TAO_END_VERSIONED_NAMESPACE_DECL