SendStatus get() const { try { // only try to collect if we didn't do so before: if ( mss != SendSuccess ) { corba::CAnyArguments_var nargs; if ( misblocking->get() ) { mss = SendStatus( static_cast<int>(msh->collect( nargs.out() ) ) - 1 ); } else { mss = SendStatus( static_cast<int>(msh->collectIfDone( nargs.out() ) ) - 1 ); } // only convert results when we got a success: if (mss == SendSuccess) { assert( nargs->length() == margs.size() ); for (size_t i=0; i < margs.size(); ++i ) { const types::TypeInfo* ti = margs[i]->getTypeInfo(); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); assert( ctt ); ctt->updateFromAny( &nargs[i], margs[i] ); } } } return mss; } catch ( corba::CWrongNumbArgException& ) { return mss; } catch ( corba::CWrongTypeArgException& ) { return mss; } }
base::DataSourceBase::shared_ptr CorbaOperationCallerFactory::produceCollect(const std::vector<base::DataSourceBase::shared_ptr>& args, internal::DataSource<bool>::shared_ptr blocking) const { unsigned int expected = mfact->getCollectArity(method.c_str()); if (args.size() != expected + 1) { throw wrong_number_of_args_exception( expected + 1, args.size() ); } // isolate and check CSendHandle std::vector<base::DataSourceBase::shared_ptr> cargs( ++args.begin(), args.end() ); DataSource<CSendHandle_var>::shared_ptr ds = DataSource<CSendHandle_var>::narrow( args.begin()->get() ); if (!ds) { throw wrong_types_of_args_exception(0,"CSendHandle_var",(*args.begin())->getTypeName() ); } // check if args matches what CSendHandle expects. try { corba::CAnyArguments_var nargs = new corba::CAnyArguments(); nargs->length( cargs.size() ); for (size_t i=0; i < cargs.size(); ++i ) { const types::TypeInfo* ti = cargs[i]->getTypeInfo(); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); assert( ctt ); DataSourceBase::shared_ptr tryout = ti->buildValue(); ctt->updateAny(tryout, nargs[i]); } ds->get()->checkArguments( nargs.in() ); } catch ( CWrongNumbArgException& wna) { throw wrong_number_of_args_exception(wna.wanted, wna.received); } catch ( CWrongTypeArgException& wta) { throw wrong_types_of_args_exception(wta.whicharg,wta.expected.in(), wta.received.in()); } // All went well, produce collect DataSource: return new CorbaOperationCallerCollect( ds->get().in(),cargs, blocking); }
bool execute() { try { if (mdocall) { CORBA::Any_var any = mfact->callOperation( mop.c_str(), nargs.inout() ); for (size_t i=0; i < margs.size(); ++i ) { const types::TypeInfo* ti = margs[i]->getTypeInfo(); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); assert( ctt ); ctt->updateFromAny( &nargs[i], margs[i] ); } // convert returned any to local type: if (mctt) return mctt->updateFromAny(&any.in(), mresult); } else { CSendHandle_var sh = mfact->sendOperation( mop.c_str(), nargs.in() ); AssignableDataSource<CSendHandle_var>::shared_ptr ads = AssignableDataSource<CSendHandle_var>::narrow( mresult.get() ); if (ads) { ads->set( sh ); // _var creates a copy of the obj reference. } } return true; } catch ( corba::CNoSuchNameException& ) { return false; } catch ( corba::CWrongNumbArgException& ) { return false; } catch ( corba::CWrongTypeArgException& ) { return false; } }
base::DataSourceBase::shared_ptr CorbaOperationCallerFactory::produceSend(const std::vector<base::DataSourceBase::shared_ptr>& args, ExecutionEngine* caller) const { corba::CAnyArguments_var nargs = new corba::CAnyArguments(); nargs->length( args.size() ); for (size_t i=0; i < args.size(); ++i ) { const types::TypeInfo* ti = args[i]->getTypeInfo(); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); if (!ctt) throw wrong_types_of_args_exception(i+1,"type known to CORBA transport", ti->getTypeName()); DataSourceBase::shared_ptr tryout = ti->buildValue(); ctt->updateAny(tryout, nargs[i]); } try { // will throw if wrong args. mfact->checkOperation(method.c_str(), nargs.inout() ); // Will return a CSendHandle_var: DataSource<CSendHandle_var>::shared_ptr result = new ValueDataSource<CSendHandle_var>(); return new ActionAliasDataSource<CSendHandle_var>(new CorbaOperationCallerCall(mfact.in(),method,args,caller, 0, result, false), result.get() ); } catch ( corba::CNoSuchNameException& nsn ) { throw name_not_found_exception( nsn.name.in() ); } catch ( corba::CWrongNumbArgException& wa ) { throw wrong_number_of_args_exception( wa.wanted, wa.received ); } catch ( corba::CWrongTypeArgException& wta ) { throw wrong_types_of_args_exception( wta.whicharg, wta.expected.in(), wta.received.in() ); } return 0; // not reached. }
/** * Helper function to convert a vector of data sources to a sequence of anys. * @param sources * @param anys * @return */ bool sourcevector_to_anysequence( vector<DataSourceBase::shared_ptr> const& sources, CAnyArguments & anys ) { bool valid = true; anys.length( sources.size() ); for(unsigned int i = 0; i != sources.size(); ++i) { const TypeInfo* ti = sources[i]->getTypeInfo(); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); ctt->updateAny(sources[i], anys[i]); } return valid; }
::CORBA::Any * RTT_corba_CConfigurationInterface_i::getAttribute ( const char * name) { if ( !mar || !mar->hasAttribute( string(name) ) ) return new CORBA::Any(); DataSourceBase::shared_ptr ds = mar->getValue( string(name) )->getDataSource(); const TypeInfo* ti = ds->getTypeInfo(); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); assert( ctt ); return ctt->createAny( ds ); }
void readArguments() { // We need to delay reading the arguments upto this point such that the args contain // the latest values. nargs = new corba::CAnyArguments(); nargs->length( margs.size() ); for (size_t i=0; i < margs.size(); ++i ) { const types::TypeInfo* ti = margs[i]->getTypeInfo(); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); assert( ctt ); ctt->updateAny(margs[i], nargs[i]); } }
::CORBA::Boolean RTT_corba_CConfigurationInterface_i::setProperty ( const char * name, const ::CORBA::Any & value) { if (mar) mbag = mar->properties(); // leave this here to get latest propertybag. DataSourceBase::shared_ptr ds = getPropertyDataSource(name); if ( !ds ) return 0; const TypeInfo* ti = ds->getTypeInfo(); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); assert( ctt ); return ctt->updateFromAny( &value, ds ); }
::CORBA::Any * RTT_corba_CSendHandle_i::ret ( void) { SendStatus ss = mhandle.collectIfDone(); // We just copy over the first collectable argument. In // case of a void operation, we will thus return the first // reference argument. if (ss == SendSuccess) { if ( cargs.size() > 0) { CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (cargs[0]->getTypeInfo()->getProtocol(ORO_CORBA_PROTOCOL_ID)); return ctt->createAny( cargs[0] ); } } return new CORBA::Any(); }
base::DataSourceBase::shared_ptr CorbaOperationCallerFactory::produce(const std::vector<base::DataSourceBase::shared_ptr>& args, ExecutionEngine* caller) const { corba::CAnyArguments_var nargs = new corba::CAnyArguments(); nargs->length( args.size() ); // this part is only done to feed to checkOperation() with some defaults. // We don't want to evaluate() the *real* data sources yet ! for (size_t i=0; i < args.size(); ++i ) { const types::TypeInfo* ti = args[i]->getTypeInfo(); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); if (!ctt) throw wrong_types_of_args_exception(i+1,"type known to CORBA transport", ti->getTypeName()); DataSourceBase::shared_ptr tryout = ti->buildValue(); ctt->updateAny(tryout, nargs[i]); } // check argument types and produce: try { // will throw if wrong args. mfact->checkOperation(method.c_str(), nargs.in() ); // convert returned any to local type: const types::TypeInfo* ti = this->getArgumentType(0); if ( ti ) { if ( ti != Types()->type("void") ) { // create a method call object and a return value and let the former store results in the latter. CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); DataSourceBase::shared_ptr result = ti->buildValue(); // evaluate()/get() will cause the method to be called and remote return value will end up in result. return ti->buildActionAlias(new CorbaOperationCallerCall(mfact.in(),method,args,caller, ctt, result, true), result ); } else { return new DataSourceCommand( new CorbaOperationCallerCall(mfact.in(),method,args,caller, 0, DataSourceBase::shared_ptr() , true) ); } } else { // it's returning a type we don't know ! Return a DataSource<Any> DataSource<CORBA::Any_var>::shared_ptr result = new AnyDataSource( new CORBA::Any() ); // todo Provide a ctt implementation for 'CORBA::Any_var' such that the result is updated ! // The result is only for dummy reasons used now, since no ctt is set, no updating will be done. return new ActionAliasDataSource<CORBA::Any_var>(new CorbaOperationCallerCall(mfact.in(),method,args,caller, 0, result, true), result.get() ); } } catch ( corba::CNoSuchNameException& nsn ) { throw name_not_found_exception( nsn.name.in() ); } catch ( corba::CWrongNumbArgException& wa ) { throw wrong_number_of_args_exception( wa.wanted, wa.received ); } catch ( corba::CWrongTypeArgException& wta ) { throw wrong_types_of_args_exception( wta.whicharg, wta.expected.in(), wta.received.in() ); } return 0; // not reached. }
::CORBA::Any * RTT_corba_CConfigurationInterface_i::getProperty ( const char * name) { if (mar) mbag = mar->properties(); // leave this here to get latest propertybag. if ( mbag == 0 ) return new CORBA::Any(); DataSourceBase::shared_ptr ds = getPropertyDataSource(name); if ( !ds ) { log(Error) <<"CConfigurationInterface: no such property: " << name << ". Returning empty CORBA::Any."<<endlog(); return new CORBA::Any(); } const TypeInfo* ti = ds->getTypeInfo(); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*>( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); assert( ctt ); return ctt->createAny( ds ); }
void RTT_corba_CSendHandle_i::checkArguments ( const ::RTT::corba::CAnyArguments & args) { try { SendHandleC shc(morig); for (unsigned int i = 0; i != mofp->collectArity(); ++i) { const TypeInfo* ti = mofp->getCollectType(i + 1); assert(ti); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (ti->getProtocol(ORO_CORBA_PROTOCOL_ID)); shc.arg(ctt->createDataSource(&args[i])); } shc.check(); } catch (name_not_found_exception& nnf) { throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str()); } catch (wrong_number_of_args_exception& wna) { throw ::RTT::corba::CWrongNumbArgException(wna.wanted, wna.received); } catch (wrong_types_of_args_exception& wta) { throw ::RTT::corba::CWrongTypeArgException(wta.whicharg, wta.expected_.c_str(), wta.received_.c_str()); } }
void RTT_corba_COperationInterface_i::checkOperation ( const char * operation, const ::RTT::corba::CAnyArguments & args) { if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) throw ::RTT::corba::CNoSuchNameException( operation ); try { OperationInterfacePart* mofp = mfact->getPart(operation); OperationCallerC mc(mofp, operation, 0); for (unsigned int i = 0; i < mofp->arity() && i < args.length(); ++i) { const TypeInfo* ti = mofp->getArgumentType(i+1); assert(ti); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (ti->getProtocol(ORO_CORBA_PROTOCOL_ID)); if (ctt) { DataSourceBase::shared_ptr ds = ctt->createDataSource(&args[i]); if (ds) mc.arg(ds); else { log(Error) << "Registered transport for type "<< ti->getTypeName() << " could not create data source from Any (argument "<< i+1 <<"): calling operation '"<< operation <<"' will fail." <<endlog(); } } else { throw wrong_types_of_args_exception(i+1,"type known to CORBA", ti->getTypeName()); } } mc.check(); } catch (no_asynchronous_operation_exception& ) { throw ::RTT::corba::CNoSuchNameException(operation); } catch (name_not_found_exception& nnf) { throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str()); } catch (wrong_number_of_args_exception& wna) { throw ::RTT::corba::CWrongNumbArgException(wna.wanted, wna.received); } catch (wrong_types_of_args_exception& wta) { throw ::RTT::corba::CWrongTypeArgException(wta.whicharg, wta.expected_.c_str(), wta.received_.c_str()); } }
::RTT::corba::CSendHandle_ptr RTT_corba_COperationInterface_i::sendOperation ( const char * operation, const ::RTT::corba::CAnyArguments & args) { // This implementation is 90% identical to callOperation above, only deviating in the orig.ready() part. if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) throw ::RTT::corba::CNoSuchNameException( operation ); // convert Corba args to C++ args. try { OperationCallerC orig(mfact->getPart(operation), operation, 0); for (size_t i =0; i != args.length(); ++i) { const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); orig.arg( ctt->createDataSource( &args[i] )); } if ( orig.ready() ) { SendHandleC resulthandle = orig.send(); // we may not destroy the SendHandle, before the operation completes: resulthandle.setAutoCollect(true); RTT_corba_CSendHandle_i* ret_i = new RTT_corba_CSendHandle_i( resulthandle, mfact->getPart(operation) ); CSendHandle_var ret = ret_i->_this(); return ret._retn(); } else { orig.check(); // will throw } } catch (no_asynchronous_operation_exception& ) { throw ::RTT::corba::CNoSuchNameException( operation ); } catch ( name_not_found_exception& ) { throw ::RTT::corba::CNoSuchNameException( operation ); } catch ( wrong_number_of_args_exception& wna ) { throw ::RTT::corba::CWrongNumbArgException( wna.wanted, wna.received ); } catch (wrong_types_of_args_exception& wta ) { throw ::RTT::corba::CWrongTypeArgException( wta.whicharg, wta.expected_.c_str(), wta.received_.c_str() ); } return CSendHandle::_nil(); }
::CORBA::Any * RTT_corba_COperationInterface_i::callOperation ( const char * operation, ::RTT::corba::CAnyArguments & args) { if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) ) throw ::RTT::corba::CNoSuchNameException( operation ); // convert Corba args to C++ args. try { OperationCallerC orig(mfact->getPart(operation), operation, 0); vector<DataSourceBase::shared_ptr> results; for (size_t i =0; i != args.length(); ++i) { const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); // we need to store the results for returning them to caller (args is inout!) after the call() results.push_back( ctt->createDataSource( &args[i] ) ); orig.arg( results[i] ); } if ( orig.ready() ) { DataSourceBase::shared_ptr ds = orig.getCallDataSource(); CORBA::Any* retany; // Try to get the return result : const TypeInfo* ti = ds->getTypeInfo(); CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); if ( !ctt ) { log(Warning) << "Could not return results of call to " << operation << ": unknown return type by CORBA transport."<<endlog(); ds->evaluate(); // equivalent to orig.call() retany = new CORBA::Any(); } else { retany = ctt->createAny( ds ); // call evaluate internally } // Return results into args: for (size_t i =0; i != args.length(); ++i) { const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1); CorbaTypeTransporter* ctta = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) ); ctta->updateAny(results[i], args[i]); } return retany; } else { orig.check(); // will throw } } catch (no_asynchronous_operation_exception& ) { throw ::RTT::corba::CNoSuchNameException( operation ); } catch ( name_not_found_exception& ) { throw ::RTT::corba::CNoSuchNameException( operation ); } catch ( wrong_number_of_args_exception& wna ) { throw ::RTT::corba::CWrongNumbArgException( wna.wanted, wna.received ); } catch (wrong_types_of_args_exception& wta ) { throw ::RTT::corba::CWrongTypeArgException( wta.whicharg, wta.expected_.c_str(), wta.received_.c_str() ); } return new ::CORBA::Any(); }