00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "TypeInfo.hpp"
00040 #include "TypeBuilder.hpp"
00041 #include "../internal/DataSourceTypeInfo.hpp"
00042 #include "TypeTransporter.hpp"
00043
00044 #include "rtt-config.h"
00045
00046 #include "../Logger.hpp"
00047 #include "../base/AttributeBase.hpp"
00048
00049 #ifdef OS_HAVE_STREAMS
00050 #include <sstream>
00051 #endif
00052
00053 namespace RTT
00054 {
00055 using namespace std;
00056 using namespace detail;
00057 using namespace internal;
00058
00059 AttributeBase* TypeInfo::buildVariable(std::string name, int ) const {
00060 return this->buildVariable(name);
00061 }
00062
00063 AttributeBase* TypeInfo::buildConstant(std::string name,DataSourceBase::shared_ptr dsb, int ) const {
00064 return this->buildConstant(name, dsb );
00065 }
00066
00067
00068 TypeInfo::~TypeInfo()
00069 {
00070
00071 for (Transporters::iterator i = transporters.begin(); i != transporters.end(); ++i)
00072 delete *i;
00073
00074
00075 for (Constructors::iterator i= constructors.begin(); i != constructors.end(); ++i)
00076 delete (*i);
00077 }
00078
00079 DataSourceBase::shared_ptr TypeInfo::construct(const std::vector<DataSourceBase::shared_ptr>& args) const
00080 {
00081
00082 DataSourceBase::shared_ptr ds;
00083
00084 if ( args.empty() ) {
00085 AttributeBase* ab = this->buildVariable("constructor");
00086 ds = ab->getDataSource();
00087 delete ab;
00088 return ds;
00089 }
00090
00091
00092 if ( args.size() == 1 && args.front()->getTypeInfo() == this )
00093 return args.front();
00094
00095 Constructors::const_iterator i= constructors.begin();
00096 while (i != constructors.end() ) {
00097 ds = (*i)->build( args );
00098 if ( ds )
00099 return ds;
00100 ++i;
00101 }
00102
00103 return ds;
00104 }
00105
00106 void TypeInfo::addConstructor(TypeBuilder* tb) {
00107 constructors.push_back(tb);
00108 }
00109
00110 DataSourceBase::shared_ptr TypeInfo::convert(DataSourceBase::shared_ptr arg) const
00111 {
00112 DataSourceBase::shared_ptr ds;
00113 Constructors::const_iterator i= constructors.begin();
00114 if ( arg->getTypeInfo() == this )
00115 return arg;
00116
00117 while (i != constructors.end() ) {
00118 ds = (*i)->convert( arg );
00119 if ( ds ) {
00120 return ds;
00121 }
00122 ++i;
00123 }
00124
00125 return arg;
00126 }
00127
00128 base::DataSourceBase::shared_ptr TypeInfo::decomposeType(base::DataSourceBase::shared_ptr source) const
00129 {
00130
00131 return convertType(source);
00132 }
00133
00134 base::DataSourceBase::shared_ptr TypeInfo::convertType(base::DataSourceBase::shared_ptr source) const
00135 {
00136 return base::DataSourceBase::shared_ptr();
00137 }
00138
00139 bool TypeInfo::resize(base::DataSourceBase::shared_ptr arg, int size) const {
00140 return false;
00141 }
00142
00143 string TypeInfo::toString( DataSourceBase::shared_ptr in ) const
00144 {
00145 #ifdef OS_HAVE_STREAMS
00146 stringstream result;
00147 this->write( result, in );
00148 return result.str();
00149 #else
00150 return string("(") + in->getTypeInfo()->getTypeName() + ")";
00151 #endif
00152 }
00153
00154 bool TypeInfo::fromString( const std::string& value, DataSourceBase::shared_ptr out ) const
00155 {
00156 stringstream result(value);
00157 return this->read( result, out ).good();
00158 }
00159
00160 bool TypeInfo::addProtocol(int protocol_id, TypeTransporter* tt)
00161 {
00162 if (transporters.size() < static_cast<size_t>(protocol_id + 1))
00163 transporters.resize(protocol_id + 1);
00164 if ( transporters[protocol_id] ) {
00165 log(Error) << "A protocol with id "<<protocol_id<<" was already added for type "<< getTypeName()<<endlog();
00166 return false;
00167 }
00168 transporters[protocol_id] = tt;
00169 return true;
00170 }
00171
00172 TypeTransporter* TypeInfo::getProtocol(int protocol_id) const
00173 {
00174
00175
00176
00177
00178 if ( protocol_id + 1 > int(transporters.size()) || transporters[protocol_id] == 0) {
00179 if ( DataSourceTypeInfo<UnknownType>::getTypeInfo() != this )
00180 return DataSourceTypeInfo<UnknownType>::getTypeInfo()->getProtocol( protocol_id );
00181 else {
00182 log(Warning) << "The protocol with id "<<protocol_id<<" did not register a fall-back handler for unknown types!"<<endlog();
00183 log(Warning) << " triggered by: "<< getTypeName() << " which does not have a transport."<<endlog();
00184 return 0;
00185 }
00186 }
00187 return transporters[protocol_id];
00188 }
00189
00190 void TypeInfo::migrateProtocols(TypeInfo* orig)
00191 {
00192 assert( transporters.empty() );
00193 transporters.insert(transporters.begin(), orig->transporters.begin(), orig->transporters.end());
00194 orig->transporters.clear();
00195 }
00196
00197 bool TypeInfo::hasProtocol(int protocol_id) const
00198 {
00199
00200
00201
00202
00203 if ( protocol_id + 1 > int(transporters.size()) || transporters[protocol_id] == 0) {
00204 return false;
00205 }
00206 return true;
00207 }
00208
00209 std::vector<int> TypeInfo::getTransportNames() const
00210 {
00211 std::vector<int> ret;
00212 for (size_t i=0; i<transporters.size(); ++i)
00213 {
00214
00215
00216
00217 if (0 != transporters[i])
00218 {
00219 ret.push_back(i);
00220 }
00221 }
00222 return ret;
00223 }
00224
00225 vector<string> TypeInfo::getMemberNames() const
00226 {
00227 return vector<string>();
00228 }
00229
00230 DataSourceBase::shared_ptr TypeInfo::getMember(DataSourceBase::shared_ptr item, const std::string& part_name) const
00231 {
00245 log(Debug) <<"No parts registered for "<< getTypeName() <<endlog();
00246 if ( part_name.empty() )
00247 return item;
00248 else
00249 return DataSourceBase::shared_ptr();
00250 }
00251
00252 DataSourceBase::shared_ptr TypeInfo::getMember(DataSourceBase::shared_ptr item, DataSourceBase::shared_ptr id) const
00253 {
00267 log(Debug) <<"No parts registered for "<< getTypeName() <<endlog();
00268 return DataSourceBase::shared_ptr();
00269 }
00270 }