Any_Unknown_IDL_Type.cpp

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

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