Use =default for skeleton copy constructor
[ACE_TAO.git] / TAO / tao / DynamicAny / DynAny_i.cpp
blob270b617167b2f7e485b08fad04f3f568552e8794
1 // -*- C++ -*-
2 #include "tao/AnyTypeCode/TypeCode.h"
3 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
4 #include "tao/AnyTypeCode/AnyTypeCode_methods.h"
6 #include "tao/DynamicAny/DynAny_i.h"
7 #include "tao/DynamicAny/DynAnyFactory.h"
9 #include "tao/DynamicAny/DynAnyUtils_T.h"
11 #include "tao/CDR.h"
13 #include "ace/OS_NS_wchar.h"
14 #include "ace/OS_NS_string.h"
16 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
18 TAO_DynAny_i::TAO_DynAny_i (CORBA::Boolean allow_truncation)
19 : TAO_DynCommon (allow_truncation)
23 TAO_DynAny_i::~TAO_DynAny_i ()
27 void
28 TAO_DynAny_i::check_typecode (CORBA::TypeCode_ptr tc)
30 // Check to see if it's a simple type.
31 CORBA::TCKind tk = TAO_DynAnyFactory::unalias (tc);
33 switch (tk)
35 case CORBA::tk_null:
36 case CORBA::tk_void:
37 case CORBA::tk_short:
38 case CORBA::tk_long:
39 case CORBA::tk_ushort:
40 case CORBA::tk_ulong:
41 case CORBA::tk_float:
42 case CORBA::tk_double:
43 case CORBA::tk_longlong:
44 case CORBA::tk_ulonglong:
45 case CORBA::tk_boolean:
46 case CORBA::tk_char:
47 case CORBA::tk_wchar:
48 case CORBA::tk_octet:
49 case CORBA::tk_any:
50 case CORBA::tk_TypeCode:
51 case CORBA::tk_objref:
52 case CORBA::tk_string:
53 case CORBA::tk_wstring:
54 case CORBA::tk_longdouble:
55 break;
56 case CORBA::tk_sequence:
57 if (tc->equivalent (CORBA::_tc_BooleanSeq)
58 || tc->equivalent (CORBA::_tc_OctetSeq)
59 || tc->equivalent (CORBA::_tc_CharSeq)
60 || tc->equivalent (CORBA::_tc_WCharSeq)
61 || tc->equivalent (CORBA::_tc_ShortSeq)
62 || tc->equivalent (CORBA::_tc_UShortSeq)
63 || tc->equivalent (CORBA::_tc_LongSeq)
64 || tc->equivalent (CORBA::_tc_ULongSeq)
65 || tc->equivalent (CORBA::_tc_LongLongSeq)
66 || tc->equivalent (CORBA::_tc_ULongLongSeq)
67 || tc->equivalent (CORBA::_tc_FloatSeq)
68 || tc->equivalent (CORBA::_tc_DoubleSeq)
69 || tc->equivalent (CORBA::_tc_LongDoubleSeq))
71 // Otherwise fall through.
72 break;
74 ACE_FALLTHROUGH;
75 default:
76 throw DynamicAny::DynAnyFactory::InconsistentTypeCode ();
80 void
81 TAO_DynAny_i::set_to_default_value (CORBA::TypeCode_ptr tc)
83 CORBA::TCKind tk = TAO_DynAnyFactory::unalias (tc);
85 switch (tk)
87 case CORBA::tk_null:
88 break;
89 case CORBA::tk_void:
90 this->any_._tao_set_typecode (CORBA::_tc_void);
91 break;
92 case CORBA::tk_short:
93 this->any_ <<= static_cast<CORBA::Short> (0);
94 break;
95 case CORBA::tk_long:
96 this->any_ <<= static_cast<CORBA::Long> (0);
97 break;
98 case CORBA::tk_ushort:
99 this->any_ <<= static_cast<CORBA::UShort> (0);
100 break;
101 case CORBA::tk_ulong:
102 this->any_ <<= static_cast<CORBA::ULong> (0);
103 break;
104 case CORBA::tk_longlong:
105 this->any_ <<= static_cast<CORBA::LongLong> (0);
106 break;
107 case CORBA::tk_ulonglong:
108 this->any_ <<= static_cast<CORBA::ULongLong> (0);
109 break;
110 case CORBA::tk_boolean:
111 this->any_ <<= CORBA::Any::from_boolean (0);
112 break;
113 case CORBA::tk_octet:
114 this->any_ <<= CORBA::Any::from_octet (0);
115 break;
116 case CORBA::tk_char:
117 this->any_ <<= CORBA::Any::from_char (0);
118 break;
119 case CORBA::tk_wchar:
120 this->any_ <<= CORBA::Any::from_wchar (0);
121 break;
122 case CORBA::tk_float:
123 this->any_ <<= static_cast<CORBA::Float> (0);
124 break;
125 case CORBA::tk_double:
126 this->any_ <<= static_cast<CORBA::Double> (0);
127 break;
128 case CORBA::tk_longdouble:
130 CORBA::LongDouble temp = ACE_CDR_LONG_DOUBLE_INITIALIZER;
131 this->any_ <<= temp;
132 break;
134 case CORBA::tk_any:
135 this->any_._tao_set_typecode (CORBA::_tc_null);
136 break;
137 case CORBA::tk_TypeCode:
138 this->any_ <<= CORBA::_tc_null;
139 break;
140 case CORBA::tk_objref:
142 TAO_OutputCDR stream;
143 stream << CORBA::Object::_nil ();
144 TAO_InputCDR in (stream);
145 TAO::Unknown_IDL_Type *unk = 0;
146 ACE_NEW (unk,
147 TAO::Unknown_IDL_Type (tc, in));
148 this->any_.replace (unk);
149 break;
151 case CORBA::tk_string:
152 this->any_ <<= "";
153 break;
154 case CORBA::tk_wstring:
156 CORBA::WChar wstr[1];
157 wstr[0] = 0;
158 this->any_ <<= wstr;
159 break;
161 default:
162 // Should never get here - check_typecode() has already been called.
163 break;
167 void
168 TAO_DynAny_i::init_common ()
170 this->ref_to_component_ = false;
171 this->container_is_destroying_ = false;
172 this->has_components_ = false;
173 this->destroyed_ = false;
174 this->current_position_ = -1;
175 this->component_count_ = 0;
178 void
179 TAO_DynAny_i::init (CORBA::TypeCode_ptr tc)
181 this->check_typecode (tc);
183 this->set_to_default_value (tc);
185 this->init_common ();
187 this->type_ = CORBA::TypeCode::_duplicate (tc);
190 void
191 TAO_DynAny_i::init (const CORBA::Any& any)
193 this->type_ = any.type ();
194 this->check_typecode (this->type_.in ());
196 this->init_common ();
198 this->any_ = any;
201 // ****************************************************************
203 TAO_DynAny_i *
204 TAO_DynAny_i::_narrow (CORBA::Object_ptr _tao_objref)
206 if (CORBA::is_nil (_tao_objref))
208 return 0;
211 return dynamic_cast<TAO_DynAny_i *> (_tao_objref);
214 // ****************************************************************
216 void
217 TAO_DynAny_i::from_any (const CORBA::Any &any)
219 if (this->destroyed_)
221 throw ::CORBA::OBJECT_NOT_EXIST ();
224 CORBA::TypeCode_var any_tc = any.type ();
226 if (!this->type_->equivalent (any_tc.in ()))
228 throw DynamicAny::DynAny::TypeMismatch ();
231 // @@@ (JP) Spec also says we should check for illegal Any
232 // value here, and throw InvalidValue if we find one.
233 // Something like a null string will be caught in the constructor.
235 this->any_ = any;
238 CORBA::Any_ptr
239 TAO_DynAny_i::to_any ()
241 if (this->destroyed_)
243 throw ::CORBA::OBJECT_NOT_EXIST ();
246 CORBA::Any_ptr retval;
248 ACE_NEW_THROW_EX (retval,
249 CORBA::Any (this->any_),
250 CORBA::NO_MEMORY ());
252 return retval;
255 CORBA::Boolean
256 TAO_DynAny_i::equal (DynamicAny::DynAny_ptr rhs)
258 if (this->destroyed_)
260 throw ::CORBA::OBJECT_NOT_EXIST ();
263 TAO_DynAny_i *rhs_n = TAO_DynAny_i::_narrow (rhs);
265 if (rhs_n == 0)
267 return false;
270 if (!this->type_->equivalent (rhs_n->type_.in ()))
272 return false;
275 CORBA::TCKind tk = TAO_DynAnyFactory::unalias (this->type_.in ());
277 switch (tk)
279 case CORBA::tk_null:
280 case CORBA::tk_void:
281 return true;
282 case CORBA::tk_short:
284 CORBA::Short rhs_v;
285 rhs_n->any_ >>= rhs_v;
286 CORBA::Short lhs_v;
287 this->any_ >>= lhs_v;
288 return (lhs_v == rhs_v);
290 case CORBA::tk_long:
292 CORBA::Long rhs_v;
293 rhs_n->any_ >>= rhs_v;
294 CORBA::Long lhs_v;
295 this->any_ >>= lhs_v;
296 return (lhs_v == rhs_v);
298 case CORBA::tk_ushort:
300 CORBA::UShort rhs_v;
301 rhs_n->any_ >>= rhs_v;
302 CORBA::UShort lhs_v;
303 this->any_ >>= lhs_v;
304 return (lhs_v == rhs_v);
306 case CORBA::tk_ulong:
308 CORBA::ULong rhs_v;
309 rhs_n->any_ >>= rhs_v;
310 CORBA::ULong lhs_v;
311 this->any_ >>= lhs_v;
312 return (lhs_v == rhs_v);
314 case CORBA::tk_float:
316 CORBA::Float rhs_v;
317 rhs_n->any_ >>= rhs_v;
318 CORBA::Float lhs_v;
319 this->any_ >>= lhs_v;
320 return ACE::is_equal (lhs_v, rhs_v);
322 case CORBA::tk_double:
324 CORBA::Double rhs_v;
325 rhs_n->any_ >>= rhs_v;
326 CORBA::Double lhs_v;
327 this->any_ >>= lhs_v;
328 return ACE::is_equal (lhs_v, rhs_v);
330 case CORBA::tk_longdouble:
332 CORBA::LongDouble rhs_v;
333 rhs_n->any_ >>= rhs_v;
334 CORBA::LongDouble lhs_v;
335 this->any_ >>= lhs_v;
336 return ACE::is_equal (lhs_v, rhs_v);
338 case CORBA::tk_longlong:
340 CORBA::LongLong rhs_v;
341 rhs_n->any_ >>= rhs_v;
342 CORBA::LongLong lhs_v;
343 this->any_ >>= lhs_v;
344 return (lhs_v == rhs_v);
346 case CORBA::tk_ulonglong:
348 CORBA::ULongLong rhs_v;
349 rhs_n->any_ >>= rhs_v;
350 CORBA::ULongLong lhs_v;
351 this->any_ >>= lhs_v;
352 return (lhs_v == rhs_v);
354 case CORBA::tk_boolean:
356 CORBA::Boolean rhs_v;
357 rhs_n->any_ >>= CORBA::Any::to_boolean (rhs_v);
358 CORBA::Boolean lhs_v;
359 this->any_ >>= CORBA::Any::to_boolean (lhs_v);
360 return (lhs_v == rhs_v);
362 case CORBA::tk_char:
364 CORBA::Char rhs_v;
365 rhs_n->any_ >>= CORBA::Any::to_char (rhs_v);
366 CORBA::Char lhs_v;
367 this->any_ >>= CORBA::Any::to_char (lhs_v);
368 return (lhs_v == rhs_v);
370 case CORBA::tk_wchar:
372 CORBA::WChar rhs_v;
373 rhs_n->any_ >>= CORBA::Any::to_wchar (rhs_v);
374 CORBA::WChar lhs_v;
375 this->any_ >>= CORBA::Any::to_wchar (lhs_v);
376 return (lhs_v == rhs_v);
378 case CORBA::tk_octet:
380 CORBA::Octet rhs_v;
381 rhs_n->any_ >>= CORBA::Any::to_octet (rhs_v);
382 CORBA::Octet lhs_v;
383 this->any_ >>= CORBA::Any::to_octet (lhs_v);
384 return (lhs_v == rhs_v);
386 case CORBA::tk_any:
388 const CORBA::Any *rhs_v;
389 rhs_n->any_ >>= rhs_v;
390 const CORBA::Any *lhs_v;
391 this->any_ >>= lhs_v;
393 DynamicAny::DynAny_var rhs_dyn =
394 TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
395 rhs_v->_tao_get_typecode (),
396 *rhs_v,
397 this->allow_truncation_ );
399 DynamicAny::DynAny_var lhs_dyn =
400 TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> (
401 lhs_v->_tao_get_typecode (),
402 *lhs_v,
403 this->allow_truncation_ );
405 CORBA::Boolean const b = rhs_dyn->equal (lhs_dyn.in ());
407 rhs_dyn->destroy ();
409 lhs_dyn->destroy ();
411 return b;
413 case CORBA::tk_TypeCode:
415 CORBA::TypeCode_ptr rhs_v;
416 rhs_n->any_ >>= rhs_v;
417 CORBA::TypeCode_ptr lhs_v;
418 this->any_ >>= lhs_v;
419 // See CORBA 2.4.2 - must use equal() here.
420 return lhs_v->equal (lhs_v);
422 case CORBA::tk_objref:
424 CORBA::Object_ptr rhs_v;
425 rhs_n->any_ >>= CORBA::Any::to_object (rhs_v);
426 CORBA::Object_ptr lhs_v;
427 this->any_ >>= CORBA::Any::to_object (lhs_v);
428 return lhs_v->_is_equivalent (lhs_v);
430 case CORBA::tk_string:
432 CORBA::TypeCode_var unaliased_tc =
433 TAO_DynAnyFactory::strip_alias (this->type_.in ());
435 CORBA::ULong bound =
436 unaliased_tc->length ();
438 const char *rhs_v, *lhs_v;
439 CORBA::Boolean rstatus, lstatus;
441 if (bound == 0)
443 rstatus = rhs_n->any_ >>= rhs_v;
444 lstatus = this->any_ >>= lhs_v;
446 if ((rstatus && lstatus) == 0)
448 return 0;
451 else
453 rstatus = rhs_n->any_ >>= CORBA::Any::to_string (rhs_v, bound);
454 lstatus = this->any_ >>= CORBA::Any::to_string (lhs_v, bound);
456 if ((rstatus && lstatus) == 0)
458 return 0;
462 return ACE_OS::strcmp (rhs_v, lhs_v) == 0;
464 case CORBA::tk_wstring:
466 CORBA::TypeCode_var unaliased_tc =
467 TAO_DynAnyFactory::strip_alias (this->type_.in ());
469 CORBA::ULong bound =
470 unaliased_tc->length ();
472 const CORBA::WChar *rhs_v, *lhs_v;
473 CORBA::Boolean rstatus, lstatus;
475 if (bound == 0)
477 rstatus = rhs_n->any_ >>= rhs_v;
478 lstatus = this->any_ >>= lhs_v;
480 if ((rstatus && lstatus) == 0)
482 return 0;
485 else
487 rstatus = rhs_n->any_ >>= CORBA::Any::to_wstring (rhs_v,
488 bound);
489 lstatus = this->any_ >>= CORBA::Any::to_wstring (lhs_v,
490 bound);
492 if ((rstatus && lstatus) == 0)
494 return 0;
498 return ACE_OS::wscmp (rhs_v, lhs_v) == 0;
500 case CORBA::tk_sequence:
502 // The only way we can get here is if we have a basic sequence (see check_typecode)
503 CORBA::TypeCode_var unaliased_tc =
504 TAO_DynAnyFactory::strip_alias (this->type_.in ());
506 CORBA::TCKind tk_content = TAO_DynAnyFactory::unalias (unaliased_tc->content_type());
508 switch (tk_content)
510 case CORBA::tk_short:
512 CORBA::ShortSeq_var lvalues(this->get_short_seq());
513 CORBA::ShortSeq_var rvalues(rhs_n->get_short_seq());
515 if (lvalues->length() != rvalues->length())
517 return 0;
520 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
522 if (lvalues[i] != rvalues[i])
523 return 0;
525 return 1; // If we get to here, all was equal
527 break;
529 case CORBA::tk_long:
531 CORBA::LongSeq_var lvalues(this->get_long_seq());
532 CORBA::LongSeq_var rvalues(rhs_n->get_long_seq());
534 if (lvalues->length() != rvalues->length())
536 return 0;
539 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
541 if (lvalues[i] != rvalues[i])
543 return 0;
546 return 1; // If we get to here, all was equal
548 break;
550 case CORBA::tk_ushort:
552 CORBA::UShortSeq_var lvalues(this->get_ushort_seq());
553 CORBA::UShortSeq_var rvalues(rhs_n->get_ushort_seq());
555 if (lvalues->length() != rvalues->length())
557 return 0;
560 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
562 if (lvalues[i] != rvalues[i])
564 return 0;
567 return 1; // If we get to here, all was equal
569 break;
571 case CORBA::tk_ulong:
573 CORBA::ULongSeq_var lvalues(this->get_ulong_seq());
574 CORBA::ULongSeq_var rvalues(rhs_n->get_ulong_seq());
576 if (lvalues->length() != rvalues->length())
578 return 0;
581 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
583 if (lvalues[i] != rvalues[i])
585 return 0;
588 return 1; // If we get to here, all was equal
590 break;
592 case CORBA::tk_float:
594 CORBA::FloatSeq_var lvalues(this->get_float_seq());
595 CORBA::FloatSeq_var rvalues(rhs_n->get_float_seq());
597 if (lvalues->length() != rvalues->length())
599 return 0;
602 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
604 if (ACE::is_inequal (lvalues[i], rvalues[i]))
606 return 0;
609 return 1; // If we get to here, all was equal
611 break;
613 case CORBA::tk_double:
615 CORBA::DoubleSeq_var lvalues(this->get_double_seq());
616 CORBA::DoubleSeq_var rvalues(rhs_n->get_double_seq());
618 if (lvalues->length() != rvalues->length())
620 return 0;
623 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
625 if (ACE::is_inequal (lvalues[i], rvalues[i]))
627 return 0;
630 return 1; // If we get to here, all was equal
632 break;
634 case CORBA::tk_longlong:
636 CORBA::LongLongSeq_var lvalues(this->get_longlong_seq());
637 CORBA::LongLongSeq_var rvalues(rhs_n->get_longlong_seq());
639 if (lvalues->length() != rvalues->length())
641 return 0;
644 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
646 if (lvalues[i] != rvalues[i])
648 return 0;
651 return 1; // If we get to here, all was equal
653 break;
655 case CORBA::tk_ulonglong:
657 CORBA::ULongLongSeq_var lvalues(this->get_ulonglong_seq());
658 CORBA::ULongLongSeq_var rvalues(rhs_n->get_ulonglong_seq());
660 if (lvalues->length() != rvalues->length())
662 return 0;
665 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
667 if (lvalues[i] != rvalues[i])
669 return 0;
672 return 1; // If we get to here, all was equal
674 break;
676 case CORBA::tk_boolean:
678 CORBA::BooleanSeq_var lvalues(this->get_boolean_seq());
679 CORBA::BooleanSeq_var rvalues(rhs_n->get_boolean_seq());
681 if (lvalues->length() != rvalues->length())
683 return 0;
686 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
688 if (lvalues[i] != rvalues[i])
690 return 0;
693 return 1; // If we get to here, all was equal
695 break;
697 case CORBA::tk_char:
699 CORBA::CharSeq_var lvalues(this->get_char_seq());
700 CORBA::CharSeq_var rvalues(rhs_n->get_char_seq());
702 if (lvalues->length() != rvalues->length())
704 return 0;
707 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
709 if (lvalues[i] != rvalues[i])
711 return 0;
714 return 1; // If we get to here, all was equal
716 break;
718 case CORBA::tk_wchar:
720 CORBA::WCharSeq_var lvalues(this->get_wchar_seq());
721 CORBA::WCharSeq_var rvalues(rhs_n->get_wchar_seq());
723 if (lvalues->length() != rvalues->length())
725 return 0;
728 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
730 if (lvalues[i] != rvalues[i])
732 return 0;
735 return 1; // If we get to here, all was equal
737 break;
739 case CORBA::tk_octet:
741 CORBA::OctetSeq_var lvalues(this->get_octet_seq());
742 CORBA::OctetSeq_var rvalues(rhs_n->get_octet_seq());
744 if (lvalues->length() != rvalues->length())
746 return 0;
749 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
751 if (lvalues[i] != rvalues[i])
753 return 0;
756 return 1; // If we get to here, all was equal
758 break;
761 case CORBA::tk_longdouble:
763 CORBA::LongDoubleSeq_var lvalues(this->get_longdouble_seq());
764 CORBA::LongDoubleSeq_var rvalues(rhs_n->get_longdouble_seq());
766 if (lvalues->length() != rvalues->length())
768 return 0;
771 for (CORBA::ULong i = 0; i < lvalues->length(); ++i)
773 if (lvalues[i] != rvalues[i])
775 return 0;
778 return 1; // If we get to here, all was equal
780 break;
782 default:
783 // Should never get here
784 break;
788 break;
789 default:
790 break; // Cannot happen...
793 return 0;
796 void
797 TAO_DynAny_i::destroy ()
799 if (this->destroyed_)
801 throw ::CORBA::OBJECT_NOT_EXIST ();
804 if (!this->ref_to_component_ || this->container_is_destroying_)
806 this->destroyed_ = 1;
811 DynamicAny::DynAny_ptr
812 TAO_DynAny_i::current_component ()
814 if (this->destroyed_)
816 throw ::CORBA::OBJECT_NOT_EXIST ();
819 throw DynamicAny::DynAny::TypeMismatch ();
822 TAO_END_VERSIONED_NAMESPACE_DECL