00001
00002
00003 #include "tao/TypeCodeFactory/Recursive_TypeCode.h"
00004 #include "tao/TypeCodeFactory/TypeCodeFactory_i.h"
00005
00006 #include "tao/AnyTypeCode/Marshal.h"
00007 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
00008 #include "tao/AnyTypeCode/Alias_TypeCode.h"
00009 #include "tao/AnyTypeCode/Enum_TypeCode.h"
00010 #include "tao/AnyTypeCode/Fixed_TypeCode.h"
00011 #include "tao/AnyTypeCode/Objref_TypeCode.h"
00012 #include "tao/AnyTypeCode/Sequence_TypeCode.h"
00013 #include "tao/AnyTypeCode/String_TypeCode.h"
00014 #include "tao/AnyTypeCode/Struct_TypeCode.h"
00015 #include "tao/AnyTypeCode/Union_TypeCode.h"
00016 #include "tao/AnyTypeCode/Value_TypeCode.h"
00017 #include "tao/AnyTypeCode/Recursive_Type_TypeCode.h"
00018 #include "tao/AnyTypeCode/TypeCode_Case_T.h"
00019 #include "tao/AnyTypeCode/TypeCode_Struct_Field.h"
00020 #include "tao/AnyTypeCode/TypeCode_Value_Field.h"
00021 #include "tao/AnyTypeCode/True_RefCount_Policy.h"
00022
00023 #include "tao/IFR_Client/IFR_BasicC.h"
00024
00025 #include "tao/ORB_Constants.h"
00026 #include "tao/CDR.h"
00027 #include "tao/SystemException.h"
00028
00029 #include "ace/SString.h"
00030 #include "ace/Containers_T.h"
00031 #include "ace/Hash_Map_Manager_T.h"
00032 #include "ace/Null_Mutex.h"
00033 #include "ace/OS_NS_string.h"
00034 #include "ace/Value_Ptr.h"
00035 #include "ace/OS_NS_ctype.h"
00036
00037 ACE_RCSID (TypeCodeFactory,
00038 TypeCodeFactory_i,
00039 "$Id: TypeCodeFactory_i.cpp 84860 2009-03-17 10:17:38Z johnnyw $")
00040
00041 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00042
00043 namespace TCF
00044 {
00045 namespace Struct
00046 {
00047 typedef
00048 ACE_Array_Base<TAO::TypeCode::Struct_Field<CORBA::String_var,
00049 CORBA::TypeCode_var> >
00050 field_array_type;
00051
00052 typedef TAO::TypeCode::Struct<CORBA::String_var,
00053 CORBA::TypeCode_var,
00054 field_array_type,
00055 TAO::True_RefCount_Policy> typecode_type;
00056
00057 typedef TAO::TypeCode::Recursive_Type<typecode_type,
00058 CORBA::TypeCode_var,
00059 field_array_type>
00060 recursive_typecode_type;
00061
00062 }
00063
00064 namespace Union
00065 {
00066
00067
00068 typedef ACE::Value_Ptr<TAO::TypeCode::Case_Dynamic> elem_type;
00069 typedef ACE_Array_Base<elem_type> case_array_type;
00070
00071 typedef TAO::TypeCode::Union<CORBA::String_var,
00072 CORBA::TypeCode_var,
00073 case_array_type,
00074 TAO::True_RefCount_Policy> typecode_type;
00075
00076 typedef TAO::TypeCode::Recursive_Type<
00077 typecode_type,
00078 CORBA::TypeCode_var,
00079 case_array_type> recursive_typecode_type;
00080 }
00081
00082 namespace Value
00083 {
00084 typedef
00085 ACE_Array_Base<TAO::TypeCode::Value_Field<CORBA::String_var,
00086 CORBA::TypeCode_var> >
00087 field_array_type;
00088
00089 typedef TAO::TypeCode::Value<CORBA::String_var,
00090 CORBA::TypeCode_var,
00091 field_array_type,
00092 TAO::True_RefCount_Policy> typecode_type;
00093
00094 typedef TAO::TypeCode::Recursive_Type<typecode_type,
00095 CORBA::TypeCode_var,
00096 field_array_type>
00097 recursive_typecode_type;
00098 }
00099 }
00100
00101
00102 TAO_TypeCodeFactory_i::TAO_TypeCodeFactory_i (void)
00103 {
00104 }
00105
00106 TAO_TypeCodeFactory_i::~TAO_TypeCodeFactory_i (void)
00107 {
00108 }
00109
00110 TAO_TypeCodeFactory_i *
00111 TAO_TypeCodeFactory_i::_narrow (CORBA::Object_ptr _tao_objref)
00112 {
00113 if (CORBA::is_nil (_tao_objref))
00114 {
00115 return 0;
00116 }
00117
00118 return dynamic_cast<TAO_TypeCodeFactory_i *> (_tao_objref);
00119 }
00120
00121 CORBA::TypeCode_ptr
00122 TAO_TypeCodeFactory_i::create_struct_tc (
00123 const char *id,
00124 const char *name,
00125 const CORBA::StructMemberSeq &members)
00126 {
00127 return this->struct_except_tc_common (id,
00128 name,
00129 members,
00130 CORBA::tk_struct);
00131 }
00132
00133 CORBA::TypeCode_ptr
00134 TAO_TypeCodeFactory_i::create_union_tc (
00135 const char *id,
00136 const char *name,
00137 CORBA::TypeCode_ptr discriminator_type,
00138 const CORBA::UnionMemberSeq &members)
00139 {
00140 CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr ();
00141
00142 if (name == 0 || !this->valid_name (name))
00143 {
00144 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO);
00145 }
00146
00147 if (id == 0 || !this->valid_id (id))
00148 {
00149 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO);
00150 }
00151
00152 CORBA::Boolean const good_disc_type =
00153 this->valid_disc_type (discriminator_type);
00154
00155 if (!good_disc_type)
00156 {
00157 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 20, CORBA::COMPLETED_NO);
00158 }
00159
00160 CORBA::ULong const len = members.length ();
00161 CORBA::ULong dups = 0;
00162 CORBA::ULong raw_default_index = ACE_UINT32_MAX;
00163 CORBA::Long default_index = -1;
00164 CORBA::Octet value = ACE_OCTET_MAX;
00165 ACE_Hash_Map_Manager<ACE_CString, int, ACE_Null_Mutex> map;
00166
00167
00168
00169
00170
00171
00172
00173
00174 for (CORBA::ULong i = 0; i < len; ++i)
00175 {
00176 CORBA::UnionMember const & member = members[i];
00177 char const * const member_name = member.name;
00178
00179 int trybind_status = 0;
00180
00181 if (i > 0)
00182 {
00183
00184
00185 if (ACE_OS::strcmp (member_name, members[i - 1].name) == 0)
00186 {
00187 CORBA::Boolean const equiv =
00188 member.type.in ()->equivalent (members[i - 1].type.in ());
00189
00190
00191
00192
00193
00194 if (equiv)
00195 {
00196 ++dups;
00197 }
00198 else
00199 {
00200 throw ::CORBA::BAD_PARAM (
00201 CORBA::OMGVMCID | 17,
00202 CORBA::COMPLETED_NO);
00203 }
00204 }
00205 else
00206 {
00207
00208
00209 ACE_CString ext_id (member_name);
00210 int int_id = 0;
00211
00212 trybind_status = map.trybind (ext_id, int_id);
00213 }
00214 }
00215 else
00216 {
00217 ACE_CString ext_id (member_name);
00218 int int_id = 0;
00219
00220 trybind_status = map.trybind (ext_id, int_id);
00221 }
00222
00223
00224 if (trybind_status != 0)
00225 {
00226 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 17, CORBA::COMPLETED_NO);
00227 }
00228
00229 CORBA::TypeCode_ptr const tc_holder = member.type.in ();
00230
00231
00232 CORBA::Boolean const valid_member =
00233 this->valid_content_type (tc_holder);
00234
00235 if (!valid_member)
00236 {
00237 throw ::CORBA::BAD_TYPECODE (
00238 CORBA::OMGVMCID | 2,
00239 CORBA::COMPLETED_NO);
00240 }
00241
00242
00243 if ((member.label >>= CORBA::Any::to_octet (value)) == 1)
00244 {
00245 if (value == 0)
00246 {
00247 raw_default_index = i;
00248
00249
00250 default_index = static_cast<CORBA::Long> (i - dups);
00251 }
00252 }
00253 else
00254 {
00255
00256
00257 CORBA::TypeCode_var const tmp = member.label.type ();
00258
00259 CORBA::Boolean const equiv =
00260 discriminator_type->equivalent (tmp.in ()
00261 );
00262
00263 if (!equiv)
00264 {
00265 throw ::CORBA::BAD_PARAM (
00266 CORBA::OMGVMCID | 19,
00267 CORBA::COMPLETED_NO);
00268 }
00269 }
00270 }
00271
00272 CORBA::Boolean const unique_labels =
00273 this->unique_label_values (members,
00274 discriminator_type,
00275 raw_default_index
00276 );
00277
00278 if (!unique_labels)
00279 {
00280 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 18, CORBA::COMPLETED_NO);
00281 }
00282
00283 using namespace TCF::Union;
00284
00285 case_array_type cases (len - dups);
00286
00287 CORBA::TCKind const kind =
00288 discriminator_type->kind ();
00289
00290 CORBA::ULong ci = 0;
00291
00292 bool is_recursive = false;
00293 CORBA::TypeCode_var recursive_tc;
00294
00295 for (CORBA::ULong index = 0; index < len; ++index)
00296 {
00297 CORBA::UnionMember const & member = members[index];
00298
00299 if (index > 0)
00300 {
00301
00302
00303 if (ACE_OS::strcmp (member.name,
00304 members[index - 1].name) == 0)
00305 {
00306 continue;
00307 }
00308 }
00309
00310
00311 bool const recursion_detected =
00312 this->check_recursion (CORBA::tk_union,
00313 id,
00314 member.type.in (),
00315 recursive_tc.inout (),
00316 0);
00317
00318
00319 if (recursion_detected)
00320 {
00321 is_recursive = true;
00322 }
00323
00324 elem_type & element = cases[ci];
00325 TAO::TypeCode::Case_Dynamic * the_case = 0;
00326
00327 if (index == raw_default_index)
00328 {
00329
00330 this->compute_default_label (kind,
00331 index,
00332 members,
00333 the_case);
00334
00335 if (the_case == 0)
00336 {
00337
00338
00339 throw ::CORBA::BAD_PARAM (
00340 CORBA::OMGVMCID | 19,
00341 CORBA::COMPLETED_NO);
00342 }
00343 }
00344 else
00345 {
00346
00347 switch (kind)
00348 {
00349 case CORBA::tk_enum:
00350 {
00351 TAO::Any_Impl * const impl = member.label.impl ();
00352 TAO_InputCDR for_reading (
00353 static_cast<ACE_Message_Block *> (0));
00354
00355 if (impl->encoded ())
00356 {
00357 TAO::Unknown_IDL_Type * const unk =
00358 dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
00359
00360 if (!unk)
00361 throw CORBA::INTERNAL ();
00362
00363
00364
00365
00366 for_reading = unk->_tao_get_cdr ();
00367 }
00368 else
00369 {
00370 TAO_OutputCDR out;
00371 impl->marshal_value (out);
00372 TAO_InputCDR tmp (out);
00373 for_reading = tmp;
00374 }
00375
00376 CORBA::ULong label;
00377 for_reading.read_ulong (label);
00378
00379 typedef TAO::TypeCode::Case_T<CORBA::ULong,
00380 CORBA::String_var,
00381 CORBA::TypeCode_var> case_type;
00382
00383 ACE_NEW_THROW_EX (the_case,
00384 case_type (label),
00385 CORBA::NO_MEMORY ());
00386 }
00387 break;
00388 case CORBA::tk_ulong:
00389 {
00390 CORBA::ULong label;
00391 if (!(member.label >>= label))
00392 {
00393
00394
00395 throw ::CORBA::BAD_PARAM (
00396 CORBA::OMGVMCID | 19,
00397 CORBA::COMPLETED_NO);
00398 }
00399
00400 typedef TAO::TypeCode::Case_T<CORBA::ULong,
00401 CORBA::String_var,
00402 CORBA::TypeCode_var> case_type;
00403
00404 ACE_NEW_THROW_EX (the_case,
00405 case_type (label),
00406 CORBA::NO_MEMORY ());
00407 }
00408 break;
00409 case CORBA::tk_long:
00410 {
00411 CORBA::Long label;
00412 if (!(member.label >>= label))
00413 {
00414
00415
00416 throw ::CORBA::BAD_PARAM (
00417 CORBA::OMGVMCID | 19,
00418 CORBA::COMPLETED_NO);
00419 }
00420
00421 typedef TAO::TypeCode::Case_T<CORBA::Long,
00422 CORBA::String_var,
00423 CORBA::TypeCode_var> case_type;
00424
00425 ACE_NEW_THROW_EX (the_case,
00426 case_type (label),
00427 CORBA::NO_MEMORY ());
00428 }
00429 break;
00430 case CORBA::tk_ushort:
00431 {
00432 CORBA::UShort label;
00433 if (!(member.label >>= label))
00434 {
00435
00436
00437 throw ::CORBA::BAD_PARAM (
00438 CORBA::OMGVMCID | 19,
00439 CORBA::COMPLETED_NO);
00440 }
00441
00442 typedef TAO::TypeCode::Case_T<CORBA::UShort,
00443 CORBA::String_var,
00444 CORBA::TypeCode_var> case_type;
00445
00446 ACE_NEW_THROW_EX (the_case,
00447 case_type (label),
00448 CORBA::NO_MEMORY ());
00449 }
00450 break;
00451 case CORBA::tk_short:
00452 {
00453 CORBA::Short label;
00454 if (!(member.label >>= label))
00455 {
00456
00457
00458 throw ::CORBA::BAD_PARAM (
00459 CORBA::OMGVMCID | 19,
00460 CORBA::COMPLETED_NO);
00461 }
00462
00463 typedef TAO::TypeCode::Case_T<CORBA::Short,
00464 CORBA::String_var,
00465 CORBA::TypeCode_var> case_type;
00466
00467 ACE_NEW_THROW_EX (the_case,
00468 case_type (label),
00469 CORBA::NO_MEMORY ());
00470 }
00471 break;
00472 case CORBA::tk_char:
00473 {
00474 CORBA::Char label;
00475 if (!(member.label >>= CORBA::Any::to_char (label)))
00476 {
00477
00478
00479 throw ::CORBA::BAD_PARAM (
00480 CORBA::OMGVMCID | 19,
00481 CORBA::COMPLETED_NO);
00482 }
00483
00484 typedef TAO::TypeCode::Case_T<CORBA::Char,
00485 CORBA::String_var,
00486 CORBA::TypeCode_var> case_type;
00487
00488 ACE_NEW_THROW_EX (the_case,
00489 case_type (label),
00490 CORBA::NO_MEMORY ());
00491 }
00492 break;
00493 case CORBA::tk_boolean:
00494 {
00495 CORBA::Boolean label;
00496 if (!(member.label >>= CORBA::Any::to_boolean (label)))
00497 {
00498
00499
00500 throw ::CORBA::BAD_PARAM (
00501 CORBA::OMGVMCID | 19,
00502 CORBA::COMPLETED_NO);
00503 }
00504
00505 typedef TAO::TypeCode::Case_T<CORBA::Boolean,
00506 CORBA::String_var,
00507 CORBA::TypeCode_var> case_type;
00508
00509 ACE_NEW_THROW_EX (the_case,
00510 case_type (label),
00511 CORBA::NO_MEMORY ());
00512 }
00513 break;
00514 case CORBA::tk_longlong:
00515 {
00516 CORBA::LongLong label;
00517 if (!(member.label >>= label))
00518 {
00519
00520
00521 throw ::CORBA::BAD_PARAM (
00522 CORBA::OMGVMCID | 19,
00523 CORBA::COMPLETED_NO);
00524 }
00525
00526 typedef TAO::TypeCode::Case_T<CORBA::LongLong,
00527 CORBA::String_var,
00528 CORBA::TypeCode_var> case_type;
00529
00530 ACE_NEW_THROW_EX (the_case,
00531 case_type (label),
00532 CORBA::NO_MEMORY ());
00533 }
00534 break;
00535 #if !defined (ACE_LACKS_LONGLONG_T)
00536 case CORBA::tk_ulonglong:
00537 {
00538 CORBA::ULongLong label;
00539 if (!(member.label >>= label))
00540 {
00541
00542
00543 throw ::CORBA::BAD_PARAM (
00544 CORBA::OMGVMCID | 19,
00545 CORBA::COMPLETED_NO);
00546 }
00547
00548 typedef TAO::TypeCode::Case_T<CORBA::ULongLong,
00549 CORBA::String_var,
00550 CORBA::TypeCode_var> case_type;
00551
00552 ACE_NEW_THROW_EX (the_case,
00553 case_type (label),
00554 CORBA::NO_MEMORY ());
00555 }
00556 break;
00557 #endif
00558 default:
00559 throw ::CORBA::BAD_PARAM (
00560 CORBA::OMGVMCID | 20,
00561 CORBA::COMPLETED_NO);
00562 }
00563 }
00564
00565 ++ci;
00566
00567 elem_type case_value (the_case);
00568 element.swap (case_value);
00569
00570 element->name (member.name.in ());
00571 element->type (member.type.in ());
00572 }
00573
00574
00575 CORBA::TypeCode_var duped_disc_type (
00576 CORBA::TypeCode::_duplicate (discriminator_type));
00577
00578 if (is_recursive)
00579 {
00580
00581 recursive_typecode_type * const rtc =
00582 dynamic_cast<recursive_typecode_type *> (recursive_tc.in ());
00583
00584 if (!rtc)
00585 {
00586 throw CORBA::INTERNAL ();
00587 }
00588
00589 rtc->union_parameters (name,
00590 duped_disc_type,
00591 cases,
00592 cases.size (),
00593 default_index);
00594
00595 return recursive_tc._retn ();
00596 }
00597
00598 ACE_NEW_THROW_EX (tc,
00599 typecode_type (id,
00600 name,
00601 duped_disc_type,
00602 cases,
00603 cases.size (),
00604 default_index),
00605 CORBA::NO_MEMORY ());
00606
00607 return tc;
00608 }
00609
00610 CORBA::TypeCode_ptr
00611 TAO_TypeCodeFactory_i::create_enum_tc (
00612 const char *id,
00613 const char *name,
00614 const CORBA::EnumMemberSeq &members)
00615 {
00616 CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr ();
00617
00618 if (name == 0 || !this->valid_name (name))
00619 {
00620 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO);
00621 }
00622
00623 if (id == 0 || !this->valid_id (id))
00624 {
00625 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO);
00626 }
00627
00628 CORBA::ULong const len = members.length ();
00629
00630 ACE_Hash_Map_Manager<ACE_CString, int, ACE_Null_Mutex> map;
00631
00632 ACE_Array_Base<CORBA::String_var> enumerators (len);
00633
00634 for (CORBA::ULong index = 0; index < len; ++index)
00635 {
00636 ACE_CString ext_id (members[index]);
00637 int int_id = 0;
00638
00639
00640 if (map.trybind (ext_id, int_id) != 0)
00641 {
00642 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 17, CORBA::COMPLETED_NO);
00643 }
00644
00645 enumerators[index] = members[index];
00646 }
00647
00648 typedef TAO::TypeCode::Enum<
00649 CORBA::String_var,
00650 ACE_Array_Base<CORBA::String_var>,
00651 TAO::True_RefCount_Policy> typecode_type;
00652
00653 ACE_NEW_THROW_EX (tc,
00654 typecode_type (id,
00655 name,
00656 enumerators,
00657 len),
00658 CORBA::NO_MEMORY ());
00659
00660 return tc;
00661 }
00662
00663 CORBA::TypeCode_ptr
00664 TAO_TypeCodeFactory_i::create_alias_tc (
00665 const char *id,
00666 const char *name,
00667 CORBA::TypeCode_ptr original_type)
00668 {
00669 return this->alias_value_box_tc_common (id,
00670 name,
00671 original_type,
00672 CORBA::tk_alias);
00673 }
00674
00675 CORBA::TypeCode_ptr
00676 TAO_TypeCodeFactory_i::create_exception_tc (
00677 const char *id,
00678 const char *name,
00679 const CORBA::StructMemberSeq &members)
00680 {
00681 return this->struct_except_tc_common (id,
00682 name,
00683 members,
00684 CORBA::tk_except);
00685 }
00686
00687 CORBA::TypeCode_ptr
00688 TAO_TypeCodeFactory_i::create_interface_tc (
00689 const char *id,
00690 const char *name)
00691 {
00692 return this->create_tc_common (id,
00693 name,
00694 CORBA::tk_objref);
00695 }
00696
00697 CORBA::TypeCode_ptr
00698 TAO_TypeCodeFactory_i::create_string_tc (CORBA::ULong bound)
00699 {
00700 return this->string_wstring_tc_common (bound,
00701 CORBA::tk_string);
00702 }
00703
00704 CORBA::TypeCode_ptr
00705 TAO_TypeCodeFactory_i::create_wstring_tc (CORBA::ULong bound)
00706 {
00707 return this->string_wstring_tc_common (bound,
00708 CORBA::tk_wstring);
00709 }
00710
00711 CORBA::TypeCode_ptr
00712 TAO_TypeCodeFactory_i::create_fixed_tc (
00713 CORBA::UShort digits,
00714 CORBA::UShort scale)
00715 {
00716 CORBA::TypeCode_ptr tc;
00717 ACE_NEW_THROW_EX (tc,
00718 TAO::TypeCode::Fixed<TAO::True_RefCount_Policy> (digits,
00719 scale),
00720 CORBA::NO_MEMORY ());
00721
00722 return tc;
00723 }
00724
00725 CORBA::TypeCode_ptr
00726 TAO_TypeCodeFactory_i::create_sequence_tc (
00727 CORBA::ULong bound,
00728 CORBA::TypeCode_ptr element_type)
00729 {
00730 return sequence_array_tc_common (bound,
00731 element_type,
00732 CORBA::tk_sequence);
00733 }
00734
00735 CORBA::TypeCode_ptr
00736 TAO_TypeCodeFactory_i::create_array_tc (
00737 CORBA::ULong length,
00738 CORBA::TypeCode_ptr element_type)
00739 {
00740 return sequence_array_tc_common (length, element_type, CORBA::tk_array);
00741 }
00742
00743 CORBA::TypeCode_ptr
00744 TAO_TypeCodeFactory_i::create_value_tc (
00745 const char *id,
00746 const char *name,
00747 CORBA::ValueModifier type_modifier,
00748 CORBA::TypeCode_ptr concrete_base,
00749 const CORBA::ValueMemberSeq &members
00750 )
00751 {
00752 return this->value_event_tc_common (id,
00753 name,
00754 type_modifier,
00755 concrete_base,
00756 members,
00757 CORBA::tk_value
00758 );
00759 }
00760
00761 CORBA::TypeCode_ptr
00762 TAO_TypeCodeFactory_i::create_value_box_tc (
00763 const char *id,
00764 const char *name,
00765 CORBA::TypeCode_ptr boxed_type
00766 )
00767 {
00768 return this->alias_value_box_tc_common (id,
00769 name,
00770 boxed_type,
00771 CORBA::tk_value_box);
00772 }
00773
00774 CORBA::TypeCode_ptr
00775 TAO_TypeCodeFactory_i::create_native_tc (
00776 const char *id,
00777 const char *name
00778 )
00779 {
00780 return this->create_tc_common (id,
00781 name,
00782 CORBA::tk_native);
00783 }
00784
00785 CORBA::TypeCode_ptr
00786 TAO_TypeCodeFactory_i::create_recursive_tc (const char *id)
00787 {
00788 CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr ();
00789
00790 if (id == 0 || !this->valid_id (id))
00791 {
00792 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO);
00793 }
00794
00795 ACE_NEW_THROW_EX (tc,
00796 TAO::TypeCodeFactory::Recursive_TypeCode (id),
00797 CORBA::NO_MEMORY ());
00798
00799 return tc;
00800 }
00801
00802 CORBA::TypeCode_ptr
00803 TAO_TypeCodeFactory_i::create_abstract_interface_tc (
00804 const char *id,
00805 const char *name
00806 )
00807 {
00808 return this->create_tc_common (id,
00809 name,
00810 CORBA::tk_abstract_interface
00811 );
00812 }
00813
00814 CORBA::TypeCode_ptr
00815 TAO_TypeCodeFactory_i::create_local_interface_tc (
00816 const char *id,
00817 const char *name
00818 )
00819 {
00820 return this->create_tc_common (id,
00821 name,
00822 CORBA::tk_local_interface
00823 );
00824 }
00825
00826 CORBA::TypeCode_ptr
00827 TAO_TypeCodeFactory_i::create_component_tc (
00828 const char *id,
00829 const char *name
00830 )
00831 {
00832 return this->create_tc_common (id,
00833 name,
00834 CORBA::tk_component);
00835 }
00836
00837 CORBA::TypeCode_ptr
00838 TAO_TypeCodeFactory_i::create_home_tc (const char *id, const char *name)
00839 {
00840 return this->create_tc_common (id,
00841 name,
00842 CORBA::tk_home);
00843 }
00844
00845 CORBA::TypeCode_ptr
00846 TAO_TypeCodeFactory_i::create_event_tc (
00847 const char *id,
00848 const char *name,
00849 CORBA::ValueModifier type_modifier,
00850 CORBA::TypeCode_ptr concrete_base,
00851 const CORBA::ValueMemberSeq &members)
00852 {
00853 return this->value_event_tc_common (id,
00854 name,
00855 type_modifier,
00856 concrete_base,
00857 members,
00858 CORBA::tk_event);
00859 }
00860
00861
00862
00863 void
00864 TAO_TypeCodeFactory_i::compute_default_label (
00865 CORBA::TCKind kind,
00866 CORBA::ULong skip_slot,
00867 const CORBA::UnionMemberSeq &members,
00868 TAO::TypeCode::Case_Dynamic *& the_case)
00869 {
00870
00871
00872 struct disc_types
00873 {
00874 CORBA::Char char_val;
00875 CORBA::Boolean bool_val;
00876 CORBA::Short short_val;
00877 CORBA::UShort ushort_val;
00878 CORBA::Long long_val;
00879 CORBA::ULong ulong_val;
00880 #if !defined (ACE_LACKS_LONGLONG_T)
00881 CORBA::ULongLong ulonglong_val;
00882 #endif
00883 CORBA::ULong enum_val;
00884
00885 } dv, u;
00886
00887 dv.char_val = 0;
00888 dv.bool_val = 0;
00889 dv.short_val = ACE_INT16_MIN;
00890 dv.ushort_val = 0;
00891 dv.long_val = ACE_INT32_MIN;
00892 dv.ulong_val = 0;
00893 #if !defined (ACE_LACKS_LONGLONG_T)
00894 dv.ulonglong_val = 0;
00895 #endif
00896 dv.enum_val = 0;
00897
00898 CORBA::ULong const len = members.length ();
00899 bool success = false;
00900
00901
00902
00903 while (!success)
00904 {
00905 success = true;
00906
00907 for (CORBA::ULong i = 0; i < len; ++i)
00908 {
00909
00910 if (i == skip_slot)
00911 {
00912 continue;
00913 }
00914
00915
00916 switch (kind)
00917 {
00918 case CORBA::tk_char:
00919 members[i].label >>= CORBA::Any::to_char (u.char_val);
00920
00921 if (u.char_val == dv.char_val)
00922 {
00923 dv.char_val++;
00924 success = false;
00925 }
00926 break;
00927 case CORBA::tk_boolean:
00928 members[i].label >>= CORBA::Any::to_boolean (u.bool_val);
00929
00930 if (u.bool_val == dv.bool_val)
00931 {
00932 dv.bool_val = !dv.bool_val;
00933 success = false;
00934 }
00935 break;
00936 case CORBA::tk_short:
00937 members[i].label >>= u.short_val;
00938
00939 if (u.short_val == dv.short_val)
00940 {
00941 dv.short_val++;
00942 success = false;
00943 }
00944 break;
00945 case CORBA::tk_ushort:
00946 members[i].label >>= u.ushort_val;
00947
00948 if (u.ushort_val == dv.ushort_val)
00949 {
00950 dv.ushort_val++;
00951 success = false;
00952 }
00953 break;
00954 case CORBA::tk_long:
00955 members[i].label >>= u.long_val;
00956
00957 if (u.long_val == dv.long_val)
00958 {
00959 dv.long_val++;
00960 success = false;
00961 }
00962 break;
00963 case CORBA::tk_ulong:
00964 members[i].label >>= u.ulong_val;
00965
00966 if (u.ulong_val == dv.ulong_val)
00967 {
00968 dv.ulong_val++;
00969 success = false;
00970 }
00971 break;
00972 #if !defined (ACE_LACKS_LONGLONG_T)
00973 case CORBA::tk_ulonglong:
00974 members[i].label >>= u.ulonglong_val;
00975
00976 if (u.ulonglong_val == dv.ulonglong_val)
00977 {
00978 dv.ulonglong_val++;
00979 success = false;
00980 }
00981 break;
00982 #endif
00983 case CORBA::tk_enum:
00984 {
00985 TAO::Any_Impl *impl = members[i].label.impl ();
00986 TAO_InputCDR for_reading (static_cast<ACE_Message_Block *> (0));
00987
00988 if (impl->encoded ())
00989 {
00990 TAO::Unknown_IDL_Type *unk =
00991 dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
00992
00993 if (!unk)
00994 throw CORBA::INTERNAL ();
00995
00996
00997
00998
00999 for_reading = unk->_tao_get_cdr ();
01000 }
01001 else
01002 {
01003 TAO_OutputCDR out;
01004 impl->marshal_value (out);
01005 TAO_InputCDR tmp (out);
01006 for_reading = tmp;
01007 }
01008
01009 for_reading.read_ulong (u.enum_val);
01010
01011 if (u.enum_val == dv.enum_val)
01012 {
01013 dv.enum_val++;
01014 success = false;
01015 }
01016 break;
01017 }
01018 default:
01019 break;
01020 }
01021
01022
01023 if (!success)
01024 {
01025 break;
01026 }
01027 }
01028 }
01029
01030
01031 switch (kind)
01032 {
01033 case CORBA::tk_char:
01034 {
01035 typedef TAO::TypeCode::Case_T<CORBA::Char,
01036 CORBA::String_var,
01037 CORBA::TypeCode_var> case_type;
01038
01039 ACE_NEW (the_case,
01040 case_type (dv.char_val));
01041 }
01042 break;
01043 case CORBA::tk_boolean:
01044 {
01045 typedef TAO::TypeCode::Case_T<CORBA::Boolean,
01046 CORBA::String_var,
01047 CORBA::TypeCode_var> case_type;
01048
01049 ACE_NEW (the_case,
01050 case_type (dv.bool_val));
01051 }
01052 break;
01053 case CORBA::tk_short:
01054 {
01055 typedef TAO::TypeCode::Case_T<CORBA::Short,
01056 CORBA::String_var,
01057 CORBA::TypeCode_var> case_type;
01058
01059 ACE_NEW (the_case,
01060 case_type (dv.short_val));
01061 }
01062 break;
01063 case CORBA::tk_ushort:
01064 {
01065 typedef TAO::TypeCode::Case_T<CORBA::UShort,
01066 CORBA::String_var,
01067 CORBA::TypeCode_var> case_type;
01068
01069 ACE_NEW (the_case,
01070 case_type (dv.ushort_val));
01071 }
01072 break;
01073 case CORBA::tk_long:
01074 {
01075 typedef TAO::TypeCode::Case_T<CORBA::Long,
01076 CORBA::String_var,
01077 CORBA::TypeCode_var> case_type;
01078
01079 ACE_NEW (the_case,
01080 case_type (dv.long_val));
01081 }
01082 break;
01083 case CORBA::tk_ulong:
01084 {
01085 typedef TAO::TypeCode::Case_T<CORBA::ULong,
01086 CORBA::String_var,
01087 CORBA::TypeCode_var> case_type;
01088
01089 ACE_NEW (the_case,
01090 case_type (dv.ulong_val));
01091 }
01092 break;
01093 #if !defined (ACE_LACKS_LONGLONG_T)
01094 case CORBA::tk_ulonglong:
01095 {
01096 typedef TAO::TypeCode::Case_T<CORBA::ULongLong,
01097 CORBA::String_var,
01098 CORBA::TypeCode_var> case_type;
01099
01100 ACE_NEW (the_case,
01101 case_type (dv.ulonglong_val));
01102 }
01103 break;
01104 #endif
01105 case CORBA::tk_enum:
01106 {
01107
01108 typedef TAO::TypeCode::Case_T<CORBA::ULong,
01109 CORBA::String_var,
01110 CORBA::TypeCode_var> case_type;
01111
01112 ACE_NEW (the_case,
01113 case_type (dv.enum_val));
01114 }
01115 break;
01116 default:
01117 break;
01118 }
01119 }
01120
01121 CORBA::TypeCode_ptr
01122 TAO_TypeCodeFactory_i::create_tc_common (
01123 const char *id,
01124 const char *name,
01125 CORBA::TCKind kind
01126
01127 )
01128 {
01129 if (name == 0 || !this->valid_name (name))
01130 {
01131 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO);
01132 }
01133
01134
01135 if (id == 0 || !this->valid_id (id))
01136 {
01137 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO);
01138 }
01139
01140 CORBA::TypeCode_ptr tc;
01141
01142 typedef TAO::TypeCode::Objref<CORBA::String_var,
01143 TAO::True_RefCount_Policy> typecode_type;
01144
01145 ACE_NEW_THROW_EX (tc,
01146 typecode_type (kind, id, name),
01147 CORBA::NO_MEMORY ());
01148
01149 return tc;
01150 }
01151
01152 CORBA::TypeCode_ptr
01153 TAO_TypeCodeFactory_i::string_wstring_tc_common (
01154 CORBA::ULong bound,
01155 CORBA::TCKind kind
01156
01157 )
01158 {
01159 CORBA::TypeCode_ptr tc;
01160 ACE_NEW_THROW_EX (tc,
01161 TAO::TypeCode::String<TAO::True_RefCount_Policy> (kind,
01162 bound),
01163 CORBA::NO_MEMORY ());
01164
01165 return tc;
01166 }
01167
01168 CORBA::TypeCode_ptr
01169 TAO_TypeCodeFactory_i::sequence_array_tc_common (
01170 CORBA::ULong bound,
01171 CORBA::TypeCode_ptr element_type,
01172 CORBA::TCKind kind)
01173 {
01174 CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr ();
01175
01176 CORBA::Boolean const valid_element =
01177 this->valid_content_type (element_type);
01178
01179 if (!valid_element)
01180 {
01181 throw ::CORBA::BAD_TYPECODE (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
01182 }
01183
01184 CORBA::TypeCode_var tmp (CORBA::TypeCode::_duplicate (element_type));
01185
01186 typedef TAO::TypeCode::Sequence<CORBA::TypeCode_var,
01187 TAO::True_RefCount_Policy> typecode_type;
01188
01189 ACE_NEW_THROW_EX (tc,
01190 typecode_type (kind, tmp, bound),
01191 CORBA::NO_MEMORY ());
01192
01193 return tc;
01194 }
01195
01196 CORBA::TypeCode_ptr
01197 TAO_TypeCodeFactory_i::struct_except_tc_common (
01198 const char *id,
01199 const char *name,
01200 const CORBA::StructMemberSeq & members,
01201 CORBA::TCKind kind
01202
01203 )
01204 {
01205 CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr ();
01206
01207 if (name == 0 || !this->valid_name (name))
01208 {
01209 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO);
01210 }
01211
01212 if (id == 0 || !this->valid_id (id))
01213 {
01214 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO);
01215 }
01216
01217 CORBA::ULong const len = members.length ();
01218
01219 ACE_Hash_Map_Manager<ACE_CString, int, ACE_Null_Mutex> map;
01220
01221 using namespace TCF::Struct;
01222
01223 field_array_type fields (len);
01224
01225 bool is_recursive = false;
01226
01227 CORBA::TypeCode_var recursive_tc;
01228
01229 for (CORBA::ULong index = 0; index < len; ++index)
01230 {
01231
01232 CORBA::TypeCode_ptr const member_tc = members[index].type.in ();
01233
01234 CORBA::Boolean const valid_member =
01235 this->valid_content_type (member_tc
01236 );
01237
01238 if (!valid_member)
01239 {
01240 throw ::CORBA::BAD_TYPECODE (
01241 CORBA::OMGVMCID | 2,
01242 CORBA::COMPLETED_NO);
01243 }
01244
01245 char const * const member_name = members[index].name;
01246
01247 if (member_name == 0 || !this->valid_name (member_name))
01248 {
01249 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO);
01250 }
01251
01252 ACE_CString ext_id (member_name);
01253 int int_id = 0;
01254
01255
01256 if (map.trybind (ext_id, int_id) != 0)
01257 {
01258 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 17, CORBA::COMPLETED_NO);
01259 }
01260
01261 TAO::TypeCode::Struct_Field<CORBA::String_var,
01262 CORBA::TypeCode_var> & field = fields[index];
01263
01264
01265 bool const recursion_detected =
01266 this->check_recursion (kind,
01267 id,
01268 member_tc,
01269 recursive_tc.inout (),
01270 0);
01271
01272
01273 if (recursion_detected)
01274 {
01275 is_recursive = true;
01276 }
01277
01278 field.name = member_name;
01279 field.type = CORBA::TypeCode::_duplicate (member_tc);
01280 }
01281
01282 if (is_recursive)
01283 {
01284 recursive_typecode_type * const rtc =
01285 dynamic_cast<recursive_typecode_type *> (recursive_tc.in ());
01286
01287 if (!rtc)
01288 {
01289 throw CORBA::INTERNAL ();
01290 }
01291
01292 rtc->struct_parameters (name, fields, len);
01293
01294 return recursive_tc._retn ();
01295 }
01296
01297 ACE_NEW_THROW_EX (tc,
01298 typecode_type (kind,
01299 id,
01300 name,
01301 fields,
01302 len),
01303 CORBA::NO_MEMORY ());
01304
01305 return tc;
01306 }
01307
01308 CORBA::TypeCode_ptr
01309 TAO_TypeCodeFactory_i::alias_value_box_tc_common (
01310 const char *id,
01311 const char *name,
01312 CORBA::TypeCode_ptr underlying_type,
01313 CORBA::TCKind kind
01314 )
01315 {
01316 CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr ();
01317
01318 if (name == 0 || !this->valid_name (name))
01319 {
01320 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO);
01321 }
01322
01323 if (id == 0 || !this->valid_id (id))
01324 {
01325 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO);
01326 }
01327
01328 CORBA::Boolean const valid_content =
01329 this->valid_content_type (underlying_type);
01330
01331 if (!valid_content)
01332 {
01333 throw ::CORBA::BAD_TYPECODE (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
01334 }
01335
01336 CORBA::TypeCode_var tmp (CORBA::TypeCode::_duplicate (underlying_type));
01337
01338 typedef TAO::TypeCode::Alias<CORBA::String_var,
01339 CORBA::TypeCode_var,
01340 TAO::True_RefCount_Policy> typecode_type;
01341
01342 ACE_NEW_THROW_EX (tc,
01343 typecode_type (kind, id, name, tmp),
01344 CORBA::NO_MEMORY ());
01345
01346 return tc;
01347 }
01348
01349 CORBA::TypeCode_ptr
01350 TAO_TypeCodeFactory_i::value_event_tc_common (
01351 const char *id,
01352 const char *name,
01353 CORBA::ValueModifier type_modifier,
01354 CORBA::TypeCode_ptr concrete_base,
01355 const CORBA::ValueMemberSeq &members,
01356 CORBA::TCKind kind
01357
01358 )
01359 {
01360 CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr ();
01361
01362 if (name == 0 || !this->valid_name (name))
01363 {
01364 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO);
01365 }
01366
01367 if (id == 0 || !this->valid_id (id))
01368 {
01369 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO);
01370 }
01371
01372 CORBA::ULong const len = members.length ();
01373
01374 using namespace TCF::Value;
01375
01376 field_array_type fields (len);
01377
01378 ACE_Hash_Map_Manager<ACE_CString, int, ACE_Null_Mutex> map;
01379
01380 bool is_recursive = false;
01381 CORBA::TypeCode_var recursive_tc;
01382
01383 for (CORBA::ULong index = 0; index < len; ++index)
01384 {
01385
01386 CORBA::TypeCode_ptr const member_tc = members[index].type.in ();
01387
01388 CORBA::Boolean const valid_member =
01389 this->valid_content_type (member_tc);
01390
01391 if (!valid_member)
01392 {
01393 throw ::CORBA::BAD_TYPECODE (
01394 CORBA::OMGVMCID | 2,
01395 CORBA::COMPLETED_NO);
01396 }
01397
01398 const char * const member_name = members[index].name;
01399
01400 if (member_name == 0 || !this->valid_name (member_name))
01401 {
01402 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO);
01403 }
01404
01405 ACE_CString ext_id (member_name);
01406 int int_id = 0;
01407
01408
01409 if (map.trybind (ext_id, int_id) != 0)
01410 {
01411 throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 17, CORBA::COMPLETED_NO);
01412 }
01413
01414
01415 bool const recursion_detected =
01416 this->check_recursion (kind,
01417 id,
01418 member_tc,
01419 recursive_tc.inout (),
01420 0);
01421
01422
01423 if (recursion_detected)
01424 {
01425 is_recursive = true;
01426 }
01427
01428 TAO::TypeCode::Value_Field<CORBA::String_var,
01429 CORBA::TypeCode_var> & field = fields[index];
01430
01431 field.name = member_name;
01432 field.type = CORBA::TypeCode::_duplicate (member_tc);
01433 field.visibility = members[index].access;
01434 }
01435
01436 CORBA::TypeCode_var tmp (
01437 CORBA::TypeCode::_duplicate (CORBA::is_nil (concrete_base)
01438 ? CORBA::_tc_null
01439 : concrete_base));
01440
01441 if (is_recursive)
01442 {
01443 recursive_typecode_type * const rtc =
01444 dynamic_cast<recursive_typecode_type *> (recursive_tc.in ());
01445
01446 if (!rtc)
01447 {
01448 throw CORBA::INTERNAL ();
01449 }
01450
01451 rtc->valuetype_parameters (name,
01452 type_modifier,
01453 tmp,
01454 fields,
01455 len);
01456
01457 return recursive_tc._retn ();
01458 }
01459
01460 ACE_NEW_THROW_EX (tc,
01461 typecode_type (kind,
01462 id,
01463 name,
01464 type_modifier,
01465 tmp,
01466 fields,
01467 len),
01468 CORBA::NO_MEMORY ());
01469
01470 return tc;
01471 }
01472
01473 CORBA::Boolean
01474 TAO_TypeCodeFactory_i::valid_name (const char *name)
01475 {
01476
01477 if (*name == '\0')
01478 {
01479 return true;
01480 }
01481
01482 if (!ACE_OS::ace_isalpha (*name))
01483 {
01484 return false;
01485 }
01486
01487 const char *tmp = name + 1;
01488
01489 for (; *tmp; ++tmp)
01490 {
01491 if (ACE_OS::ace_isalnum (*tmp) || *tmp == '_')
01492 {
01493 continue;
01494 }
01495 else
01496 {
01497 return false;
01498 }
01499 }
01500
01501 return true;
01502 }
01503
01504 CORBA::Boolean
01505 TAO_TypeCodeFactory_i::valid_id (const char *id)
01506 {
01507 ACE_CString safety (id,
01508 0,
01509 false);
01510
01511 ACE_CString::size_type const pos = safety.find (':');
01512
01513 if (pos == ACE_CString::npos)
01514 {
01515 return 0;
01516 }
01517
01518 ACE_CString format (safety.substr (0, pos));
01519
01520 if (format == "IDL"
01521 || format == "RMI"
01522 || format == "DCE"
01523 || format == "LOCAL")
01524 {
01525 return true;
01526 }
01527
01528 return false;
01529 }
01530
01531 CORBA::Boolean
01532 TAO_TypeCodeFactory_i::valid_content_type (CORBA::TypeCode_ptr tc)
01533 {
01534 CORBA::TCKind const kind =
01535 TAO::unaliased_kind (tc);
01536
01537 switch (kind)
01538 {
01539 case CORBA::TAO_TC_KIND_COUNT:
01540 return true;
01541 case CORBA::tk_void:
01542 case CORBA::tk_except:
01543 return false;
01544 default:
01545 return true;
01546 }
01547 }
01548
01549 CORBA::Boolean
01550 TAO_TypeCodeFactory_i::unique_label_values (
01551 const CORBA::UnionMemberSeq &members,
01552 CORBA::TypeCode_ptr disc_tc,
01553 CORBA::ULong default_index_slot
01554 )
01555 {
01556 CORBA::TCKind disc_kind = disc_tc->kind ();
01557
01558 CORBA::ULong length = members.length ();
01559
01560
01561
01562
01563 struct label_types
01564 {
01565 CORBA::Char char_val;
01566 CORBA::Boolean bool_val;
01567 CORBA::Short short_val;
01568 CORBA::UShort ushort_val;
01569 CORBA::Long long_val;
01570 CORBA::ULong ulong_val;
01571 CORBA::ULong enum_val;
01572 CORBA::ULongLong ulonglong_val;
01573 CORBA::LongLong longlong_val;
01574 } s = {0, 0, 0, 0, 0, 0, 0, 0, ACE_CDR_LONGLONG_INITIALIZER };
01575
01576
01577 if (disc_kind == CORBA::tk_long
01578 || disc_kind == CORBA::tk_short)
01579 {
01580 ACE_Bounded_Set<CORBA::Long> checker (length);
01581
01582 for (CORBA::ULong i = 0; i < length; ++i)
01583 {
01584 if (i == default_index_slot)
01585 {
01586 continue;
01587 }
01588
01589 switch (disc_kind)
01590 {
01591 case CORBA::tk_long:
01592 members[i].label >>= s.long_val;
01593
01594 if (checker.insert (s.long_val) != 0)
01595 {
01596 return false;
01597 }
01598
01599 break;
01600 case CORBA::tk_short:
01601 members[i].label >>= s.short_val;
01602
01603 if (checker.insert (s.short_val) != 0)
01604 {
01605 return false;
01606 }
01607
01608 break;
01609 default:
01610 break;
01611 }
01612 }
01613 }
01614 else
01615 {
01616 ACE_Bounded_Set<CORBA::ULong> checker (length);
01617
01618 for (CORBA::ULong i = 0; i < length; ++i)
01619 {
01620 if (i == default_index_slot)
01621 {
01622 continue;
01623 }
01624
01625 switch (disc_kind)
01626 {
01627 case CORBA::tk_boolean:
01628 members[i].label >>= CORBA::Any::to_boolean (s.bool_val);
01629
01630 if (checker.insert (s.bool_val) != 0)
01631 {
01632 return false;
01633 }
01634
01635 break;
01636 case CORBA::tk_char:
01637 members[i].label >>= CORBA::Any::to_char (s.char_val);
01638
01639 if (checker.insert (s.char_val) != 0)
01640 {
01641 return false;
01642 }
01643
01644 break;
01645 case CORBA::tk_ushort:
01646 members[i].label >>= s.ushort_val;
01647
01648 if (checker.insert (s.ushort_val) != 0)
01649 {
01650 return false;
01651 }
01652
01653 break;
01654 case CORBA::tk_ulong:
01655 members[i].label >>= s.ulong_val;
01656
01657 if (checker.insert (s.ulong_val) != 0)
01658 {
01659 return false;
01660 }
01661
01662 break;
01663 case CORBA::tk_enum:
01664 {
01665 TAO::Any_Impl *impl = members[i].label.impl ();
01666 TAO_InputCDR for_reading (static_cast<ACE_Message_Block *> (0));
01667
01668 if (impl->encoded ())
01669 {
01670 TAO::Unknown_IDL_Type *unk =
01671 dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
01672
01673 if (!unk)
01674 throw CORBA::INTERNAL ();
01675
01676
01677
01678
01679 for_reading = unk->_tao_get_cdr ();
01680 }
01681 else
01682 {
01683 TAO_OutputCDR out;
01684 impl->marshal_value (out);
01685 TAO_InputCDR tmp (out);
01686 for_reading = tmp;
01687 }
01688
01689 for_reading.read_ulong (s.enum_val);
01690
01691 if (checker.insert (s.enum_val) != 0)
01692 {
01693 return false;
01694 }
01695
01696 break;
01697 }
01698 default:
01699 break;
01700 }
01701 }
01702 }
01703
01704 return true;
01705 }
01706
01707 CORBA::Boolean
01708 TAO_TypeCodeFactory_i::valid_disc_type (CORBA::TypeCode_ptr tc
01709 )
01710 {
01711 CORBA::TCKind const kind = tc->kind ();
01712
01713 return
01714 (kind == CORBA::tk_enum
01715 || kind == CORBA::tk_ulong
01716 || kind == CORBA::tk_long
01717 || kind == CORBA::tk_ushort
01718 || kind == CORBA::tk_short
01719 || kind == CORBA::tk_char
01720 || kind == CORBA::tk_boolean
01721 || kind == CORBA::tk_longlong
01722 || kind == CORBA::tk_ulonglong);
01723 }
01724
01725 bool
01726 TAO_TypeCodeFactory_i::check_recursion (CORBA::TCKind kind,
01727 char const * id,
01728 CORBA::TypeCode_ptr member,
01729 CORBA::TypeCode_ptr & recursive_tc,
01730 char const * working_id)
01731 {
01732 if (kind != CORBA::tk_struct
01733 && kind != CORBA::tk_union
01734 && kind != CORBA::tk_value
01735 && kind != CORBA::tk_event)
01736 return false;
01737
01738 CORBA::TypeCode_var unaliased_member =
01739 TAO::unaliased_typecode (member);
01740
01741 CORBA::TCKind const unaliased_member_kind =
01742 unaliased_member->kind ();
01743
01744
01745
01746
01747 switch (unaliased_member_kind)
01748 {
01749 case CORBA::tk_struct:
01750 case CORBA::tk_union:
01751 case CORBA::tk_value:
01752 case CORBA::tk_event:
01753 {
01754 CORBA::ULong const nfields =
01755 unaliased_member->member_count ();
01756
01757 for (CORBA::ULong i = 0; i < nfields; ++i)
01758 {
01759 CORBA::TypeCode_var member_tc =
01760 unaliased_member->member_type (i);
01761
01762 CORBA::TCKind const member_tc_kind =
01763 member_tc->kind ();
01764
01765 if (member_tc_kind == CORBA::TAO_TC_KIND_COUNT)
01766 {
01767
01768
01769
01770
01771 if (kind == CORBA::tk_value || kind == CORBA::tk_event)
01772 {
01773 char const * member_tc_id =
01774 member_tc->id ();
01775
01776 if (ACE_OS::strcmp (id, member_tc_id) == 0)
01777 {
01778 TAO::TypeCodeFactory::Recursive_TypeCode * const rtc =
01779 dynamic_cast<
01780 TAO::TypeCodeFactory::Recursive_TypeCode *> (
01781 member_tc.in ());
01782
01783 if (!rtc)
01784 {
01785 throw CORBA::INTERNAL ();
01786 }
01787
01788 if (CORBA::is_nil (recursive_tc))
01789 {
01790 recursive_tc = this->make_recursive_tc (kind, id);
01791 }
01792
01793
01794 rtc->the_typecode (recursive_tc);
01795
01796 return true;
01797 }
01798
01799
01800 }
01801 else
01802 {
01803
01804
01805
01806
01807
01808 throw ::CORBA::BAD_TYPECODE ();
01809 }
01810 }
01811 else
01812 {
01813 if (member_tc_kind == CORBA::tk_value
01814 || member_tc_kind == CORBA::tk_event)
01815 {
01816 char const * member_tc_id = member_tc->id ();
01817
01818 if (working_id != 0
01819 && ACE_OS::strcmp (working_id, member_tc_id) == 0)
01820 {
01821
01822
01823
01824 break;
01825 }
01826
01827
01828
01829 working_id = member_tc_id;
01830 }
01831
01832 bool const recursion_detected =
01833 this->check_recursion (kind,
01834 id,
01835 member_tc.in (),
01836 recursive_tc,
01837 working_id);
01838
01839 if (recursion_detected)
01840 {
01841 return true;
01842 }
01843 }
01844
01845
01846
01847 }
01848 }
01849 break;
01850
01851 case CORBA::tk_sequence:
01852 case CORBA::tk_array:
01853 {
01854 CORBA::TypeCode_var content_tc =
01855 unaliased_member->content_type ();
01856
01857 CORBA::TCKind const content_tc_kind =
01858 content_tc->kind ();
01859
01860 char const * content_tc_id = 0;
01861
01862 if (content_tc_kind == CORBA::tk_struct
01863 || content_tc_kind == CORBA::tk_union
01864 || content_tc_kind == CORBA::TAO_TC_KIND_COUNT)
01865 {
01866 content_tc_id = content_tc->id ();
01867 }
01868
01869 if (working_id != 0
01870 && content_tc_id != 0
01871 && ACE_OS::strcmp (working_id, content_tc_id) == 0)
01872 {
01873
01874
01875
01876 break;
01877 }
01878
01879 if (content_tc_kind == CORBA::TAO_TC_KIND_COUNT)
01880 {
01881 if (ACE_OS::strcmp (id, content_tc_id) == 0)
01882 {
01883 TAO::TypeCodeFactory::Recursive_TypeCode * const rtc =
01884 dynamic_cast<TAO::TypeCodeFactory::Recursive_TypeCode *>
01885 (content_tc.in ());
01886
01887 if (!rtc)
01888 {
01889 throw CORBA::INTERNAL ();
01890 }
01891
01892 if (CORBA::is_nil (recursive_tc))
01893 {
01894 recursive_tc = this->make_recursive_tc (kind, id);
01895 }
01896
01897
01898 rtc->the_typecode (recursive_tc);
01899
01900 return true;
01901 }
01902
01903
01904 }
01905
01906 return
01907 this->check_recursion (
01908 kind,
01909 id,
01910 content_tc.in (),
01911 recursive_tc,
01912 content_tc_id != 0 ? content_tc_id : working_id);
01913 }
01914
01915 default:
01916 break;
01917 }
01918
01919 return false;
01920 }
01921
01922 CORBA::TypeCode_ptr
01923 TAO_TypeCodeFactory_i::make_recursive_tc (CORBA::TCKind kind, char const * id)
01924 {
01925 CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr ();
01926
01927 switch (kind)
01928 {
01929 case CORBA::tk_struct:
01930 ACE_NEW_THROW_EX (tc,
01931 TCF::Struct::recursive_typecode_type (kind, id),
01932 CORBA::NO_MEMORY ());
01933 break;
01934
01935 case CORBA::tk_union:
01936 ACE_NEW_THROW_EX (tc,
01937 TCF::Union::recursive_typecode_type (kind, id),
01938 CORBA::NO_MEMORY ());
01939 break;
01940
01941 case CORBA::tk_value:
01942 case CORBA::tk_event:
01943 ACE_NEW_THROW_EX (tc,
01944 TCF::Value::recursive_typecode_type (kind, id),
01945 CORBA::NO_MEMORY ());
01946 break;
01947
01948 default:
01949 throw ::CORBA::INTERNAL ();
01950 }
01951
01952 return tc;
01953 }
01954
01955 TAO_END_VERSIONED_NAMESPACE_DECL