Orocos Real-Time Toolkit
2.5.0
|
00001 /*************************************************************************** 00002 tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 TypeInfo.cpp 00003 00004 TypeInfo.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 #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 // cleanup transporters 00071 for (Transporters::iterator i = transporters.begin(); i != transporters.end(); ++i) 00072 delete *i; 00073 00074 // cleanup constructors 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 // build default constructible: 00084 if ( args.empty() ) { 00085 AttributeBase* ab = this->buildVariable("constructor"); 00086 ds = ab->getDataSource(); 00087 delete ab; 00088 return ds; 00089 } 00090 00091 // return same type if equal: 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 // returns empty data source to indicate not constructible 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 //log(Info) << getTypeName() << ": trying to convert from " << arg->getTypeName()<<endlog(); 00117 while (i != constructors.end() ) { 00118 ds = (*i)->convert( arg ); 00119 if ( ds ) { 00120 return ds; 00121 } 00122 ++i; 00123 } 00124 // if no conversion happend, return arg again. 00125 return arg; 00126 } 00127 00128 base::DataSourceBase::shared_ptr TypeInfo::decomposeType(base::DataSourceBase::shared_ptr source) const 00129 { 00130 // return deprecated api in case user did not implement this. 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 // if the protocol is unknown to this type, return the protocol of the 'unknown type' 00175 // type, which is a fallback such that we won't have to return zero, but can 00176 // gracefully fall-back. 00177 // In order to not endlessly recurse, we check if we aren't the UnknownType ! 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; // That transport did not register a fall-back ! 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(); // prevents deletion. 00195 } 00196 00197 bool TypeInfo::hasProtocol(int protocol_id) const 00198 { 00199 // if the protocol is unknown to this type, return the protocol of the 'unknown type' 00200 // type, which is a fallback such that we won't have to return zero, but can 00201 // gracefully fall-back. 00202 // In order to not endlessly recurse, we check if we aren't the UnknownType ! 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 // dump only protocols with an actual transporter 00215 // NB the transporter does not have a name, so you have to manually 00216 // match the protocol number to an actual transport 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 }