00001
00002
00003 #include "tao/AnyTypeCode/TypeCode_CDR_Extraction.h"
00004
00005 #include "tao/AnyTypeCode/TypeCode_Constants.h"
00006 #include "tao/AnyTypeCode/True_RefCount_Policy.h"
00007
00008 #include "tao/AnyTypeCode/Alias_TypeCode.h"
00009 #include "tao/AnyTypeCode/Enum_TypeCode.h"
00010 #include "tao/AnyTypeCode/TypeCode_Case_Enum_T.h"
00011 #include "tao/AnyTypeCode/Fixed_TypeCode.h"
00012 #include "tao/AnyTypeCode/Objref_TypeCode.h"
00013 #include "tao/AnyTypeCode/Sequence_TypeCode.h"
00014 #include "tao/AnyTypeCode/String_TypeCode.h"
00015 #include "tao/AnyTypeCode/Struct_TypeCode.h"
00016 #include "tao/AnyTypeCode/Union_TypeCode.h"
00017 #include "tao/AnyTypeCode/Value_TypeCode.h"
00018 #include "tao/AnyTypeCode/Any.h"
00019
00020 #include "tao/AnyTypeCode/Recursive_Type_TypeCode.h"
00021
00022 #include "tao/AnyTypeCode/TypeCode_Case_T.h"
00023 #include "tao/AnyTypeCode/TypeCode_Struct_Field.h"
00024 #include "tao/AnyTypeCode/TypeCode_Value_Field.h"
00025
00026 #include "tao/CDR.h"
00027
00028 #include "ace/Array_Base.h"
00029 #include "ace/Value_Ptr.h"
00030
00031
00032 ACE_RCSID (AnyTypeCode,
00033 TypeCode_CDR_Extraction,
00034 "$Id: TypeCode_CDR_Extraction.cpp 84293 2009-02-02 09:16:35Z sma $")
00035
00036 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00037
00038 namespace TAO
00039 {
00040 namespace TypeCodeFactory
00041 {
00042
00043
00044
00045
00046
00047
00048
00049 struct TC_Info
00050 {
00051
00052 TC_Info (void) : id (0), type () {}
00053
00054
00055 char const * id;
00056
00057
00058 CORBA::TypeCode_ptr type;
00059 };
00060
00061 typedef ACE_Array_Base<TC_Info> TC_Info_List;
00062 }
00063 }
00064
00065 namespace
00066 {
00067 bool add_to_recursion_list (CORBA::TypeCode_ptr & tc,
00068 TAO::TypeCodeFactory::TC_Info_List & infos)
00069 {
00070
00071 size_t const old_size = infos.size ();
00072 if (infos.size (old_size + 1) == -1)
00073 {
00074
00075 return false;
00076 }
00077
00078 TAO::TypeCodeFactory::TC_Info & info = infos [old_size];
00079
00080 try
00081 {
00082
00083 info.id = tc->id ();
00084 info.type = tc;
00085 }
00086 catch (...)
00087 {
00088 infos.size (old_size);
00089 return false;
00090 }
00091 return true;
00092 }
00093
00094 bool start_cdr_encap_extraction (TAO_InputCDR & cdr)
00095 {
00096 CORBA::Boolean byte_order;
00097
00098
00099
00100
00101
00102
00103 if (!(cdr.skip_ulong ()
00104 && cdr >> TAO_InputCDR::to_boolean (byte_order)))
00105 return false;
00106
00107 cdr.reset_byte_order (byte_order);
00108
00109 return true;
00110 }
00111
00112 class TAO_InputCDRByteOrderGuard
00113 {
00114 TAO_InputCDR &cdr_;
00115 CORBA::Boolean byte_order_;
00116 public:
00117 TAO_InputCDRByteOrderGuard (TAO_InputCDR & cdr):
00118 cdr_ (cdr),
00119 byte_order_ (cdr.byte_order ()) {}
00120 ~TAO_InputCDRByteOrderGuard ()
00121 {
00122 cdr_.reset_byte_order (byte_order_);
00123 }
00124 };
00125
00126
00127
00128 CORBA::ULong const TYPECODE_INDIRECTION = 0xffffffffU;
00129
00130
00131
00132
00133
00134 typedef ACE::Value_Ptr<TAO::TypeCode::Case<CORBA::String_var, CORBA::TypeCode_var> > union_elem_type;
00135 typedef ACE_Array_Base<union_elem_type> union_case_array_type;
00136
00137
00138
00139
00140 bool tc_demarshal (TAO_InputCDR & cdr,
00141 CORBA::TypeCode_ptr & tc,
00142 TAO::TypeCodeFactory::TC_Info_List & infos);
00143
00144
00145 bool tc_demarshal_indirection (TAO_InputCDR & cdr,
00146 CORBA::TypeCode_ptr & tc,
00147 TAO::TypeCodeFactory::TC_Info_List & infos);
00148
00149 bool find_recursive_tc (char const * id,
00150 TAO::TypeCodeFactory::TC_Info_List & tcs,
00151 TAO::TypeCodeFactory::TC_Info_List & infos)
00152 {
00153
00154
00155
00156 size_t const len = infos.size ();
00157
00158 for (size_t i = 0; i < len; ++i)
00159 {
00160 TAO::TypeCodeFactory::TC_Info & info = infos[i];
00161
00162 if (ACE_OS::strcmp (info.id, id) == 0)
00163 {
00164
00165
00166 size_t const old_size = tcs.size ();
00167 if (tcs.size (old_size + 1) == -1)
00168 return false;
00169
00170 TAO::TypeCodeFactory::TC_Info & new_info = tcs[old_size];
00171 new_info.type = info.type;
00172 }
00173 }
00174
00175 return (tcs.size () > 0) ;
00176 }
00177 }
00178
00179 bool
00180 TAO::TypeCodeFactory::tc_null_factory (CORBA::TCKind,
00181 TAO_InputCDR &,
00182 CORBA::TypeCode_ptr & tc,
00183 TC_Info_List &)
00184 {
00185 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_null);
00186
00187 return true;
00188 }
00189
00190 bool
00191 TAO::TypeCodeFactory::tc_void_factory (CORBA::TCKind,
00192 TAO_InputCDR &,
00193 CORBA::TypeCode_ptr & tc,
00194 TC_Info_List &)
00195 {
00196 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_void);
00197
00198 return true;
00199 }
00200
00201 bool
00202 TAO::TypeCodeFactory::tc_short_factory (CORBA::TCKind,
00203 TAO_InputCDR &,
00204 CORBA::TypeCode_ptr & tc,
00205 TC_Info_List &)
00206 {
00207 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_short);
00208
00209 return true;
00210 }
00211
00212 bool
00213 TAO::TypeCodeFactory::tc_long_factory (CORBA::TCKind,
00214 TAO_InputCDR &,
00215 CORBA::TypeCode_ptr & tc,
00216 TC_Info_List &)
00217 {
00218 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_long);
00219
00220 return true;
00221 }
00222
00223 bool
00224 TAO::TypeCodeFactory::tc_ushort_factory (CORBA::TCKind,
00225 TAO_InputCDR &,
00226 CORBA::TypeCode_ptr & tc,
00227 TC_Info_List &)
00228 {
00229 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_ushort);
00230
00231 return true;
00232 }
00233
00234 bool
00235 TAO::TypeCodeFactory::tc_ulong_factory (CORBA::TCKind,
00236 TAO_InputCDR &,
00237 CORBA::TypeCode_ptr & tc,
00238 TC_Info_List &)
00239 {
00240 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_ulong);
00241
00242 return true;
00243 }
00244
00245 bool
00246 TAO::TypeCodeFactory::tc_float_factory (CORBA::TCKind,
00247 TAO_InputCDR &,
00248 CORBA::TypeCode_ptr & tc,
00249 TC_Info_List &)
00250 {
00251 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_float);
00252
00253 return true;
00254 }
00255
00256 bool
00257 TAO::TypeCodeFactory::tc_double_factory (CORBA::TCKind,
00258 TAO_InputCDR &,
00259 CORBA::TypeCode_ptr & tc,
00260 TC_Info_List &)
00261 {
00262 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_double);
00263
00264 return true;
00265 }
00266
00267 bool
00268 TAO::TypeCodeFactory::tc_boolean_factory (CORBA::TCKind,
00269 TAO_InputCDR &,
00270 CORBA::TypeCode_ptr & tc,
00271 TC_Info_List &)
00272 {
00273 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_boolean);
00274
00275 return true;
00276 }
00277
00278 bool
00279 TAO::TypeCodeFactory::tc_char_factory (CORBA::TCKind,
00280 TAO_InputCDR &,
00281 CORBA::TypeCode_ptr & tc,
00282 TC_Info_List &)
00283 {
00284 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_char);
00285
00286 return true;
00287 }
00288
00289 bool
00290 TAO::TypeCodeFactory::tc_octet_factory (CORBA::TCKind,
00291 TAO_InputCDR &,
00292 CORBA::TypeCode_ptr & tc,
00293 TC_Info_List &)
00294 {
00295 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_octet);
00296
00297 return true;
00298 }
00299
00300 bool
00301 TAO::TypeCodeFactory::tc_any_factory (CORBA::TCKind,
00302 TAO_InputCDR &,
00303 CORBA::TypeCode_ptr & tc,
00304 TC_Info_List &)
00305 {
00306 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_any);
00307
00308 return true;
00309 }
00310
00311 bool
00312 TAO::TypeCodeFactory::tc_TypeCode_factory (CORBA::TCKind,
00313 TAO_InputCDR &,
00314 CORBA::TypeCode_ptr & tc,
00315 TC_Info_List &)
00316 {
00317 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_TypeCode);
00318
00319 return true;
00320 }
00321
00322 bool
00323 TAO::TypeCodeFactory::tc_Principal_factory (CORBA::TCKind,
00324 TAO_InputCDR &,
00325 CORBA::TypeCode_ptr & tc,
00326 TC_Info_List &)
00327 {
00328 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_Principal);
00329
00330 return true;
00331 }
00332
00333 bool
00334 TAO::TypeCodeFactory::tc_objref_factory (CORBA::TCKind kind,
00335 TAO_InputCDR & cdr,
00336 CORBA::TypeCode_ptr & tc,
00337 TC_Info_List &)
00338 {
00339
00340
00341 TAO_InputCDRByteOrderGuard boguard (cdr);
00342 if (!start_cdr_encap_extraction (cdr))
00343 return false;
00344
00345
00346 CORBA::String_var id;
00347 if (!(cdr >> TAO_InputCDR::to_string (id.out (), 0)))
00348 return false;
00349
00350 static char const Object_id[] = "IDL:omg.org/CORBA/Object:1.0";
00351 static char const CCMObject_id[] = "IDL:omg.org/CORBA/CCMObject:1.0";
00352 static char const CCMHome_id[] = "IDL:omg.org/CORBA/CCMHome:1.0";
00353
00354 char const * tc_constant_id = "";
00355
00356 switch (kind)
00357 {
00358 case CORBA::tk_component:
00359 tc_constant_id = CCMObject_id;
00360 break;
00361 case CORBA::tk_home:
00362 tc_constant_id = CCMHome_id;
00363 break;
00364 case CORBA::tk_objref:
00365 tc_constant_id = Object_id;
00366 break;
00367 default:
00368 break;
00369 }
00370
00371 if (ACE_OS::strcmp (id.in (),
00372 tc_constant_id) == 0)
00373 {
00374 if (!cdr.skip_string ())
00375 return false;
00376
00377 CORBA::TypeCode_ptr tc_constant = CORBA::TypeCode::_nil ();
00378 switch (kind)
00379 {
00380 case CORBA::tk_component:
00381 tc_constant = CORBA::_tc_Component;
00382 break;
00383 case CORBA::tk_home:
00384 tc_constant = CORBA::_tc_Home;
00385 break;
00386 case CORBA::tk_objref:
00387 tc_constant = CORBA::_tc_Object;
00388 break;
00389 default:
00390 break;
00391 }
00392
00393
00394
00395 tc =
00396 CORBA::TypeCode::_duplicate (tc_constant);
00397 }
00398 else
00399 {
00400 CORBA::String_var name;
00401
00402 if (!(cdr >> TAO_InputCDR::to_string (name.out (), 0)))
00403 return false;
00404
00405 typedef TAO::TypeCode::Objref<CORBA::String_var,
00406 TAO::True_RefCount_Policy> typecode_type;
00407
00408 ACE_NEW_RETURN (tc,
00409 typecode_type (kind,
00410 id.in (),
00411 name.in ()),
00412 false);
00413 }
00414
00415 return true;
00416 }
00417
00418 bool
00419 TAO::TypeCodeFactory::tc_struct_factory (CORBA::TCKind kind,
00420 TAO_InputCDR & cdr,
00421 CORBA::TypeCode_ptr & tc,
00422 TC_Info_List & infos)
00423 {
00424 ACE_ASSERT (kind == CORBA::tk_struct || kind == CORBA::tk_except);
00425
00426
00427
00428 TAO_InputCDRByteOrderGuard boguard (cdr);
00429 if (!start_cdr_encap_extraction (cdr))
00430 return false;
00431
00432
00433 CORBA::String_var id, name;
00434 CORBA::ULong nfields;
00435
00436 if (!(cdr >> TAO_InputCDR::to_string (id.out (), 0)
00437 && cdr >> TAO_InputCDR::to_string (name.out (), 0)
00438 && cdr >> nfields))
00439 return false;
00440
00441 typedef ACE_Array_Base<TAO::TypeCode::Struct_Field<CORBA::String_var,
00442 CORBA::TypeCode_var> >
00443 member_array_type;
00444
00445 member_array_type fields (nfields);
00446
00447 for (CORBA::ULong i = 0; i < nfields; ++i)
00448 {
00449 if (!(cdr >> TAO_InputCDR::to_string (fields[i].name.out (), 0)
00450 && tc_demarshal (cdr, fields[i].type.out (), infos)))
00451 return false;
00452 }
00453
00454 typedef TAO::TypeCode::Struct<
00455 CORBA::String_var,
00456 CORBA::TypeCode_var,
00457 member_array_type,
00458 TAO::True_RefCount_Policy> typecode_type;
00459
00460
00461 TAO::TypeCodeFactory::TC_Info_List recursive_tc;
00462 if (kind == CORBA::tk_struct && find_recursive_tc (id.in (), recursive_tc, infos))
00463 {
00464
00465 typedef TAO::TypeCode::Recursive_Type<typecode_type,
00466 CORBA::TypeCode_var,
00467 member_array_type>
00468 recursive_typecode_type;
00469
00470 size_t const len = recursive_tc.size ();
00471
00472 bool assigned_params = false;
00473 for (size_t i = 0; i < len; ++i)
00474 {
00475 TAO::TypeCodeFactory::TC_Info & info = recursive_tc[i];
00476
00477 recursive_typecode_type * const rtc =
00478 dynamic_cast<recursive_typecode_type *> (info.type);
00479
00480 if (!rtc)
00481 return false;
00482
00483 assigned_params |= rtc->struct_parameters (name.in (), fields, nfields);
00484 }
00485
00486
00487
00488
00489 if ( !assigned_params)
00490 {
00491 tc = CORBA::TypeCode::_duplicate(recursive_tc[0].type);
00492 }
00493 else
00494 {
00495 tc = recursive_tc[0].type;
00496 }
00497 }
00498 else
00499 {
00500 ACE_NEW_RETURN (tc,
00501 typecode_type (kind,
00502 id.in (),
00503 name.in (),
00504 fields,
00505 nfields),
00506 false);
00507 }
00508
00509 return true;
00510 }
00511
00512 bool
00513 TAO::TypeCodeFactory::tc_union_factory (CORBA::TCKind ,
00514 TAO_InputCDR & cdr,
00515 CORBA::TypeCode_ptr & tc,
00516 TC_Info_List & infos)
00517 {
00518
00519
00520
00521 TAO_InputCDRByteOrderGuard boguard (cdr);
00522 if (!start_cdr_encap_extraction (cdr))
00523 return false;
00524
00525
00526
00527 CORBA::String_var id, name;
00528 CORBA::TypeCode_var discriminant_type;
00529 CORBA::Long default_index = -1;
00530 CORBA::ULong ncases = 0;
00531
00532 if (!(cdr >> TAO_InputCDR::to_string (id.out (), 0)
00533 && cdr >> TAO_InputCDR::to_string (name.out (), 0)
00534 && cdr >> discriminant_type.out ()))
00535 return false;
00536
00537 CORBA::TCKind const discriminant_kind =
00538 discriminant_type->kind ();
00539
00540
00541 if (!(discriminant_kind == CORBA::tk_enum
00542 || discriminant_kind == CORBA::tk_ulong
00543 || discriminant_kind == CORBA::tk_long
00544 || discriminant_kind == CORBA::tk_ushort
00545 || discriminant_kind == CORBA::tk_short
00546 || discriminant_kind == CORBA::tk_char
00547 || discriminant_kind == CORBA::tk_boolean
00548 || discriminant_kind == CORBA::tk_longlong
00549 || discriminant_kind == CORBA::tk_ulonglong))
00550 return false;
00551
00552 if (!(cdr >> default_index
00553 && default_index >= -1
00554 && cdr >> ncases))
00555 return false;
00556
00557 typedef union_elem_type elem_type;
00558 typedef union_case_array_type case_array_type;
00559
00560 case_array_type cases (ncases);
00561
00562 for (CORBA::ULong i = 0; i < ncases; ++i)
00563 {
00564 elem_type & member = cases[i];
00565
00566 TAO::TypeCode::Case<CORBA::String_var, CORBA::TypeCode_var> * the_case = 0;
00567
00568
00569 switch (discriminant_kind)
00570 {
00571 case CORBA::tk_enum:
00572 {
00573 CORBA::ULong label;
00574 if (!(cdr >> label))
00575 return false;
00576
00577 typedef TypeCode::Case_Enum_T<CORBA::String_var,
00578 CORBA::TypeCode_var> case_type;
00579
00580 ACE_NEW_RETURN (the_case,
00581 case_type (discriminant_type.in(), label),
00582 false);
00583 }
00584 break;
00585 case CORBA::tk_ulong:
00586 {
00587 CORBA::ULong label;
00588 if (!(cdr >> label))
00589 return false;
00590
00591 typedef TypeCode::Case_T<CORBA::ULong,
00592 CORBA::String_var,
00593 CORBA::TypeCode_var> case_type;
00594
00595 ACE_NEW_RETURN (the_case,
00596 case_type (label),
00597 false);
00598 }
00599 break;
00600 case CORBA::tk_long:
00601 {
00602 CORBA::Long label;
00603 if (!(cdr >> label))
00604 return false;
00605
00606 typedef TypeCode::Case_T<CORBA::Long,
00607 CORBA::String_var,
00608 CORBA::TypeCode_var> case_type;
00609
00610 ACE_NEW_RETURN (the_case,
00611 case_type (label),
00612 false);
00613 }
00614 break;
00615 case CORBA::tk_ushort:
00616 {
00617 CORBA::UShort label;
00618 if (!(cdr >> label))
00619 return false;
00620
00621 typedef TypeCode::Case_T<CORBA::UShort,
00622 CORBA::String_var,
00623 CORBA::TypeCode_var> case_type;
00624
00625 ACE_NEW_RETURN (the_case,
00626 case_type (label),
00627 false);
00628 }
00629 break;
00630 case CORBA::tk_short:
00631 {
00632 CORBA::Short label;
00633 if (!(cdr >> label))
00634 return false;
00635
00636 typedef TypeCode::Case_T<CORBA::Short,
00637 CORBA::String_var,
00638 CORBA::TypeCode_var> case_type;
00639
00640 ACE_NEW_RETURN (the_case,
00641 case_type (label),
00642 false);
00643 }
00644 break;
00645 case CORBA::tk_char:
00646 {
00647 CORBA::Char label;
00648 if (!(cdr >> CORBA::Any::to_char (label)))
00649 return false;
00650
00651 typedef TypeCode::Case_T<CORBA::Char,
00652 CORBA::String_var,
00653 CORBA::TypeCode_var> case_type;
00654
00655 ACE_NEW_RETURN (the_case,
00656 case_type (label),
00657 false);
00658 }
00659 break;
00660 case CORBA::tk_boolean:
00661 {
00662 CORBA::Boolean label;
00663 if (!(cdr >> CORBA::Any::to_boolean (label)))
00664 return false;
00665
00666 typedef TypeCode::Case_T<CORBA::Boolean,
00667 CORBA::String_var,
00668 CORBA::TypeCode_var> case_type;
00669
00670 ACE_NEW_RETURN (the_case,
00671 case_type (label),
00672 false);
00673 }
00674 break;
00675 case CORBA::tk_longlong:
00676 {
00677 CORBA::LongLong label;
00678 if (!(cdr >> label))
00679 return false;
00680
00681 typedef TypeCode::Case_T<CORBA::LongLong,
00682 CORBA::String_var,
00683 CORBA::TypeCode_var> case_type;
00684
00685 ACE_NEW_RETURN (the_case,
00686 case_type (label),
00687 false);
00688 }
00689 break;
00690 #if !defined (ACE_LACKS_LONGLONG_T)
00691 case CORBA::tk_ulonglong:
00692 {
00693 CORBA::ULongLong label;
00694 if (!(cdr >> label))
00695 return false;
00696
00697 typedef TypeCode::Case_T<CORBA::ULongLong,
00698 CORBA::String_var,
00699 CORBA::TypeCode_var> case_type;
00700
00701 ACE_NEW_RETURN (the_case,
00702 case_type (label),
00703 false);
00704 }
00705 break;
00706 #endif
00707 default:
00708 return false;
00709 }
00710
00711 elem_type case_value (the_case);
00712 member.swap (case_value);
00713
00714 CORBA::String_var the_name;
00715 CORBA::TypeCode_var the_type;
00716
00717 if (!(cdr >> TAO_InputCDR::to_string (the_name.out (), 0)
00718 && tc_demarshal (cdr, the_type.out (), infos)))
00719 return false;
00720
00721 member->name (the_name.in ());
00722 member->type (the_type.in ());
00723 }
00724
00725 typedef TAO::TypeCode::Union<CORBA::String_var,
00726 CORBA::TypeCode_var,
00727 case_array_type,
00728 TAO::True_RefCount_Policy> typecode_type;
00729
00730
00731 TAO::TypeCodeFactory::TC_Info_List recursive_tc;
00732 if (find_recursive_tc (id.in (), recursive_tc, infos))
00733 {
00734
00735
00736 typedef TAO::TypeCode::Recursive_Type<typecode_type,
00737 CORBA::TypeCode_var,
00738 case_array_type>
00739 recursive_typecode_type;
00740
00741 size_t const len = recursive_tc.size ();
00742
00743 bool assigned_params = false;
00744 for (size_t i = 0; i < len; ++i)
00745 {
00746 TAO::TypeCodeFactory::TC_Info & info = recursive_tc[i];
00747
00748 recursive_typecode_type * const rtc =
00749 dynamic_cast<recursive_typecode_type *> (info.type);
00750
00751 if (!rtc)
00752 return false;
00753
00754 assigned_params |= rtc->union_parameters (name.in (),
00755 discriminant_type,
00756 cases,
00757 ncases,
00758 default_index);
00759
00760 }
00761
00762
00763
00764
00765 if ( !assigned_params)
00766 {
00767 tc = CORBA::TypeCode::_duplicate(recursive_tc[0].type);
00768 }
00769 else
00770 {
00771 tc = recursive_tc[0].type;
00772 }
00773 }
00774 else
00775 {
00776 ACE_NEW_RETURN (tc,
00777 typecode_type (id.in (),
00778 name.in (),
00779 discriminant_type,
00780 cases,
00781 ncases,
00782 default_index),
00783 false);
00784 }
00785
00786 return true;
00787 }
00788
00789 bool
00790 TAO::TypeCodeFactory::tc_enum_factory (CORBA::TCKind ,
00791 TAO_InputCDR & cdr,
00792 CORBA::TypeCode_ptr & tc,
00793 TC_Info_List &)
00794 {
00795
00796
00797 TAO_InputCDRByteOrderGuard boguard (cdr);
00798 if (!start_cdr_encap_extraction (cdr))
00799 return false;
00800
00801
00802 CORBA::String_var id, name;
00803 CORBA::ULong nenumerators;
00804
00805 if (!(cdr >> TAO_InputCDR::to_string (id.out (), 0)
00806 && cdr >> TAO_InputCDR::to_string (name.out (), 0)
00807 && cdr >> nenumerators))
00808 return false;
00809
00810 ACE_Array_Base<CORBA::String_var> enumerators (nenumerators);
00811
00812 for (CORBA::ULong i = 0; i < nenumerators; ++i)
00813 {
00814 if (!(cdr >> TAO_InputCDR::to_string (enumerators[i].out (), 0)))
00815 return false;
00816 }
00817
00818 typedef TAO::TypeCode::Enum<
00819 CORBA::String_var,
00820 ACE_Array_Base<CORBA::String_var>,
00821 TAO::True_RefCount_Policy> typecode_type;
00822
00823 ACE_NEW_RETURN (tc,
00824 typecode_type (id.in (),
00825 name.in (),
00826 enumerators,
00827 nenumerators),
00828 false);
00829
00830 return true;
00831 }
00832
00833 bool
00834 TAO::TypeCodeFactory::tc_string_factory (CORBA::TCKind kind,
00835 TAO_InputCDR & cdr,
00836 CORBA::TypeCode_ptr & tc,
00837 TC_Info_List &)
00838 {
00839
00840
00841
00842 CORBA::ULong bound;
00843 if (!(cdr >> bound))
00844 return false;
00845
00846 if (bound == 0)
00847 {
00848
00849 if (kind == CORBA::tk_string)
00850 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_string);
00851 else if (kind == CORBA::tk_wstring)
00852 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_wstring);
00853 else
00854 return false;
00855
00856 return true;
00857 }
00858
00859 typedef TAO::TypeCode::String<TAO::True_RefCount_Policy> typecode_type;
00860
00861 ACE_NEW_RETURN (tc,
00862 typecode_type (kind, bound),
00863 false);
00864
00865 return true;
00866 }
00867
00868 bool
00869 TAO::TypeCodeFactory::tc_sequence_factory (CORBA::TCKind kind,
00870 TAO_InputCDR & cdr,
00871 CORBA::TypeCode_ptr & tc,
00872 TC_Info_List & infos)
00873 {
00874 ACE_ASSERT (kind == CORBA::tk_sequence || kind == CORBA::tk_array);
00875
00876
00877
00878 TAO_InputCDRByteOrderGuard boguard (cdr);
00879 if (!start_cdr_encap_extraction (cdr))
00880 return false;
00881
00882
00883 CORBA::TypeCode_var content_type;
00884 CORBA::ULong length;
00885
00886 if (!(tc_demarshal (cdr, content_type.out (), infos)
00887 && cdr >> length))
00888 return false;
00889
00890 typedef TAO::TypeCode::Sequence<
00891 CORBA::TypeCode_var,
00892 TAO::True_RefCount_Policy> typecode_type;
00893
00894 ACE_NEW_RETURN (tc,
00895 typecode_type (kind, content_type, length),
00896 false);
00897
00898 return true;
00899 }
00900
00901 bool
00902 TAO::TypeCodeFactory::tc_array_factory (CORBA::TCKind kind,
00903 TAO_InputCDR & cdr,
00904 CORBA::TypeCode_ptr & tc,
00905 TC_Info_List & infos)
00906 {
00907 return tc_sequence_factory (kind, cdr, tc, infos);
00908 }
00909
00910 bool
00911 TAO::TypeCodeFactory::tc_alias_factory (CORBA::TCKind kind,
00912 TAO_InputCDR & cdr,
00913 CORBA::TypeCode_ptr & tc,
00914 TC_Info_List & infos)
00915 {
00916
00917
00918 TAO_InputCDRByteOrderGuard boguard (cdr);
00919 if (!start_cdr_encap_extraction (cdr))
00920 return false;
00921
00922
00923 CORBA::String_var id, name;
00924 CORBA::TypeCode_var content_type;
00925 if (!(cdr >> TAO_InputCDR::to_string (id.out (), 0)
00926 && cdr >> TAO_InputCDR::to_string (name.out (), 0)
00927 && tc_demarshal (cdr, content_type.out (), infos)))
00928 {
00929 return false;
00930 }
00931
00932 typedef TAO::TypeCode::Alias<
00933 CORBA::String_var,
00934 CORBA::TypeCode_var,
00935 TAO::True_RefCount_Policy> typecode_type;
00936
00937 ACE_NEW_RETURN (tc,
00938 typecode_type (kind,
00939 id.in (),
00940 name.in (),
00941 content_type),
00942 false);
00943 return true;
00944 }
00945
00946 bool
00947 TAO::TypeCodeFactory::tc_except_factory (CORBA::TCKind kind,
00948 TAO_InputCDR & cdr,
00949 CORBA::TypeCode_ptr & tc,
00950 TC_Info_List & infos)
00951 {
00952 return tc_struct_factory (kind, cdr, tc, infos);
00953 }
00954
00955 bool
00956 TAO::TypeCodeFactory::tc_longlong_factory (CORBA::TCKind,
00957 TAO_InputCDR &,
00958 CORBA::TypeCode_ptr & tc,
00959 TC_Info_List &)
00960 {
00961 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_longlong);
00962
00963 return true;
00964 }
00965
00966 bool
00967 TAO::TypeCodeFactory::tc_ulonglong_factory (CORBA::TCKind,
00968 TAO_InputCDR &,
00969 CORBA::TypeCode_ptr & tc,
00970 TC_Info_List &)
00971 {
00972 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_ulonglong);
00973
00974 return true;
00975 }
00976
00977 bool
00978 TAO::TypeCodeFactory::tc_longdouble_factory (CORBA::TCKind,
00979 TAO_InputCDR &,
00980 CORBA::TypeCode_ptr & tc,
00981 TC_Info_List &)
00982 {
00983 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_longdouble);
00984
00985 return true;
00986 }
00987
00988 bool
00989 TAO::TypeCodeFactory::tc_wchar_factory (CORBA::TCKind,
00990 TAO_InputCDR &,
00991 CORBA::TypeCode_ptr & tc,
00992 TC_Info_List &)
00993 {
00994 tc = CORBA::TypeCode::_duplicate (CORBA::_tc_wchar);
00995
00996 return true;
00997 }
00998
00999 bool
01000 TAO::TypeCodeFactory::tc_wstring_factory (CORBA::TCKind kind,
01001 TAO_InputCDR & cdr,
01002 CORBA::TypeCode_ptr & tc,
01003 TC_Info_List & infos)
01004 {
01005 return tc_string_factory (kind, cdr, tc, infos);
01006 }
01007
01008 bool
01009 TAO::TypeCodeFactory::tc_fixed_factory (CORBA::TCKind,
01010 TAO_InputCDR & cdr,
01011 CORBA::TypeCode_ptr & tc,
01012 TC_Info_List &)
01013 {
01014
01015
01016
01017 CORBA::UShort digits, scale;
01018 if (!(cdr >> digits && cdr >> scale))
01019 return false;
01020
01021 typedef TAO::TypeCode::Fixed<TAO::True_RefCount_Policy> typecode_type;
01022
01023 ACE_NEW_RETURN (tc,
01024 typecode_type (digits, scale),
01025 false);
01026
01027 return true;
01028 }
01029
01030 bool
01031 TAO::TypeCodeFactory::tc_value_factory (CORBA::TCKind kind,
01032 TAO_InputCDR & cdr,
01033 CORBA::TypeCode_ptr & tc,
01034 TC_Info_List & infos)
01035 {
01036
01037
01038 TAO_InputCDRByteOrderGuard boguard (cdr);
01039 if (!start_cdr_encap_extraction (cdr))
01040 return false;
01041
01042
01043 CORBA::String_var id;
01044 if (!(cdr >> TAO_InputCDR::to_string (id.out (), 0)))
01045 return false;
01046
01047 CORBA::String_var name;
01048 CORBA::ValueModifier type_modifier;
01049 CORBA::TypeCode_var concrete_base;
01050 CORBA::ULong nfields;
01051
01052 if (!(cdr >> TAO_InputCDR::to_string (name.out (), 0)
01053 && cdr >> type_modifier
01054 && cdr >> concrete_base.out ()
01055 && cdr >> nfields))
01056 return false;
01057
01058 typedef ACE_Array_Base<TAO::TypeCode::Value_Field<CORBA::String_var,
01059 CORBA::TypeCode_var> >
01060 member_array_type;
01061
01062 member_array_type fields (nfields);
01063
01064 for (CORBA::ULong i = 0; i < nfields; ++i)
01065 {
01066 TAO::TypeCode::Value_Field<CORBA::String_var,
01067 CORBA::TypeCode_var> & field = fields[i];
01068
01069 if (!(cdr >> TAO_InputCDR::to_string (field.name.out (), 0)
01070 && tc_demarshal (cdr, field.type.out (), infos)
01071 && cdr >> field.visibility))
01072 return false;
01073 }
01074
01075 typedef TAO::TypeCode::Value<
01076 CORBA::String_var,
01077 CORBA::TypeCode_var,
01078 member_array_type,
01079 TAO::True_RefCount_Policy> typecode_type;
01080
01081
01082 TAO::TypeCodeFactory::TC_Info_List recursive_tc;
01083 if (find_recursive_tc (id.in (), recursive_tc, infos))
01084 {
01085
01086
01087 typedef TAO::TypeCode::Recursive_Type<typecode_type,
01088 CORBA::TypeCode_var,
01089 member_array_type>
01090 recursive_typecode_type;
01091
01092 size_t const len = recursive_tc.size ();
01093 bool assigned_params = false;
01094
01095 for (size_t i = 0; i < len; ++i)
01096 {
01097 TAO::TypeCodeFactory::TC_Info & info = recursive_tc[i];
01098
01099 recursive_typecode_type * const rtc =
01100 dynamic_cast<recursive_typecode_type *> (info.type);
01101
01102 if (!rtc)
01103 return false;
01104
01105 assigned_params |= rtc->valuetype_parameters (name.in (),
01106 type_modifier,
01107 concrete_base,
01108 fields,
01109 nfields);
01110 }
01111
01112
01113
01114 if ( !assigned_params)
01115 {
01116 tc = CORBA::TypeCode::_duplicate(recursive_tc[0].type);
01117 }
01118 else
01119 {
01120 tc = recursive_tc[0].type;
01121 }
01122 }
01123 else
01124 {
01125 ACE_NEW_RETURN (tc,
01126 typecode_type (kind,
01127 id.in (),
01128 name.in (),
01129 type_modifier,
01130 concrete_base,
01131 fields,
01132 nfields),
01133 false);
01134 }
01135
01136 return true;
01137 }
01138
01139 bool
01140 TAO::TypeCodeFactory::tc_value_box_factory (CORBA::TCKind kind,
01141 TAO_InputCDR & cdr,
01142 CORBA::TypeCode_ptr & tc,
01143 TC_Info_List & infos)
01144 {
01145 return tc_alias_factory (kind, cdr, tc, infos);
01146 }
01147
01148 bool
01149 TAO::TypeCodeFactory::tc_native_factory (CORBA::TCKind,
01150 TAO_InputCDR & cdr,
01151 CORBA::TypeCode_ptr & tc,
01152 TC_Info_List & infos)
01153 {
01154 return tc_objref_factory (CORBA::tk_native, cdr, tc, infos);
01155 }
01156
01157 bool
01158 TAO::TypeCodeFactory::tc_abstract_interface_factory (CORBA::TCKind,
01159 TAO_InputCDR & cdr,
01160 CORBA::TypeCode_ptr & tc,
01161 TC_Info_List & infos)
01162 {
01163 return tc_objref_factory (CORBA::tk_abstract_interface, cdr, tc, infos);
01164 }
01165
01166 bool
01167 TAO::TypeCodeFactory::tc_local_interface_factory (CORBA::TCKind,
01168 TAO_InputCDR & cdr,
01169 CORBA::TypeCode_ptr & tc,
01170 TC_Info_List & infos)
01171 {
01172 return tc_objref_factory (CORBA::tk_local_interface, cdr, tc, infos);
01173 }
01174
01175 bool
01176 TAO::TypeCodeFactory::tc_component_factory (CORBA::TCKind,
01177 TAO_InputCDR & cdr,
01178 CORBA::TypeCode_ptr & tc,
01179 TC_Info_List & infos)
01180 {
01181 return tc_objref_factory (CORBA::tk_component, cdr, tc, infos);
01182 }
01183
01184 bool
01185 TAO::TypeCodeFactory::tc_home_factory (CORBA::TCKind,
01186 TAO_InputCDR & cdr,
01187 CORBA::TypeCode_ptr & tc,
01188 TC_Info_List & infos)
01189 {
01190 return tc_objref_factory (CORBA::tk_home, cdr, tc, infos);
01191 }
01192
01193 bool
01194 TAO::TypeCodeFactory::tc_event_factory (CORBA::TCKind kind,
01195 TAO_InputCDR & cdr,
01196 CORBA::TypeCode_ptr & tc,
01197 TC_Info_List & infos)
01198 {
01199 return tc_value_factory (kind, cdr, tc, infos);
01200 }
01201
01202
01203
01204 namespace
01205 {
01206 bool
01207 tc_demarshal (TAO_InputCDR & cdr,
01208 CORBA::TypeCode_ptr & tc,
01209 TAO::TypeCodeFactory::TC_Info_List & infos)
01210 {
01211
01212
01213 CORBA::ULong kind;
01214 if (!(cdr >> kind)
01215 || (kind >= static_cast<CORBA::ULong> (CORBA::TAO_TC_KIND_COUNT)
01216 && kind != TYPECODE_INDIRECTION))
01217 return false;
01218
01219 if (kind == TYPECODE_INDIRECTION)
01220 return tc_demarshal_indirection (cdr, tc, infos);
01221
01222 using namespace TAO::TypeCodeFactory;
01223
01224 static factory const factory_map[] =
01225 {
01226 tc_null_factory,
01227 tc_void_factory,
01228 tc_short_factory,
01229 tc_long_factory,
01230 tc_ushort_factory,
01231 tc_ulong_factory,
01232 tc_float_factory,
01233 tc_double_factory,
01234 tc_boolean_factory,
01235 tc_char_factory,
01236 tc_octet_factory,
01237 tc_any_factory,
01238 tc_TypeCode_factory,
01239 tc_Principal_factory,
01240 tc_objref_factory,
01241 tc_struct_factory,
01242 tc_union_factory,
01243 tc_enum_factory,
01244 tc_string_factory,
01245 tc_sequence_factory,
01246 tc_array_factory,
01247 tc_alias_factory,
01248 tc_except_factory,
01249 tc_longlong_factory,
01250 tc_ulonglong_factory,
01251 tc_longdouble_factory,
01252 tc_wchar_factory,
01253 tc_wstring_factory,
01254 tc_fixed_factory,
01255 tc_value_factory,
01256 tc_value_box_factory,
01257 tc_native_factory,
01258 tc_abstract_interface_factory,
01259 tc_local_interface_factory,
01260 tc_component_factory,
01261 tc_home_factory,
01262 tc_event_factory
01263 };
01264
01265 return factory_map[kind] (static_cast<CORBA::TCKind> (kind),
01266 cdr,
01267 tc,
01268 infos);
01269 }
01270
01271 bool
01272 tc_demarshal_indirection (TAO_InputCDR & cdr,
01273 CORBA::TypeCode_ptr & tc,
01274 TAO::TypeCodeFactory::TC_Info_List & infos)
01275 {
01276 CORBA::Long offset;
01277
01278 if (!(cdr >> offset) || offset >= -4)
01279 {
01280
01281
01282
01283
01284
01285 return false;
01286 }
01287
01288 TAO_InputCDR indir_stream (cdr.rd_ptr () + offset - sizeof (CORBA::Long),
01289 (-offset) + sizeof (CORBA::Long),
01290 cdr.byte_order ());
01291
01292 if (!indir_stream.good_bit ())
01293 {
01294 return false;
01295 }
01296
01297 CORBA::TCKind kind;
01298 if (!(indir_stream >> kind)
01299
01300
01301 || static_cast<CORBA::ULong> (kind) == TYPECODE_INDIRECTION
01302
01303
01304
01305 || !(kind == CORBA::tk_struct
01306 || kind == CORBA::tk_union
01307 || kind == CORBA::tk_value
01308 || kind == CORBA::tk_event
01309 || kind == CORBA::tk_alias))
01310 {
01311 return false;
01312 }
01313
01314
01315
01316 TAO_InputCDRByteOrderGuard boguard (indir_stream);
01317 if (!start_cdr_encap_extraction (indir_stream))
01318 {
01319 return false;
01320 }
01321
01322
01323
01324
01325
01326
01327
01328
01329 CORBA::String_var id;
01330 if (!(indir_stream >> TAO_InputCDR::to_string (id.out (), 0)))
01331 return false;
01332
01333 if (CORBA::tk_alias == kind)
01334 {
01335
01336
01337
01338 CORBA::String_var name;
01339 CORBA::TypeCode_var content_type;
01340 if (!(indir_stream >> TAO_InputCDR::to_string (name.out (), 0)
01341 && tc_demarshal (indir_stream, content_type.out (), infos)))
01342 {
01343 return false;
01344 }
01345
01346 typedef TAO::TypeCode::Alias<
01347 CORBA::String_var,
01348 CORBA::TypeCode_var,
01349 TAO::True_RefCount_Policy> typecode_type;
01350
01351
01352 ACE_NEW_RETURN (tc,
01353 typecode_type (kind,
01354 id.in (),
01355 name.in (),
01356 content_type),
01357 false);
01358 return true;
01359 }
01360
01361
01362
01363
01364
01365 TAO::TypeCodeFactory::TC_Info_List recursive_tc;
01366 if (find_recursive_tc (id.in (), recursive_tc, infos))
01367 {
01368 tc = recursive_tc[0].type;
01369 }
01370 else switch (kind)
01371 {
01372 case CORBA::tk_struct:
01373 {
01374 typedef ACE_Array_Base<
01375 TAO::TypeCode::Struct_Field<
01376 CORBA::String_var,
01377 CORBA::TypeCode_var> > member_array_type;
01378
01379 typedef TAO::TypeCode::Struct<
01380 CORBA::String_var,
01381 CORBA::TypeCode_var,
01382 member_array_type,
01383 TAO::True_RefCount_Policy> typecode_type;
01384
01385 typedef TAO::TypeCode::Recursive_Type<typecode_type,
01386 CORBA::TypeCode_var,
01387 member_array_type>
01388 recursive_typecode_type;
01389
01390 ACE_NEW_RETURN (tc,
01391 recursive_typecode_type (kind,
01392 id.in ()),
01393 false);
01394
01395
01396 return add_to_recursion_list (tc, infos);
01397 }
01398 break;
01399 case CORBA::tk_union:
01400 {
01401 typedef union_case_array_type member_array_type;
01402
01403 typedef TAO::TypeCode::Union<
01404 CORBA::String_var,
01405 CORBA::TypeCode_var,
01406 member_array_type,
01407 TAO::True_RefCount_Policy> typecode_type;
01408
01409 typedef TAO::TypeCode::Recursive_Type<typecode_type,
01410 CORBA::TypeCode_var,
01411 member_array_type>
01412 recursive_typecode_type;
01413
01414 ACE_NEW_RETURN (tc,
01415 recursive_typecode_type (kind,
01416 id.in ()),
01417 false);
01418
01419
01420 return add_to_recursion_list (tc, infos);
01421 }
01422 break;
01423 case CORBA::tk_value:
01424 case CORBA::tk_event:
01425 {
01426 typedef ACE_Array_Base<
01427 TAO::TypeCode::Value_Field<
01428 CORBA::String_var,
01429 CORBA::TypeCode_var> > member_array_type;
01430
01431 typedef TAO::TypeCode::Value<
01432 CORBA::String_var,
01433 CORBA::TypeCode_var,
01434 member_array_type,
01435 TAO::True_RefCount_Policy> typecode_type;
01436
01437 typedef TAO::TypeCode::Recursive_Type<typecode_type,
01438 CORBA::TypeCode_var,
01439 member_array_type>
01440 recursive_typecode_type;
01441
01442 ACE_NEW_RETURN (tc,
01443 recursive_typecode_type (kind,
01444 id.in ()),
01445 false);
01446
01447
01448 return add_to_recursion_list (tc, infos);
01449 }
01450 break;
01451 default:
01452 return false;
01453 }
01454
01455 return true;
01456 }
01457 }
01458
01459
01460
01461 CORBA::Boolean
01462 operator>> (TAO_InputCDR & cdr, CORBA::TypeCode_ptr & tc)
01463 {
01464 TAO::TypeCodeFactory::TC_Info_List infos;
01465
01466 return tc_demarshal (cdr, tc, infos);
01467 }
01468
01469 TAO_END_VERSIONED_NAMESPACE_DECL