Orocos Real-Time Toolkit
2.6.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 try { 00130 SendStatus ss = mhandle.collect(); 00131 args = new CAnyArguments(); 00132 if (ss == SendSuccess) { 00133 sourcevector_to_anysequence( cargs, *args.ptr() ); 00134 } 00135 return CSendStatus(static_cast<int>(ss) + 1); 00136 } catch(std::runtime_error& e) { 00137 throw ::RTT::corba::CCallError(e.what()); 00138 } 00139 } 00140 00141 ::RTT::corba::CSendStatus RTT_corba_CSendHandle_i::collectIfDone ( 00142 ::RTT::corba::CAnyArguments_out args) 00143 { 00144 try { 00145 SendStatus ss = mhandle.collectIfDone(); 00146 args = new CAnyArguments(); 00147 if (ss == SendSuccess) { 00148 sourcevector_to_anysequence( cargs, *args.ptr() ); 00149 } 00150 return CSendStatus(static_cast<int>(ss) + 1); 00151 } catch(std::runtime_error& e) { 00152 throw ::RTT::corba::CCallError(e.what()); 00153 } 00154 } 00155 00156 ::RTT::corba::CSendStatus RTT_corba_CSendHandle_i::checkStatus ( 00157 void) 00158 { 00159 return CSendStatus( static_cast<int>(mhandle.collectIfDone()) + 1 ); 00160 } 00161 00162 ::CORBA::Any * RTT_corba_CSendHandle_i::ret ( 00163 void) 00164 { 00165 try { 00166 SendStatus ss = mhandle.collectIfDone(); 00167 // We just copy over the first collectable argument. In 00168 // case of a void operation, we will thus return the first 00169 // reference argument. 00170 if (ss == SendSuccess) { 00171 if ( cargs.size() > 0) { 00172 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (cargs[0]->getTypeInfo()->getProtocol(ORO_CORBA_PROTOCOL_ID)); 00173 return ctt->createAny( cargs[0] ); 00174 } 00175 } 00176 return new CORBA::Any(); 00177 } catch(std::runtime_error& e) { 00178 throw ::RTT::corba::CCallError(e.what()); 00179 } 00180 } 00181 00182 void RTT_corba_CSendHandle_i::checkArguments ( 00183 const ::RTT::corba::CAnyArguments & args) 00184 { 00185 try { 00186 SendHandleC shc(morig); 00187 for (unsigned int i = 0; i != mofp->collectArity(); ++i) { 00188 const TypeInfo* ti = mofp->getCollectType(i + 1); 00189 assert(ti); 00190 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (ti->getProtocol(ORO_CORBA_PROTOCOL_ID)); 00191 shc.arg(ctt->createDataSource(&args[i])); 00192 } 00193 // otherwise, we would block !!! 00194 shc.setAutoCollect(false); 00195 shc.check(); 00196 } catch (name_not_found_exception& nnf) { 00197 throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str()); 00198 } catch (wrong_number_of_args_exception& wna) { 00199 throw ::RTT::corba::CWrongNumbArgException(wna.wanted, wna.received); 00200 } catch (wrong_types_of_args_exception& wta) { 00201 throw ::RTT::corba::CWrongTypeArgException(wta.whicharg, wta.expected_.c_str(), wta.received_.c_str()); 00202 } 00203 } 00204 00205 void RTT_corba_CSendHandle_i::dispose ( 00206 void) 00207 { 00208 PortableServer::POA_var mPOA = _default_POA(); 00209 PortableServer::ObjectId_var oid = mPOA->servant_to_id(this); 00210 mPOA->deactivate_object( oid.in() ); 00211 return; 00212 } 00213 00214 // Implementation skeleton constructor 00215 RTT_corba_COperationInterface_i::RTT_corba_COperationInterface_i (OperationInterface* gmf, PortableServer::POA_ptr the_poa) 00216 :mfact(gmf), mpoa( PortableServer::POA::_duplicate(the_poa)) 00217 { 00218 } 00219 00220 PortableServer::POA_ptr RTT_corba_COperationInterface_i::_default_POA() 00221 { 00222 return PortableServer::POA::_duplicate(mpoa); 00223 } 00224 00225 00226 // Implementation skeleton destructor 00227 RTT_corba_COperationInterface_i::~RTT_corba_COperationInterface_i (void) 00228 { 00229 } 00230 00231 ::RTT::corba::COperationInterface::COperationList * RTT_corba_COperationInterface_i::getOperations ( 00232 void) 00233 { 00234 RTT::corba::COperationInterface::COperationList_var rlist = new RTT::corba::COperationInterface::COperationList(); 00235 00236 vector<string> flist = mfact->getNames(); 00237 rlist->length( flist.size() ); 00238 size_t drops=0; 00239 for (size_t i=0; i != flist.size(); ++i) 00240 if ( !mfact->isSynchronous(flist[i]) ) { 00241 rlist[i - drops] = CORBA::string_dup( flist[i].c_str() ); 00242 } else { 00243 ++drops; 00244 } 00245 rlist->length( flist.size() - drops); // we don't show the synchronous operations. 00246 return rlist._retn(); 00247 } 00248 00249 ::RTT::corba::CDescriptions * RTT_corba_COperationInterface_i::getArguments ( 00250 const char * operation) 00251 { 00252 CDescriptions_var ret = new CDescriptions(); 00253 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation))) 00254 throw ::RTT::corba::CNoSuchNameException( operation ); 00255 // operation found, convert args: 00256 OperationInterface::Descriptions args = mfact->getArgumentList( string(operation) ); 00257 ret->length( args.size() ); 00258 for (size_t i =0; i != args.size(); ++i) { 00259 ret[i].name = CORBA::string_dup( args[i].name.c_str() ); 00260 ret[i].description = CORBA::string_dup( args[i].description.c_str() ); 00261 ret[i].type = CORBA::string_dup( args[i].type.c_str() ); 00262 } 00263 return ret._retn(); 00264 } 00265 00266 char * RTT_corba_COperationInterface_i::getResultType ( 00267 const char * operation) 00268 { 00269 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00270 throw ::RTT::corba::CNoSuchNameException( operation ); 00271 return CORBA::string_dup( mfact->getResultType( string(operation) ).c_str() ); 00272 } 00273 00274 char* RTT_corba_COperationInterface_i::getArgumentType( 00275 const char* operation, 00276 CORBA::UShort nbr) 00277 { 00278 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00279 throw ::RTT::corba::CNoSuchNameException( operation ); 00280 if ( nbr > mfact->getPart(operation)->arity() ) 00281 throw ::RTT::corba::CWrongArgumentException( nbr, mfact->getPart(operation)->arity() ); 00282 return CORBA::string_dup( mfact->getPart( operation )->getArgumentType(nbr)->getTypeName().c_str() ); 00283 } 00284 00285 char* RTT_corba_COperationInterface_i::getCollectType( 00286 const char* operation, 00287 CORBA::UShort nbr) 00288 { 00289 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00290 throw ::RTT::corba::CNoSuchNameException( operation ); 00291 if ( nbr > mfact->getPart(operation)->collectArity() ) 00292 throw ::RTT::corba::CWrongArgumentException( nbr, mfact->getPart(operation)->collectArity() ); 00293 return CORBA::string_dup( mfact->getPart( operation )->getCollectType(nbr)->getTypeName().c_str() ); 00294 00295 } 00296 00297 ::CORBA::UShort RTT_corba_COperationInterface_i::getArity ( 00298 const char * operation) 00299 { 00300 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00301 throw ::RTT::corba::CNoSuchNameException( operation ); 00302 return mfact->getPart(operation)->arity(); 00303 } 00304 00305 ::CORBA::UShort RTT_corba_COperationInterface_i::getCollectArity ( 00306 const char * operation) 00307 { 00308 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00309 throw ::RTT::corba::CNoSuchNameException( operation ); 00310 return mfact->getPart(operation)->collectArity(); 00311 } 00312 00313 char * RTT_corba_COperationInterface_i::getDescription ( 00314 const char * operation) 00315 { 00316 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00317 throw ::RTT::corba::CNoSuchNameException( operation ); 00318 return CORBA::string_dup( mfact->getDescription( string(operation) ).c_str() ); 00319 } 00320 00321 void RTT_corba_COperationInterface_i::checkOperation ( 00322 const char * operation, 00323 const ::RTT::corba::CAnyArguments & args) 00324 { 00325 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00326 throw ::RTT::corba::CNoSuchNameException( operation ); 00327 try { 00328 OperationInterfacePart* mofp = mfact->getPart(operation); 00329 OperationCallerC mc(mofp, operation, 0); 00330 for (unsigned int i = 0; i < mofp->arity() && i < args.length(); ++i) { 00331 const TypeInfo* ti = mofp->getArgumentType(i+1); 00332 assert(ti); 00333 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (ti->getProtocol(ORO_CORBA_PROTOCOL_ID)); 00334 if (ctt) { 00335 DataSourceBase::shared_ptr ds = ctt->createDataSource(&args[i]); 00336 if (ds) 00337 mc.arg(ds); 00338 else { 00339 log(Error) << "Registered transport for type "<< ti->getTypeName() 00340 << " could not create data source from Any (argument "<< i+1 00341 <<"): calling operation '"<< operation <<"' will fail." <<endlog(); 00342 } 00343 } else { 00344 throw wrong_types_of_args_exception(i+1,"type known to CORBA", ti->getTypeName()); 00345 } 00346 } 00347 mc.check(); 00348 } catch (no_asynchronous_operation_exception& ) { 00349 throw ::RTT::corba::CNoSuchNameException(operation); 00350 } catch (name_not_found_exception& nnf) { 00351 throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str()); 00352 } catch (wrong_number_of_args_exception& wna) { 00353 throw ::RTT::corba::CWrongNumbArgException(wna.wanted, wna.received); 00354 } catch (wrong_types_of_args_exception& wta) { 00355 throw ::RTT::corba::CWrongTypeArgException(wta.whicharg, wta.expected_.c_str(), wta.received_.c_str()); 00356 } 00357 } 00358 00359 ::CORBA::Any * RTT_corba_COperationInterface_i::callOperation ( 00360 const char * operation, 00361 ::RTT::corba::CAnyArguments & args) 00362 { 00363 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00364 throw ::RTT::corba::CNoSuchNameException( operation ); 00365 // convert Corba args to C++ args. 00366 try { 00367 OperationCallerC orig(mfact->getPart(operation), operation, 0); 00368 vector<DataSourceBase::shared_ptr> results; 00369 for (size_t i =0; i != args.length(); ++i) { 00370 const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1); 00371 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); 00372 // we need to store the results for returning them to caller (args is inout!) after the call() 00373 results.push_back( ctt->createDataSource( &args[i] ) ); 00374 orig.arg( results[i] ); 00375 } 00376 if ( orig.ready() ) { 00377 DataSourceBase::shared_ptr ds = orig.getCallDataSource(); 00378 CORBA::Any* retany; 00379 00380 // Try to get the return result : 00381 const TypeInfo* ti = ds->getTypeInfo(); 00382 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); 00383 if ( !ctt ) { 00384 log(Warning) << "Could not return results of call to " << operation << ": unknown return type by CORBA transport."<<endlog(); 00385 ds->evaluate(); // equivalent to orig.call() 00386 retany = new CORBA::Any(); 00387 } else { 00388 retany = ctt->createAny( ds ); // call evaluate internally 00389 } 00390 00391 // Return results into args: 00392 for (size_t i =0; i != args.length(); ++i) { 00393 const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1); 00394 CorbaTypeTransporter* ctta = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); 00395 ctta->updateAny(results[i], args[i]); 00396 } 00397 return retany; 00398 } else { 00399 orig.check(); // will throw 00400 } 00401 } catch (no_asynchronous_operation_exception& ) { 00402 throw ::RTT::corba::CNoSuchNameException( operation ); 00403 } catch ( name_not_found_exception& ) { 00404 throw ::RTT::corba::CNoSuchNameException( operation ); 00405 } catch ( wrong_number_of_args_exception& wna ) { 00406 throw ::RTT::corba::CWrongNumbArgException( wna.wanted, wna.received ); 00407 } catch (wrong_types_of_args_exception& wta ) { 00408 throw ::RTT::corba::CWrongTypeArgException( wta.whicharg, wta.expected_.c_str(), wta.received_.c_str() ); 00409 } catch (std::runtime_error& e){ 00410 throw ::RTT::corba::CCallError(e.what()); 00411 } 00412 return new ::CORBA::Any(); 00413 } 00414 00415 ::RTT::corba::CSendHandle_ptr RTT_corba_COperationInterface_i::sendOperation ( 00416 const char * operation, 00417 const ::RTT::corba::CAnyArguments & args) 00418 { 00419 // This implementation is 90% identical to callOperation above, only deviating in the orig.ready() part. 00420 if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) 00421 throw ::RTT::corba::CNoSuchNameException( operation ); 00422 // convert Corba args to C++ args. 00423 try { 00424 OperationCallerC orig(mfact->getPart(operation), operation, 0); 00425 for (size_t i =0; i != args.length(); ++i) { 00426 const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1); 00427 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); 00428 orig.arg( ctt->createDataSource( &args[i] )); 00429 } 00430 if ( orig.ready() ) { 00431 SendHandleC resulthandle = orig.send(); 00432 // we may not destroy the SendHandle, before the operation completes: 00433 resulthandle.setAutoCollect(true); 00434 // our resulthandle copy makes sure that the resulthandle can return. 00435 RTT_corba_CSendHandle_i* ret_i = new RTT_corba_CSendHandle_i( resulthandle, mfact->getPart(operation) ); 00436 CSendHandle_var ret = ret_i->_this(); 00437 ret_i->_remove_ref(); // if POA drops this, it gets cleaned up. 00438 return ret._retn(); 00439 } else { 00440 orig.check(); // will throw 00441 } 00442 } catch (no_asynchronous_operation_exception& ) { 00443 throw ::RTT::corba::CNoSuchNameException( operation ); 00444 } catch ( name_not_found_exception& ) { 00445 throw ::RTT::corba::CNoSuchNameException( operation ); 00446 } catch ( wrong_number_of_args_exception& wna ) { 00447 throw ::RTT::corba::CWrongNumbArgException( wna.wanted, wna.received ); 00448 } catch (wrong_types_of_args_exception& wta ) { 00449 throw ::RTT::corba::CWrongTypeArgException( wta.whicharg, wta.expected_.c_str(), wta.received_.c_str() ); 00450 } 00451 return CSendHandle::_nil(); 00452 }