Orocos Real-Time Toolkit
2.5.0
|
00001 /*************************************************************************** 00002 tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 OperationInterfaceI.cpp 00003 00004 OperationInterfaceI.cpp - description 00005 ------------------- 00006 begin : Tue September 07 2010 00007 copyright : (C) 2010 The SourceWorks 00008 email : peter@thesourceworks.com 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 // -*- C++ -*- 00040 // 00041 // $Id$ 00042 00043 // **** Code generated by the The ACE ORB (TAO) IDL Compiler **** 00044 // TAO and the TAO IDL Compiler have been developed by: 00045 // Center for Distributed Object Computing 00046 // Washington University 00047 // St. Louis, MO 00048 // USA 00049 // http://www.cs.wustl.edu/~schmidt/doc-center.html 00050 // and 00051 // Distributed Object Computing Laboratory 00052 // University of California at Irvine 00053 // Irvine, CA 00054 // USA 00055 // http://doc.ece.uci.edu/ 00056 // and 00057 // Institute for Software Integrated Systems 00058 // Vanderbilt University 00059 // Nashville, TN 00060 // USA 00061 // http://www.isis.vanderbilt.edu/ 00062 // 00063 // Information about TAO is available at: 00064 // http://www.cs.wustl.edu/~schmidt/TAO.html 00065 00066 // TAO_IDL - Generated from 00067 // ../../../ACE_wrappers/TAO/TAO_IDL/be/be_codegen.cpp:1196 00068 00069 #include "CorbaLib.hpp" 00070 #include "CorbaTypeTransporter.hpp" 00071 #include "OperationInterfaceI.h" 00072 #include "AnyDataSource.hpp" 00073 #include "../../rtt-detail-fwd.hpp" 00074 #include "../../internal/OperationCallerC.hpp" 00075 #include "../../internal/SendHandleC.hpp" 00076 #include "../../Logger.hpp" 00077 00078 using namespace RTT; 00079 using namespace RTT::detail; 00080 using namespace std; 00081 00082 RTT_corba_CSendHandle_i::RTT_corba_CSendHandle_i (SendHandleC const& sh, OperationInterfacePart* ofp) 00083 : mhandle(sh), morig(sh), mofp(ofp) 00084 { 00085 // this will always be correct: 00086 for (unsigned int i = 1; i <= mofp->collectArity(); ++i) { 00087 const TypeInfo* ti = mofp->getCollectType(i); // retrieve 1..collectArity() 00088 assert(ti); 00089 cargs.push_back( ti->buildValue() ); 00090 mhandle.arg( cargs.back() ); 00091 } 00092 assert( mhandle.ready() ); 00093 } 00094 00095 RTT_corba_CSendHandle_i::~RTT_corba_CSendHandle_i (void) 00096 { 00097 } 00098 00105 bool anysequence_to_sourcevector( CAnyArguments const& anys, vector<DataSourceBase::shared_ptr>& sources) { 00106 return false; 00107 } 00108 00115 bool sourcevector_to_anysequence( vector<DataSourceBase::shared_ptr> const& sources, CAnyArguments & anys ) { 00116 bool valid = true; 00117 anys.length( sources.size() ); 00118 for(unsigned int i = 0; i != sources.size(); ++i) { 00119 const TypeInfo* ti = sources[i]->getTypeInfo(); 00120 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); 00121 ctt->updateAny(sources[i], anys[i]); 00122 } 00123 return valid; 00124 } 00125 00126 ::RTT::corba::CSendStatus RTT_corba_CSendHandle_i::collect ( 00127 ::RTT::corba::CAnyArguments_out args) 00128 { 00129 SendStatus ss = mhandle.collect(); 00130 args = new CAnyArguments(); 00131 if (ss == SendSuccess) { 00132 sourcevector_to_anysequence( cargs, *args.ptr() ); 00133 } 00134 return CSendStatus(static_cast<int>(ss) + 1); 00135 } 00136 00137 ::RTT::corba::CSendStatus RTT_corba_CSendHandle_i::collectIfDone ( 00138 ::RTT::corba::CAnyArguments_out args) 00139 { 00140 SendStatus ss = mhandle.collectIfDone(); 00141 args = new CAnyArguments(); 00142 if (ss == SendSuccess) { 00143 sourcevector_to_anysequence( cargs, *args.ptr() ); 00144 } 00145 return CSendStatus(static_cast<int>(ss) + 1); 00146 } 00147 00148 ::RTT::corba::CSendStatus RTT_corba_CSendHandle_i::checkStatus ( 00149 void) 00150 { 00151 return CSendStatus( static_cast<int>(mhandle.collectIfDone()) + 1 ); 00152 } 00153 00154 ::CORBA::Any * RTT_corba_CSendHandle_i::ret ( 00155 void) 00156 { 00157 SendStatus ss = mhandle.collectIfDone(); 00158 // We just copy over the first collectable argument. In 00159 // case of a void operation, we will thus return the first 00160 // reference argument. 00161 if (ss == SendSuccess) { 00162 if ( cargs.size() > 0) { 00163 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (cargs[0]->getTypeInfo()->getProtocol(ORO_CORBA_PROTOCOL_ID)); 00164 return ctt->createAny( cargs[0] ); 00165 } 00166 } 00167 return new CORBA::Any(); 00168 } 00169 00170 void RTT_corba_CSendHandle_i::checkArguments ( 00171 const ::RTT::corba::CAnyArguments & args) 00172 { 00173 try { 00174 SendHandleC shc(morig); 00175 for (unsigned int i = 0; i != mofp->collectArity(); ++i) { 00176 const TypeInfo* ti = mofp->getCollectType(i + 1); 00177 assert(ti); 00178 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (ti->getProtocol(ORO_CORBA_PROTOCOL_ID)); 00179 shc.arg(ctt->createDataSource(&args[i])); 00180 } 00181 // otherwise, we would block !!! 00182 shc.setAutoCollect(false); 00183 shc.check(); 00184 } catch (name_not_found_exception& nnf) { 00185 throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str()); 00186 } catch (wrong_number_of_args_exception& wna) { 00187 throw ::RTT::corba::CWrongNumbArgException(wna.wanted, wna.received); 00188 } catch (wrong_types_of_args_exception& wta) { 00189 throw ::RTT::corba::CWrongTypeArgException(wta.whicharg, wta.expected_.c_str(), wta.received_.c_str()); 00190 } 00191 } 00192 00193 void RTT_corba_CSendHandle_i::dispose ( 00194 void) 00195 { 00196 PortableServer::POA_var mPOA = _default_POA(); 00197 PortableServer::ObjectId_var oid = mPOA->servant_to_id(this); 00198 mPOA->deactivate_object( oid.in() ); 00199 return; 00200 } 00201 00202 // Implementation skeleton constructor 00203 RTT_corba_COperationInterface_i::RTT_corba_COperationInterface_i (OperationInterface* gmf, PortableServer::POA_ptr the_poa) 00204 :mfact(gmf), mpoa( PortableServer::POA::_duplicate(the_poa)) 00205 { 00206 } 00207 00208 PortableServer::POA_ptr RTT_corba_COperationInterface_i::_default_POA() 00209 { 00210 return PortableServer::POA::_duplicate(mpoa); 00211 } 00212 00213 00214 // Implementation skeleton destructor 00215 RTT_corba_COperationInterface_i::~RTT_corba_COperationInterface_i (void) 00216 { 00217 } 00218 00219 ::RTT::corba::COperationInterface::COperationList * RTT_corba_COperationInterface_i::getOperations ( 00220 void) 00221 { 00222 RTT::corba::COperationInterface::COperationList_var rlist = new RTT::corba::COperationInterface::COperationList(); 00223 00224 vector<string> flist = mfact->getNames(); 00225 rlist->length( flist.size() ); 00226 size_t drops=0; 00227 for (size_t i=0; i != flist.size(); ++i) 00228 if ( !mfact->isSynchronous(flist[i]) ) { 00229 rlist[i - drops] = CORBA::string_dup( flist[i].c_str() ); 00230 } else { 00231 ++drops; 00232 } 00233 rlist->length( flist.size() - drops); // we don't show the synchronous operations. 00234 return rlist._retn(); 00235 } 00236 00237 ::RTT::corba::CDescriptions * RTT_corba_COperationInterface_i::getArguments ( 00238 const char * operation) 00239 { 00240 CDescriptions_var ret = new CDescriptions(); 00241 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation))) 00242 throw ::RTT::corba::CNoSuchNameException( operation ); 00243 // operation found, convert args: 00244 OperationInterface::Descriptions args = mfact->getArgumentList( string(operation) ); 00245 ret->length( args.size() ); 00246 for (size_t i =0; i != args.size(); ++i) { 00247 ret[i].name = CORBA::string_dup( args[i].name.c_str() ); 00248 ret[i].description = CORBA::string_dup( args[i].description.c_str() ); 00249 ret[i].type = CORBA::string_dup( args[i].type.c_str() ); 00250 } 00251 return ret._retn(); 00252 } 00253 00254 char * RTT_corba_COperationInterface_i::getResultType ( 00255 const char * operation) 00256 { 00257 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00258 throw ::RTT::corba::CNoSuchNameException( operation ); 00259 return CORBA::string_dup( mfact->getResultType( string(operation) ).c_str() ); 00260 } 00261 00262 char* RTT_corba_COperationInterface_i::getArgumentType( 00263 const char* operation, 00264 CORBA::UShort nbr) 00265 { 00266 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00267 throw ::RTT::corba::CNoSuchNameException( operation ); 00268 if ( nbr > mfact->getPart(operation)->arity() ) 00269 throw ::RTT::corba::CWrongArgumentException( nbr, mfact->getPart(operation)->arity() ); 00270 return CORBA::string_dup( mfact->getPart( operation )->getArgumentType(nbr)->getTypeName().c_str() ); 00271 } 00272 00273 char* RTT_corba_COperationInterface_i::getCollectType( 00274 const char* operation, 00275 CORBA::UShort nbr) 00276 { 00277 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00278 throw ::RTT::corba::CNoSuchNameException( operation ); 00279 if ( nbr > mfact->getPart(operation)->collectArity() ) 00280 throw ::RTT::corba::CWrongArgumentException( nbr, mfact->getPart(operation)->collectArity() ); 00281 return CORBA::string_dup( mfact->getPart( operation )->getCollectType(nbr)->getTypeName().c_str() ); 00282 00283 } 00284 00285 ::CORBA::UShort RTT_corba_COperationInterface_i::getArity ( 00286 const char * operation) 00287 { 00288 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00289 throw ::RTT::corba::CNoSuchNameException( operation ); 00290 return mfact->getPart(operation)->arity(); 00291 } 00292 00293 ::CORBA::UShort RTT_corba_COperationInterface_i::getCollectArity ( 00294 const char * operation) 00295 { 00296 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00297 throw ::RTT::corba::CNoSuchNameException( operation ); 00298 return mfact->getPart(operation)->collectArity(); 00299 } 00300 00301 char * RTT_corba_COperationInterface_i::getDescription ( 00302 const char * operation) 00303 { 00304 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00305 throw ::RTT::corba::CNoSuchNameException( operation ); 00306 return CORBA::string_dup( mfact->getDescription( string(operation) ).c_str() ); 00307 } 00308 00309 void RTT_corba_COperationInterface_i::checkOperation ( 00310 const char * operation, 00311 const ::RTT::corba::CAnyArguments & args) 00312 { 00313 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00314 throw ::RTT::corba::CNoSuchNameException( operation ); 00315 try { 00316 OperationInterfacePart* mofp = mfact->getPart(operation); 00317 OperationCallerC mc(mofp, operation, 0); 00318 for (unsigned int i = 0; i < mofp->arity() && i < args.length(); ++i) { 00319 const TypeInfo* ti = mofp->getArgumentType(i+1); 00320 assert(ti); 00321 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (ti->getProtocol(ORO_CORBA_PROTOCOL_ID)); 00322 if (ctt) { 00323 DataSourceBase::shared_ptr ds = ctt->createDataSource(&args[i]); 00324 if (ds) 00325 mc.arg(ds); 00326 else { 00327 log(Error) << "Registered transport for type "<< ti->getTypeName() 00328 << " could not create data source from Any (argument "<< i+1 00329 <<"): calling operation '"<< operation <<"' will fail." <<endlog(); 00330 } 00331 } else { 00332 throw wrong_types_of_args_exception(i+1,"type known to CORBA", ti->getTypeName()); 00333 } 00334 } 00335 mc.check(); 00336 } catch (no_asynchronous_operation_exception& ) { 00337 throw ::RTT::corba::CNoSuchNameException(operation); 00338 } catch (name_not_found_exception& nnf) { 00339 throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str()); 00340 } catch (wrong_number_of_args_exception& wna) { 00341 throw ::RTT::corba::CWrongNumbArgException(wna.wanted, wna.received); 00342 } catch (wrong_types_of_args_exception& wta) { 00343 throw ::RTT::corba::CWrongTypeArgException(wta.whicharg, wta.expected_.c_str(), wta.received_.c_str()); 00344 } 00345 } 00346 00347 ::CORBA::Any * RTT_corba_COperationInterface_i::callOperation ( 00348 const char * operation, 00349 ::RTT::corba::CAnyArguments & args) 00350 { 00351 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00352 throw ::RTT::corba::CNoSuchNameException( operation ); 00353 // convert Corba args to C++ args. 00354 try { 00355 OperationCallerC orig(mfact->getPart(operation), operation, 0); 00356 vector<DataSourceBase::shared_ptr> results; 00357 for (size_t i =0; i != args.length(); ++i) { 00358 const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1); 00359 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); 00360 // we need to store the results for returning them to caller (args is inout!) after the call() 00361 results.push_back( ctt->createDataSource( &args[i] ) ); 00362 orig.arg( results[i] ); 00363 } 00364 if ( orig.ready() ) { 00365 DataSourceBase::shared_ptr ds = orig.getCallDataSource(); 00366 CORBA::Any* retany; 00367 00368 // Try to get the return result : 00369 const TypeInfo* ti = ds->getTypeInfo(); 00370 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); 00371 if ( !ctt ) { 00372 log(Warning) << "Could not return results of call to " << operation << ": unknown return type by CORBA transport."<<endlog(); 00373 ds->evaluate(); // equivalent to orig.call() 00374 retany = new CORBA::Any(); 00375 } else { 00376 retany = ctt->createAny( ds ); // call evaluate internally 00377 } 00378 00379 // Return results into args: 00380 for (size_t i =0; i != args.length(); ++i) { 00381 const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1); 00382 CorbaTypeTransporter* ctta = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); 00383 ctta->updateAny(results[i], args[i]); 00384 } 00385 return retany; 00386 } else { 00387 orig.check(); // will throw 00388 } 00389 } catch (no_asynchronous_operation_exception& ) { 00390 throw ::RTT::corba::CNoSuchNameException( operation ); 00391 } catch ( name_not_found_exception& ) { 00392 throw ::RTT::corba::CNoSuchNameException( operation ); 00393 } catch ( wrong_number_of_args_exception& wna ) { 00394 throw ::RTT::corba::CWrongNumbArgException( wna.wanted, wna.received ); 00395 } catch (wrong_types_of_args_exception& wta ) { 00396 throw ::RTT::corba::CWrongTypeArgException( wta.whicharg, wta.expected_.c_str(), wta.received_.c_str() ); 00397 } 00398 return new ::CORBA::Any(); 00399 } 00400 00401 ::RTT::corba::CSendHandle_ptr RTT_corba_COperationInterface_i::sendOperation ( 00402 const char * operation, 00403 const ::RTT::corba::CAnyArguments & args) 00404 { 00405 // This implementation is 90% identical to callOperation above, only deviating in the orig.ready() part. 00406 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00407 throw ::RTT::corba::CNoSuchNameException( operation ); 00408 // convert Corba args to C++ args. 00409 try { 00410 OperationCallerC orig(mfact->getPart(operation), operation, 0); 00411 for (size_t i =0; i != args.length(); ++i) { 00412 const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1); 00413 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); 00414 orig.arg( ctt->createDataSource( &args[i] )); 00415 } 00416 if ( orig.ready() ) { 00417 SendHandleC resulthandle = orig.send(); 00418 // we may not destroy the SendHandle, before the operation completes: 00419 resulthandle.setAutoCollect(true); 00420 // our resulthandle copy makes sure that the resulthandle can return. 00421 RTT_corba_CSendHandle_i* ret_i = new RTT_corba_CSendHandle_i( resulthandle, mfact->getPart(operation) ); 00422 CSendHandle_var ret = ret_i->_this(); 00423 ret_i->_remove_ref(); // if POA drops this, it gets cleaned up. 00424 return ret._retn(); 00425 } else { 00426 orig.check(); // will throw 00427 } 00428 } catch (no_asynchronous_operation_exception& ) { 00429 throw ::RTT::corba::CNoSuchNameException( operation ); 00430 } catch ( name_not_found_exception& ) { 00431 throw ::RTT::corba::CNoSuchNameException( operation ); 00432 } catch ( wrong_number_of_args_exception& wna ) { 00433 throw ::RTT::corba::CWrongNumbArgException( wna.wanted, wna.received ); 00434 } catch (wrong_types_of_args_exception& wta ) { 00435 throw ::RTT::corba::CWrongTypeArgException( wta.whicharg, wta.expected_.c_str(), wta.received_.c_str() ); 00436 } 00437 return CSendHandle::_nil(); 00438 }