Any_Unknown_IDL_Type.cpp

Go to the documentation of this file.
00001 // $Id: Any_Unknown_IDL_Type.cpp 80551 2008-02-01 22:14:35Z parsons $
00002 
00003 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
00004 #include "tao/AnyTypeCode/Marshal.h"
00005 #include "tao/AnyTypeCode/TypeCode.h"
00006 #include "tao/Valuetype_Adapter.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/SystemException.h"
00009 #include "tao/CDR.h"
00010 
00011 #include "ace/Dynamic_Service.h"
00012 #include "ace/OS_NS_string.h"
00013 
00014 ACE_RCSID (AnyTypeCode,
00015            Any_Unknown_IDL_Type,
00016            "$Id: Any_Unknown_IDL_Type.cpp 80551 2008-02-01 22:14:35Z parsons $")
00017 
00018 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 
00021 TAO::Unknown_IDL_Type::LOCK
00022 TAO::Unknown_IDL_Type::lock_i (void)
00023 {
00024   static LOCK base_lock_ (new ACE_Lock_Adapter<TAO_SYNCH_MUTEX>());
00025   return base_lock_;
00026 }
00027 
00028 TAO::Unknown_IDL_Type::Unknown_IDL_Type (CORBA::TypeCode_ptr tc,
00029                                          TAO_InputCDR &cdr)
00030   : TAO::Any_Impl (0, tc, true)
00031   , lock_ (lock_i ())
00032   , cdr_ (static_cast<ACE_Message_Block*>(0), lock_.get ())
00033 {
00034   try
00035     {
00036       this->_tao_decode (cdr);
00037     }
00038   catch (::CORBA::Exception const &)
00039     {
00040     }
00041 }
00042 
00043 TAO::Unknown_IDL_Type::Unknown_IDL_Type (CORBA::TypeCode_ptr tc)
00044   : TAO::Any_Impl (0, tc, true)
00045   , lock_ (lock_i ())
00046   , cdr_ (static_cast<ACE_Message_Block*>(0), lock_.get ())
00047 {
00048 }
00049 
00050 TAO::Unknown_IDL_Type::~Unknown_IDL_Type (void)
00051 {
00052 }
00053 
00054 CORBA::Boolean
00055 TAO::Unknown_IDL_Type::marshal_value (TAO_OutputCDR & cdr)
00056 {
00057   try
00058     {
00059       // We don't want the rd_ptr to move, in case we are shared by
00060       // another Any, so we use this to copy the state, not the buffer.
00061       TAO_InputCDR for_reading (this->cdr_);
00062 
00063       TAO::traverse_status const status =
00064         TAO_Marshal_Object::perform_append (this->type_,
00065                                             &for_reading,
00066                                             &cdr);
00067 
00068       if (status != TAO::TRAVERSE_CONTINUE)
00069         {
00070           return false;
00071         }
00072     }
00073   catch (::CORBA::Exception const &)
00074     {
00075       return false;
00076     }
00077 
00078   return true;
00079 }
00080 
00081 const void *
00082 TAO::Unknown_IDL_Type::value (void) const
00083 {
00084   return this->cdr_.start ();
00085 }
00086 
00087 void
00088 TAO::Unknown_IDL_Type::free_value (void)
00089 {
00090   ::CORBA::release (this->type_);
00091 }
00092 
00093 TAO_InputCDR &
00094 TAO::Unknown_IDL_Type::_tao_get_cdr (void)
00095 {
00096   return this->cdr_;
00097 }
00098 
00099 int
00100 TAO::Unknown_IDL_Type::_tao_byte_order (void) const
00101 {
00102   return this->cdr_.byte_order ();
00103 }
00104 void
00105 TAO::Unknown_IDL_Type::_tao_decode (TAO_InputCDR & cdr)
00106 {
00107   // @@ (JP) The following code depends on the fact that
00108   //         TAO_InputCDR does not contain chained message blocks,
00109   //         otherwise <begin> and <end> could be part of
00110   //         different buffers!
00111 
00112   // This will be the start of a new message block.
00113   char const * const begin = cdr.rd_ptr ();
00114 
00115   // Skip over the next argument.
00116   TAO::traverse_status const status =
00117     TAO_Marshal_Object::perform_skip (this->type_, &cdr);
00118 
00119   if (status != TAO::TRAVERSE_CONTINUE)
00120     {
00121       throw ::CORBA::MARSHAL ();
00122     }
00123 
00124   // This will be the end of the new message block.
00125   char const * const end = cdr.rd_ptr ();
00126 
00127   // The ACE_CDR::mb_align() call can shift the rd_ptr by up to
00128   // ACE_CDR::MAX_ALIGNMENT - 1 bytes. Similarly, the offset adjustment
00129   // can move the rd_ptr by up to the same amount. We accommodate
00130   // this by including 2 * ACE_CDR::MAX_ALIGNMENT bytes of additional
00131   // space in the message block.
00132   size_t const size = end - begin;
00133 
00134   ACE_Message_Block new_mb (size + 2 * ACE_CDR::MAX_ALIGNMENT);
00135 
00136   ACE_CDR::mb_align (&new_mb);
00137   ptrdiff_t offset = ptrdiff_t (begin) % ACE_CDR::MAX_ALIGNMENT;
00138 
00139   if (offset < 0)
00140     {
00141       offset += ACE_CDR::MAX_ALIGNMENT;
00142     }
00143 
00144   new_mb.rd_ptr (offset);
00145   new_mb.wr_ptr (offset + size);
00146 
00147   ACE_OS::memcpy (new_mb.rd_ptr (), begin, size);
00148 
00149   this->cdr_.reset (&new_mb, cdr.byte_order ());
00150   this->cdr_.char_translator (cdr.char_translator ());
00151   this->cdr_.wchar_translator (cdr.wchar_translator ());
00152 
00153   // Take over the GIOP version, the input cdr can have a different
00154   // version then our current GIOP version.
00155   ACE_CDR::Octet major_version;
00156   ACE_CDR::Octet minor_version;
00157   cdr.get_version (major_version, minor_version);
00158   this->cdr_.set_version (major_version, minor_version);
00159 }
00160 
00161 CORBA::Boolean
00162 TAO::Unknown_IDL_Type::to_object (CORBA::Object_ptr & obj) const
00163 {
00164   try
00165     {
00166       CORBA::TCKind const kind = TAO::unaliased_kind (this->type_);
00167 
00168       if (kind != CORBA::tk_objref)
00169         {
00170           return false;
00171         }
00172 
00173       // We don't want the rd_ptr to move, in case we are shared by
00174       // another Any, so we use this to copy the state, not the buffer.
00175       TAO_InputCDR for_reading (this->cdr_);
00176 
00177       return for_reading >> obj;
00178     }
00179   catch (::CORBA::Exception const &)
00180     {
00181     }
00182 
00183   return false;
00184 }
00185 
00186 CORBA::Boolean
00187 TAO::Unknown_IDL_Type::to_value (CORBA::ValueBase* & val) const
00188 {
00189   try
00190     {
00191       CORBA::TCKind const kind = TAO::unaliased_kind (this->type_);
00192 
00193       if (kind != CORBA::tk_value)
00194         {
00195           return false;
00196         }
00197 
00198       TAO_ORB_Core *orb_core = this->cdr_.orb_core ();
00199       if (orb_core == 0)
00200         {
00201           orb_core = TAO_ORB_Core_instance ();
00202 
00203           if (TAO_debug_level > 0)
00204             {
00205               ACE_DEBUG ((LM_WARNING,
00206                           ACE_TEXT ("TAO (%P|%t) WARNING: extracting ")
00207                           ACE_TEXT ("valuetype using default ORB_Core\n")));
00208             }
00209         }
00210 
00211       // We don't want the rd_ptr to move, in case we are shared by
00212       // another Any, so we use this to copy the state, not the buffer.
00213       TAO_InputCDR for_reading (this->cdr_);
00214 
00215       TAO_Valuetype_Adapter * const adapter =
00216         orb_core->valuetype_adapter ();
00217       return adapter->stream_to_value (for_reading, val);
00218     }
00219   catch (::CORBA::Exception const &)
00220     {
00221     }
00222 
00223   return false;
00224 }
00225 
00226 CORBA::Boolean
00227 TAO::Unknown_IDL_Type::to_abstract_base (CORBA::AbstractBase_ptr & obj) const
00228 {
00229   try
00230     {
00231       CORBA::TCKind const kind = TAO::unaliased_kind (this->type_);
00232 
00233       if (kind != CORBA::tk_abstract_interface)
00234         {
00235           return false;
00236         }
00237 
00238       TAO_ORB_Core *orb_core = this->cdr_.orb_core ();
00239       if (orb_core == 0)
00240         {
00241           orb_core = TAO_ORB_Core_instance ();
00242 
00243           if (TAO_debug_level > 0)
00244             {
00245               ACE_DEBUG ((LM_WARNING,
00246                           ACE_TEXT ("TAO (%P|%t) WARNING: extracting ")
00247                           ACE_TEXT ("abstract base using default ORB_Core\n")));
00248             }
00249         }
00250 
00251       // We don't want the rd_ptr to move, in case we are shared by
00252       // another Any, so we use this to copy the state, not the buffer.
00253       TAO_InputCDR for_reading (this->cdr_);
00254 
00255       TAO_Valuetype_Adapter * const adapter =
00256         orb_core->valuetype_adapter ();
00257       return adapter->stream_to_abstract_base (for_reading, obj);
00258     }
00259    catch (::CORBA::Exception const &)
00260     {
00261     }
00262 
00263   return false;
00264 }
00265 
00266 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:40:11 2010 for TAO_AnyTypeCode by  doxygen 1.4.7