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