Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / TAO / tao / DynamicAny / DynValueBox_i.cpp
blobcfa81bd3bea937a3748b73a2f8a053562874efba
1 // -*- C++ -*-
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"
10 #include "tao/CDR.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 ()
25 void
26 TAO_DynValueBox_i::set_to_value ()
28 if (CORBA::is_nil (this->boxed_.in ()))
30 set_to_null ();
32 else
34 this->is_null_ = false;
35 this->component_count_ = 1u;
36 this->current_position_ = 0;
40 void
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)
46 return;
49 throw DynamicAny::DynAnyFactory::InconsistentTypeCode ();
52 void
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 ());
61 CORBA::TypeCode_var
62 mtype (unaliased_tc->content_type ());
63 this->boxed_ =
64 TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr>
65 (mtype.in (), mtype.in (), this->allow_truncation_);
67 this->init_common ();
68 this->set_to_null ();
71 void
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);
80 TAO_DynValueBox_i *
81 TAO_DynValueBox_i::_narrow (CORBA::Object_ptr _tao_objref)
83 return (CORBA::is_nil (_tao_objref)) ?
84 0 :
85 dynamic_cast<TAO_DynValueBox_i *> (_tao_objref);
88 CORBA::Any *
89 TAO_DynValueBox_i::get_boxed_value ()
91 if (this->destroyed_)
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 ();
104 void
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 ();
122 this->boxed_ =
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 ());
148 void
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 ();
169 void
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);
186 CORBA::Boolean
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 ()))
197 return false;
200 DynamicAny::DynValueBox_ptr rhs_v=
201 dynamic_cast<DynamicAny::DynValueBox_ptr> (rhs);
202 if (!rhs_v || this->is_null () != rhs_v->is_null ())
204 return false;
207 if (!this->is_null ())
209 DynamicAny::DynAny_var
210 tmp (rhs->current_component ());
211 return tmp->equal (this->boxed_.in ());
214 return true;
217 void
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?
247 if (this->is_null_)
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
257 // an Any argument.
258 void
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.
262 TAO_OutputCDR out;
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);
269 if (!unk)
270 throw CORBA::INTERNAL ();
272 in = unk->_tao_get_cdr ();
274 else
276 impl->marshal_value (out);
277 TAO_InputCDR tmp_in (out);
278 in = tmp_in;
281 while (true)
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 (
291 indrected_strm,
292 this->type_.in ()->id (),
293 is_null_object,
294 is_indirected) ||
295 is_null_object)
297 this->set_to_null ();
298 return;
301 if (!is_indirected)
303 break;
306 in = indrected_strm;
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);
319 this->boxed_ =
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 ();
325 CORBA::Any_ptr
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))
342 // is provided.
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);
365 if (!boxed_unk)
367 throw CORBA::INTERNAL ();
369 boxed_in_cdr = boxed_unk->_tao_get_cdr ();
371 else
373 TAO_OutputCDR boxed_out_cdr;
374 boxed_impl->marshal_value (boxed_out_cdr);
375 TAO_InputCDR tmp (boxed_out_cdr);
376 boxed_in_cdr = tmp;
379 CORBA::TypeCode_var boxed_tc = this->boxed_->type ();
380 (void) TAO_Marshal_Object::perform_append (boxed_tc.in (),
381 &boxed_in_cdr,
382 &out_cdr);
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);
394 return retval;
397 TAO_END_VERSIONED_NAMESPACE_DECL