CorbaTemplateProtocol.hpp

00001 /***************************************************************************
00002   tag: FMTC  Tue Mar 11 21:49:24 CET 2008  CorbaTemplateProtocol.hpp
00003 
00004                         CorbaTemplateProtocol.hpp -  description
00005                            -------------------
00006     begin                : Tue March 11 2008
00007     copyright            : (C) 2008 FMTC
00008     email                : peter.soetens@fmtc.be
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
00035  *                                                                         *
00036  ***************************************************************************/
00037 
00038 
00039 #ifndef ORO_CORBA_TEMPATE_PROTOCOL_HPP
00040 #define ORO_CORBA_TEMPATE_PROTOCOL_HPP
00041 
00042 #include "../Types.hpp"
00043 #include "ExpressionProxy.hpp"
00044 
00045 #include "CorbaPort.hpp"
00046 #include "CorbaDataObjectProxy.hpp"
00047 #include "CorbaBufferProxy.hpp"
00048 #include "ExpressionServer.hpp"
00049 #include "DataFlowI.h"
00050 
00051 namespace RTT
00052 { namespace detail
00053   {
00054       using namespace RTT::Corba;
00055 
00074       template<class T>
00075       class CorbaTemplateProtocol
00076           : public TypeTransporter
00077       {
00078       public:
00082           typedef T UserType;
00086           typedef typename Property<T>::DataSourceType PropertyType;
00087 
00091           virtual void* createBlob( DataSourceBase::shared_ptr source) const
00092           {
00093               typename DataSource<T>::shared_ptr d = AdaptDataSource<T>()( source );
00094               if ( d )
00095                   return AnyConversion<PropertyType>::createAny( d->value() );
00096               return 0;
00097           }
00098 
00102           virtual bool updateBlob(const void* blob, DataSourceBase::shared_ptr target) const
00103           {
00104             //This line causes a compile error in DataSourceAdaptor.hpp (where the bug is)
00105             //Only narrow.
00106 //             AssignableDataSource<T>* ad = AdaptAssignableDataSource<T>()( target );
00107             typename AssignableDataSource<T>::shared_ptr ad = AssignableDataSource<T>::narrow( target.get() );
00108             const CORBA::Any* any = static_cast<const CORBA::Any*>(blob);
00109             if ( ad ) {
00110                 PropertyType value;
00111                 if (AnyConversion<PropertyType>::update(*any, value ) ) {
00112                     ad->set( value );
00113                     return true;
00114                 }
00115             }
00116             return false;
00117           }
00118 
00122           virtual DataSourceBase* proxy( void* data ) const
00123           {
00124             DataSourceBase* result = 0;
00125             Corba::Expression_ptr e = static_cast<Corba::Expression_ptr>(data);
00126 
00127             // first try as assignable DS, if not possible, try as normal DS.
00128             result = Corba::ExpressionProxy::NarrowAssignableDataSource<PropertyType>( e );
00129             if (!result )
00130                 result = Corba::ExpressionProxy::NarrowDataSource<PropertyType>( e );
00131 
00132             return result;
00133           }
00134 
00135           virtual void* server(DataSourceBase::shared_ptr source, bool assignable, void* arg ) const
00136           {
00137               PortableServer::POA_ptr p = static_cast<PortableServer::POA_ptr>(arg);
00138               if (assignable){
00139                   return static_cast<Expression_ptr>(Corba::ExpressionServer::CreateAssignableExpression( source, p ));
00140 
00141               } else {
00142                   return Corba::ExpressionServer::CreateExpression( source, p );
00143               }
00144           }
00145 
00146           virtual void* method(DataSourceBase::shared_ptr source, MethodC* orig, void* arg) const
00147           {
00148               PortableServer::POA_ptr p = static_cast<PortableServer::POA_ptr>(arg);
00149               return Corba::ExpressionServer::CreateMethod( source, orig, p );
00150           }
00151 
00152           virtual DataSourceBase* narrowDataSource(DataSourceBase* dsb)
00153           {
00154               // then try to see if it is a CORBA object.
00155               //Corba::ExpressionProxyInterface* prox = dynamic_cast< Corba::ExpressionProxyInterface* >(dsb);
00156               // Only try if the names match in the first place.
00157               if ( dsb->serverProtocol() == ORO_CORBA_PROTOCOL_ID && dsb->getTypeName() == DataSource<T>::GetTypeName() ) {
00158                   Logger::log() << Logger::Debug << "Trying to narrow server "<<dsb->getType()<<" to local "<<DataSource<T>::GetType() <<Logger::endl;
00159                   Corba::Expression_var expr = (Corba::Expression_ptr)dsb->server(ORO_CORBA_PROTOCOL_ID, 0) ;
00160                   assert( !CORBA::is_nil(expr) );
00161                   return Corba::ExpressionProxy::NarrowDataSource<T>( expr.in() );
00162               }
00163               Logger::log() << Logger::Debug << "Failed to narrow server "<<dsb->getType()<<" to local "<<DataSource<T>::GetType() <<Logger::endl;
00164 
00165               // See if the DS contains an Any. This is required for the createMethodAny variants:
00166               DataSource<CORBA::Any_var>* aret = dynamic_cast< DataSource<CORBA::Any_var>* >( dsb );
00167               if (aret){
00168                   return Corba::ExpressionProxy::NarrowConstant<T>( aret->get().in() );
00169               }
00170               return 0;
00171           }
00172 
00173           virtual DataSourceBase* narrowAssignableDataSource(DataSourceBase* dsb)
00174           {
00175               // then try to see if it is a CORBA object.
00176               //Corba::ExpressionProxyInterface* prox = dynamic_cast< Corba::ExpressionProxyInterface* >(dsb);
00177               if ( dsb->serverProtocol() == ( ORO_CORBA_PROTOCOL_ID ) && dsb->getTypeName() == DataSource<T>::GetTypeName() ) {
00178                   Corba::Expression_var expr = (Corba::Expression_ptr)dsb->server(ORO_CORBA_PROTOCOL_ID,0) ;
00179                   return Corba::ExpressionProxy::NarrowAssignableDataSource<T>( expr.in() );
00180               }
00181               return 0;
00182           }
00183 
00184           virtual DataSourceBase* dataProxy( PortInterface* data ) const
00185           {
00186               // Detect corba connection
00187               Corba::CorbaPort* cp = dynamic_cast<Corba::CorbaPort*>( data );
00188 
00189               assert(cp);
00190 
00191               return new Corba::CorbaDataObjectProxy<T>("CorbaProxy", cp->getDataChannel());
00192           }
00193 
00194           virtual DataSourceBase* dataProxy( void* data ) const
00195           {
00196               Corba::AssignableExpression_ptr ae = static_cast<Corba::AssignableExpression_ptr>(data);
00197               log(Debug) << "Creating Corba DataSource proxy." << endlog();
00198               return new Corba::CorbaDataObjectProxy<T>("CorbaProxy", ae );
00199           }
00200 
00201           virtual void* dataServer( DataSourceBase::shared_ptr source, void* arg) const
00202           {
00203               // create a default channel.
00204               log(Debug) << "Returning Corba Data Object." << endlog();
00205               return this->server(source, true, arg );
00206           }
00207 
00212           virtual BufferBase* bufferProxy( PortInterface* data ) const
00213           {
00214               // Detect corba connection
00215               Corba::CorbaPort* cp = dynamic_cast<Corba::CorbaPort*>( data );
00216 
00217               assert( cp );
00218 
00219               return new Corba::CorbaBufferProxy<T>( cp->getBufferChannel() );
00220           }
00221 
00222           virtual BufferBase* bufferProxy( void* data ) const
00223           {
00224               Corba::BufferChannel_ptr buf = static_cast<Corba::BufferChannel_ptr>(data);
00225               log(Debug) << "Creating Corba BufferChannel proxy." << endlog();
00226               return new Corba::CorbaBufferProxy<T>( buf );
00227           }
00228 
00229             virtual void* bufferServer( BufferBase::shared_ptr source, void* arg) const
00230           {
00231               // arg is POA !
00232               typename RTT::BufferInterface<T>::shared_ptr bi = boost::dynamic_pointer_cast< RTT::BufferInterface<T> >( source );
00233               log(Debug) << "Creating Corba BufferChannel." << endlog();
00234               RTT_Corba_BufferChannel_i<T>* cbuf = new RTT_Corba_BufferChannel_i<T>( bi );
00235               return cbuf->_this();
00236           }
00237       };
00238 }
00239 }
00240 
00241 #endif
Generated on Thu Dec 23 13:22:36 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3