Union_TypeCode.cpp

Go to the documentation of this file.
00001 // $Id: Union_TypeCode.cpp 78457 2007-05-23 12:42:05Z johnnyw $
00002 
00003 #ifndef TAO_UNION_TYPECODE_CPP
00004 #define TAO_UNION_TYPECODE_CPP
00005 
00006 #include "tao/AnyTypeCode/Union_TypeCode.h"
00007 #include "tao/AnyTypeCode/TypeCode_Case_Base_T.h"
00008 
00009 #ifndef __ACE_INLINE__
00010 # include "tao/AnyTypeCode/Union_TypeCode.inl"
00011 #endif  /* !__ACE_INLINE__ */
00012 
00013 #include "tao/AnyTypeCode/Any.h"
00014 
00015 #include "ace/Value_Ptr.h"
00016 
00017 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00018 
00019 template <typename StringType,
00020           typename TypeCodeType,
00021           class CaseArrayType,
00022           class RefCountPolicy>
00023 bool
00024 TAO::TypeCode::Union<StringType,
00025                      TypeCodeType,
00026                      CaseArrayType,
00027                      RefCountPolicy>::tao_marshal (
00028   TAO_OutputCDR & cdr,
00029   CORBA::ULong offset) const
00030 {
00031   // A tk_union TypeCode has a "complex" parameter list type (see
00032   // Table 15-2 in Section 15.3.5.1 "TypeCode" in the CDR section of
00033   // the CORBA specification), meaning that it must be marshaled into
00034   // a CDR encapsulation.
00035 
00036   // Create a CDR encapsulation.
00037   TAO_OutputCDR enc;
00038 
00039   // Account for the encoded CDR encapsulation length and byte order.
00040   //
00041   // Aligning on an octet since the next value after the CDR
00042   // encapsulation length will always be the byte order octet/boolean
00043   // in this case.
00044   offset = ACE_align_binary (offset + 4,
00045                              ACE_CDR::OCTET_ALIGN);
00046 
00047   bool const success =
00048     (enc << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER))
00049     && (enc << TAO_OutputCDR::from_string (this->base_attributes_.id (), 0))
00050     && (enc << TAO_OutputCDR::from_string (this->base_attributes_.name (), 0))
00051     && marshal (enc,
00052                 Traits<StringType>::get_typecode (this->discriminant_type_),
00053                 offset + enc.total_length ())
00054     && (enc << this->default_index_)
00055     && (enc << this->ncases_);
00056 
00057   if (!success)
00058     {
00059       return false;
00060     }
00061 
00062   for (CORBA::ULong i = 0; i < this->ncases_; ++i)
00063     {
00064       case_type const & c = *this->cases_[i];
00065 
00066       if (!c.marshal (enc, offset))
00067         {
00068           return false;
00069         }
00070     }
00071 
00072   return
00073     cdr << static_cast<CORBA::ULong> (enc.total_length ())
00074     && cdr.write_octet_array_mb (enc.begin ());
00075 }
00076 
00077 template <typename StringType,
00078           typename TypeCodeType,
00079           class CaseArrayType,
00080           class RefCountPolicy>
00081 void
00082 TAO::TypeCode::Union<StringType,
00083                      TypeCodeType,
00084                      CaseArrayType,
00085                      RefCountPolicy>::tao_duplicate (void)
00086 {
00087   this->RefCountPolicy::add_ref ();
00088 }
00089 
00090 template <typename StringType,
00091           typename TypeCodeType,
00092           class CaseArrayType,
00093           class RefCountPolicy>
00094 void
00095 TAO::TypeCode::Union<StringType,
00096                      TypeCodeType,
00097                      CaseArrayType,
00098                      RefCountPolicy>::tao_release (void)
00099 {
00100   this->RefCountPolicy::remove_ref ();
00101 }
00102 
00103 template <typename StringType,
00104           typename TypeCodeType,
00105           class CaseArrayType,
00106           class RefCountPolicy>
00107 CORBA::Boolean
00108 TAO::TypeCode::Union<StringType,
00109                      TypeCodeType,
00110                      CaseArrayType,
00111                      RefCountPolicy>::equal_i (CORBA::TypeCode_ptr tc) const
00112 {
00113   // These calls shouldn't throw since CORBA::TypeCode::equal()
00114   // verified that the TCKind is the same as our's prior to invoking
00115   // this method, meaning that the CORBA::tk_union TypeCode methods
00116   // are supported.
00117 
00118   CORBA::ULong const tc_count =
00119     tc->member_count ();
00120 
00121   CORBA::Long tc_def = tc->default_index ();
00122 
00123   if (tc_count != this->ncases_
00124       || tc_def != this->default_index_)
00125     return false;
00126 
00127   // Check the discriminator type.
00128   CORBA::TypeCode_var tc_discriminator =
00129     tc->discriminator_type ();
00130 
00131   CORBA::Boolean const equal_discriminators =
00132     Traits<StringType>::get_typecode (this->discriminant_type_)->equal (
00133       tc_discriminator.in ());
00134 
00135   if (!equal_discriminators)
00136     return false;
00137 
00138   for (CORBA::ULong i = 0; i < this->ncases_; ++i)
00139     {
00140       if (this->default_index_ > -1
00141           && static_cast<CORBA::ULong> (this->default_index_) == i)
00142         {
00143           // Don't bother checking equality of default case label.  It
00144           // will always be the zero octet (the CDR encoded value is
00145           // ignored).
00146           continue;
00147         }
00148 
00149       case_type const & lhs_case = *this->cases_[i];
00150 
00151       bool const equal_case = lhs_case.equal (i, tc);
00152 
00153       if (!equal_case)
00154         return false;
00155     }
00156 
00157   return true;
00158 }
00159 
00160 template <typename StringType,
00161           typename TypeCodeType,
00162           class CaseArrayType,
00163           class RefCountPolicy>
00164 CORBA::Boolean
00165 TAO::TypeCode::Union<StringType,
00166                      TypeCodeType,
00167                      CaseArrayType,
00168                      RefCountPolicy>::equivalent_i (CORBA::TypeCode_ptr tc) const
00169 {
00170   // Perform a structural comparison, excluding the name() and
00171   // member_name() operations.
00172 
00173   CORBA::ULong const tc_count =
00174     tc->member_count ();
00175 
00176   CORBA::Long tc_def = tc->default_index ();
00177 
00178   if (tc_count != this->ncases_
00179       || tc_def != this->default_index_)
00180     return false;
00181 
00182   CORBA::TypeCode_var tc_discriminator =
00183     tc->discriminator_type ();
00184 
00185   CORBA::Boolean const equiv_discriminators =
00186     Traits<StringType>::get_typecode (this->discriminant_type_)->equivalent (
00187       tc_discriminator.in ());
00188 
00189   if (!equiv_discriminators)
00190     return false;
00191 
00192   for (CORBA::ULong i = 0; i < this->ncases_; ++i)
00193     {
00194       if (this->default_index_ > -1
00195           && static_cast<CORBA::ULong> (this->default_index_) == i)
00196         {
00197           // Don't bother checking equality/equivalence of default
00198           // case label.  It will always be the zero octet (the CDR
00199           // encoded value is ignored).
00200           continue;
00201         }
00202 
00203       case_type const & lhs_case = *this->cases_[i];
00204 
00205       bool const equivalent_case =
00206         lhs_case.equivalent (i, tc);
00207 
00208       if (!equivalent_case)
00209         return false;
00210     }
00211 
00212   return true;
00213 }
00214 
00215 template <typename StringType,
00216           typename TypeCodeType,
00217           class CaseArrayType,
00218           class RefCountPolicy>
00219 CORBA::TypeCode_ptr
00220 TAO::TypeCode::Union<StringType,
00221                      TypeCodeType,
00222                      CaseArrayType,
00223                      RefCountPolicy>::get_compact_typecode_i (void) const
00224 {
00225 //   typedef ACE::Value_Ptr<TAO::TypeCode::Case<CORBA::String_var,
00226 //                                              CORBA::TypeCode_var> > elem_type;
00227 
00228 //   ACE_Array_Base<elem_type> tc_cases (this->ncases_);
00229 
00230 //   if (this->ncases_ > 0)
00231 //     {
00232 //       // Dynamically construct a new array of cases stripped of
00233 //       // member names.
00234 
00235 //       static char const empty_name[] = "";
00236 
00237 //       for (CORBA::ULong i = 0; i < this->ncases_; ++i)
00238 //         {
00239 //           // Member names will be stripped, i.e. not embedded within
00240 //           // the compact TypeCode.
00241 //           tc_cases[i].name = empty_name;
00242 //           tc_cases[i].type =
00243 //             this->cases_[i]->type ()->get_compact_typecode (
00244 //              );
00245 //         }
00246 //     }
00247 
00248 //   // Create the compact union TypeCode.
00249 //   TAO_TypeCodeFactory_Adapter * adapter =
00250 //     ACE_Dynamic_Service<TAO_TypeCodeFactory_Adapter>::instance (
00251 //       TAO_ORB_Core::typecodefactory_adapter_name ());
00252 
00253 //   if (adapter == 0)
00254 //     {
00255 //       throw ::CORBA::INTERNAL ();
00256 //     }
00257 
00258 //   return
00259 //     adapter->create_union_tc (
00260 //       this->base_attributes_.id (),
00261 //       "",  /* empty name */
00262 //       Traits<StringType>::get_typecode (this->discriminant_type_),
00263 //       tc_cases,
00264 //       this->ncases_,
00265 //       this->default_index_,
00266 //       "",
00267 //       Traits<StringType>::get_typecode (this->default_case_.type)
00268 //      );
00269 
00270   throw ::CORBA::NO_IMPLEMENT ();
00271 }
00272 
00273 template <typename StringType,
00274           typename TypeCodeType,
00275           class CaseArrayType,
00276           class RefCountPolicy>
00277 char const *
00278 TAO::TypeCode::Union<StringType,
00279                      TypeCodeType,
00280                      CaseArrayType,
00281                      RefCountPolicy>::id_i (void) const
00282 {
00283   // Ownership is retained by the TypeCode, as required by the C++
00284   // mapping.
00285   return this->base_attributes_.id ();
00286 }
00287 
00288 template <typename StringType,
00289           typename TypeCodeType,
00290           class CaseArrayType,
00291           class RefCountPolicy>
00292 char const *
00293 TAO::TypeCode::Union<StringType,
00294                      TypeCodeType,
00295                      CaseArrayType,
00296                      RefCountPolicy>::name_i (void) const
00297 {
00298   // Ownership is retained by the TypeCode, as required by the C++
00299   // mapping.
00300   return this->base_attributes_.name ();
00301 }
00302 
00303 template <typename StringType,
00304           typename TypeCodeType,
00305           class CaseArrayType,
00306           class RefCountPolicy>
00307 CORBA::ULong
00308 TAO::TypeCode::Union<StringType,
00309                      TypeCodeType,
00310                       CaseArrayType,
00311                       RefCountPolicy>::member_count_i (void) const
00312 {
00313   return this->ncases_;
00314 }
00315 
00316 template <typename StringType,
00317           typename TypeCodeType,
00318           class CaseArrayType,
00319           class RefCountPolicy>
00320 char const *
00321 TAO::TypeCode::Union<StringType,
00322                      TypeCodeType,
00323                      CaseArrayType,
00324                      RefCountPolicy>::member_name_i (CORBA::ULong index) const
00325 {
00326   // Ownership is retained by the TypeCode, as required by the C++
00327   // mapping.
00328   if (index >= this->ncases_)
00329     throw ::CORBA::TypeCode::Bounds ();
00330 
00331   return this->cases_[index]->name ();
00332 }
00333 
00334 template <typename StringType,
00335           typename TypeCodeType,
00336           class CaseArrayType,
00337           class RefCountPolicy>
00338 CORBA::TypeCode_ptr
00339 TAO::TypeCode::Union<StringType,
00340                      TypeCodeType,
00341                      CaseArrayType,
00342                      RefCountPolicy>::member_type_i (CORBA::ULong index) const
00343 {
00344   if (index >= this->ncases_)
00345     throw ::CORBA::TypeCode::Bounds ();
00346 
00347   return CORBA::TypeCode::_duplicate (this->cases_[index]->type ());
00348 }
00349 
00350 template <typename StringType,
00351           typename TypeCodeType,
00352           class CaseArrayType,
00353           class RefCountPolicy>
00354 CORBA::Any *
00355 TAO::TypeCode::Union<StringType,
00356                      TypeCodeType,
00357                      CaseArrayType,
00358                      RefCountPolicy>::member_label_i (CORBA::ULong index) const
00359 {
00360   if (index >= this->ncases_)
00361     throw ::CORBA::TypeCode::Bounds ();
00362 
00363   // Default case.
00364   if (this->default_index_ > -1
00365       && static_cast<CORBA::ULong> (this->default_index_) == index)
00366     {
00367       CORBA::Any * any = 0;
00368       ACE_NEW_THROW_EX (any,
00369                         CORBA::Any,
00370                         CORBA::NO_MEMORY ());
00371 
00372       CORBA::Any_var safe_any (any);
00373 
00374       // Default case's label is a zero octet.
00375       CORBA::Any::from_octet const zero_octet (0);
00376 
00377       // Default case/member has a zero octet label value.
00378       (*any) <<= zero_octet;
00379 
00380       return safe_any._retn ();
00381     }
00382 
00383   // Non-default cases.
00384   return this->cases_[index]->label ();
00385 }
00386 
00387 template <typename StringType,
00388           typename TypeCodeType,
00389           class CaseArrayType,
00390           class RefCountPolicy>
00391 CORBA::TypeCode_ptr
00392 TAO::TypeCode::Union<StringType,
00393                      TypeCodeType,
00394                      CaseArrayType,
00395                      RefCountPolicy>::discriminator_type_i (void) const
00396 {
00397   return
00398     CORBA::TypeCode::_duplicate (
00399       Traits<StringType>::get_typecode (this->discriminant_type_));
00400 }
00401 
00402 template <typename StringType,
00403           typename TypeCodeType,
00404           class CaseArrayType,
00405           class RefCountPolicy>
00406 CORBA::Long
00407 TAO::TypeCode::Union<StringType,
00408                      TypeCodeType,
00409                      CaseArrayType,
00410                      RefCountPolicy>::default_index_i (void) const
00411 {
00412   return this->default_index_;
00413 }
00414 
00415 TAO_END_VERSIONED_NAMESPACE_DECL
00416 
00417 #endif  /* TAO_UNION_TYPECODE_CPP */

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