TypeCode_CDR_Extraction.cpp

Go to the documentation of this file.
00001 // $Id: TypeCode_CDR_Extraction.cpp 79322 2007-08-13 10:43:10Z sma $
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     // An array of TC_Info objects is used instead of a map of
00043     // repository IDs to TypeCodes since it is presumed that the
00044     // number of directly or indirectly embedded types in a TypeCode
00045     // capable of holding another TypeCode will be small enough to
00046     // make traversing a list faster than performing a map lookup.
00047     // Use a simple array also reduces static and run-time footprint.
00048 
00049     struct TC_Info
00050     {
00051       /// Constructor.
00052       TC_Info (void) : id (0), type () {}
00053 
00054       /// Repository ID.
00055       char const * id;
00056 
00057       /// TypeCode
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     // Since we created a new tc, add it to the list.
00071     size_t const old_size = infos.size ();
00072     if (infos.size (old_size + 1) == -1)  // Incremental growth -- *sigh*
00073       {
00074         // Can't increase the list size.
00075         return false;
00076       }
00077 
00078     TAO::TypeCodeFactory::TC_Info & info = infos [old_size];
00079 
00080     try
00081       {
00082         // Append the new TC to the list.
00083         info.id = tc->id (); // Should never throw, but just incase!
00084         info.type = tc;
00085       }
00086     catch (...)
00087       {
00088         infos.size (old_size); // Remove the partially added new TC from the list.
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     // Don't bother demarshaling the encapsulation length.  Prefer
00099     // speed over early error checking.  Any CDR length related
00100     // failures will be detected when demarshaling the remainder of
00101     // the complex parameter list TypeCode.
00102 
00103     if (!(cdr.skip_ulong () // Skip encapsulation length.
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   // Use an ACE::Value_Ptr to provide exception safety and proper
00119   // copying semantics.
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   /// Demarshal a TypeCode.
00126   bool tc_demarshal (TAO_InputCDR & cdr,
00127                      CORBA::TypeCode_ptr & tc,
00128                      TAO::TypeCodeFactory::TC_Info_List & infos);
00129 
00130   /// Demarshal an indirected TypeCode.
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     // See comments above for rationale behind using an array instead
00140     // of a map.
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             // We have a matching id, so store the TypeCode in the out
00151             // array and then compare the others.
00152             size_t const old_size = tcs.size ();
00153             if (tcs.size (old_size + 1) == -1)  // Incremental growth -- *sigh*
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   // The remainder of a tk_objref TypeCode is encoded in a CDR
00326   // encapsulation.
00327   if (!start_cdr_encap_extraction (cdr))
00328     return false;
00329 
00330   // Extract the repository ID and name.
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 (),  // len >= 0!!!
00357                       tc_constant_id) == 0)
00358     {
00359       if (!cdr.skip_string ())  // No need to demarshal the name.
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       // No need to create a TypeCode.  Just use the TypeCode
00379       // constant.
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   // The remainder of a tk_struct/tk_except TypeCode is encoded in
00412   // a CDR encapsulation.
00413   if (!start_cdr_encap_extraction (cdr))
00414     return false;
00415 
00416   // Extract the repository ID, name and number of fields.
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   // Check if struct TypeCode is recursive.
00445   TAO::TypeCodeFactory::TC_Info_List recursive_tc;
00446   if (kind == CORBA::tk_struct && find_recursive_tc (id.in (), recursive_tc, infos))
00447     {
00448       // Set remaining parameters.
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;  // Should never occur.
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,     // Will be copied.
00478                                      nfields),
00479                       false);
00480     }
00481 
00482   return true;
00483 }
00484 
00485 bool
00486 TAO::TypeCodeFactory::tc_union_factory (CORBA::TCKind /* kind */,
00487                                         TAO_InputCDR & cdr,
00488                                         CORBA::TypeCode_ptr & tc,
00489                                         TC_Info_List & infos)
00490 {
00491   // The remainder of a tk_enum TypeCode is encoded in a CDR
00492   // encapsulation.
00493 
00494   if (!start_cdr_encap_extraction (cdr))
00495     return false;
00496 
00497   // Extract the repository ID, name, discriminant type, default index
00498   // and case count.
00499   CORBA::String_var id, name;
00500   CORBA::TypeCode_var discriminant_type;
00501   CORBA::Long default_index = -1;
00502   CORBA::ULong ncases = 0;  // Just 'n case :-)
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 ())) // No need to use tc_demarshal()
00507     return false;
00508 
00509   CORBA::TCKind const discriminant_kind =
00510     discriminant_type->kind ();
00511 
00512   // Check for valid discriminant type.
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       // Ugly.  *sigh*
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  /* !ACE_LACKS_LONGLONG_T */
00679         default:
00680           return false;
00681         }
00682 
00683       elem_type case_value (the_case);
00684       member.swap (case_value);  // Exception-safe
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   // Check if we have recursive members.  There could be multiple.
00703   TAO::TypeCodeFactory::TC_Info_List recursive_tc;
00704   if (find_recursive_tc (id.in (), recursive_tc, infos))
00705     {
00706       // Set remaining parameters.
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;  // Should never occur.
00724 
00725           rtc->union_parameters (name.in (),
00726                                  discriminant_type,
00727                                  cases,     // Will be copied.
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,     // Will be copied.
00741                                      ncases,
00742                                      default_index),
00743                       false);
00744     }
00745 
00746   return true;
00747 }
00748 
00749 bool
00750 TAO::TypeCodeFactory::tc_enum_factory (CORBA::TCKind /* kind */,
00751                                        TAO_InputCDR & cdr,
00752                                        CORBA::TypeCode_ptr & tc,
00753                                        TC_Info_List &)
00754 {
00755   // The remainder of a tk_enum TypeCode is encoded in a CDR
00756   // encapsulation.
00757 
00758   if (!start_cdr_encap_extraction (cdr))
00759     return false;
00760 
00761   // Extract the repository ID, name and number of fields.
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,     // Will be copied.
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   // A tk_string/tk_wstring TypeCode has a simple parameter list,
00800   // i.e. it is not encoded in a CDR encapsulation.
00801 
00802   CORBA::ULong bound;
00803   if (!(cdr >> bound))
00804     return false;
00805 
00806   if (bound == 0)
00807     {
00808       // Just use the TypeCode constant.
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   // The remainder of a tk_sequence TypeCode is encoded in a CDR
00837   // encapsulation.
00838 
00839   if (!start_cdr_encap_extraction (cdr))
00840     return false;
00841 
00842   // Extract the repository ID, name and content type.
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   // The remainder of a tk_alias or tk_value_box TypeCode is encoded
00877   // in a CDR encapsulation.
00878 
00879   if (!start_cdr_encap_extraction (cdr))
00880     return false;
00881 
00882   // Extract the repository ID, name and content type.
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   // A tk_fixed TypeCode has a simple parameter list, i.e. it is not
00975   // encoded in a CDR encapsulation.
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   // The remainder of a tk_value/tk_event TypeCode is encoded in a
00997   // CDR encapsulation
00998 
00999   if (!start_cdr_encap_extraction (cdr))
01000     return false;
01001 
01002   // Extract the repository ID, name and number of fields.
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   // Check if valuetype/eventtype TypeCode is recursive.
01042   TAO::TypeCodeFactory::TC_Info_List recursive_tc;
01043   if (find_recursive_tc (id.in (), recursive_tc, infos))
01044     {
01045       // Set remaining parameters.
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;  // Should never occur.
01063 
01064           rtc->valuetype_parameters (name.in (),
01065                                      type_modifier,
01066                                      concrete_base,
01067                                      fields,     // Will be copied.
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,     // Will be copied.
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     // ULong since we need to detect indirected TypeCodes, too.
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         // Offsets must be negative since they point back to a
01230         // TypeCode found earlier in the CDR stream.  They must be
01231         // less than -4 since an offset of -4 points back to the
01232         // indirection TypeCode itself, meaning that it would be
01233         // self-indirecting.
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         // Indirected TypeCode must point to top-level TypeCode.
01250         || static_cast<CORBA::ULong> (kind) == TYPECODE_INDIRECTION
01251 
01252         // Only struct, union, event and valuetype TypeCodes may be
01253         // recursive. However non-recursive ALIAS may be indirected.
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         // Currently all recursive TypeCodes have complex parameter
01261         // lists, meaning they are encoded as CDR encapsulations.
01262         || !start_cdr_encap_extraction (indir_stream))
01263       {
01264         return false;
01265       }
01266 
01267     /**
01268      * @todo Recursive TypeCode demarshaling is currently suboptimal
01269      *       due to redundant demarshaling of TypeCode parameters,
01270      *       such as repository ID, and excessive
01271      *       allocations/copying.
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       // NOTE: Although Alias may be indirect, they are NOT recursive!
01281       // Just create another type code for this alias.
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       // NOTE: Although Alias may be indirect, they are NOT recursive!
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     // Don't bother demarshaling the rest of the parameters.  They will
01307     // be handled by the top-level TypeCode demarshaling call.
01308 
01309     // Check if we already have a tc for this RECURSIVE type, if yes, use that
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           // Since we created a new recursive tc, add it to the "Recursive" list.
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           // Since we created a new recursive tc, add it to the "Recursive" list.
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           // Since we created a new recursive tc, add it to the "Recursive" list.
01393           return add_to_recursion_list (tc, infos);
01394         }
01395         break;
01396       default:
01397         return false;  // We should never get here.
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

Generated on Sun Jan 27 13:21:07 2008 for TAO_AnyTypeCode by doxygen 1.3.6