Go to the documentation of this file.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 #ifndef ORO_TEMPLATE_CARRAY_INFO_HPP
00040 #define ORO_TEMPLATE_CARRAY_INFO_HPP
00041
00042 #include "PrimitiveTypeInfo.hpp"
00043 #include "../internal/ArrayPartDataSource.hpp"
00044 #include <boost/lexical_cast.hpp>
00045 #include "carray.hpp"
00046 #include "../internal/carray.hpp"
00047 #include "PropertyComposition.hpp"
00048 #include "PropertyDecomposition.hpp"
00049
00050 namespace RTT
00051 {
00052 namespace types
00053 {
00062 template<typename T, bool has_ostream = false>
00063 class CArrayTypeInfo:
00064 public PrimitiveTypeInfo<T, has_ostream>,
00065 public MemberFactory, public CompositionFactory
00066 {
00067 public:
00068 CArrayTypeInfo(std::string name) :
00069 PrimitiveTypeInfo<T, has_ostream> (name)
00070 {
00071 }
00072
00073 bool installTypeInfoObject(TypeInfo* ti) {
00074
00075 boost::shared_ptr< CArrayTypeInfo<T> > mthis = boost::dynamic_pointer_cast<CArrayTypeInfo<T> >( this->getSharedPtr() );
00076
00077 PrimitiveTypeInfo<T,has_ostream>::installTypeInfoObject(ti);
00078
00079 ti->setMemberFactory( mthis );
00080 ti->setCompositionFactory( mthis );
00081
00082
00083 return false;
00084 }
00085
00086 using TemplateValueFactory<T>::buildVariable;
00087 virtual base::AttributeBase* buildVariable(std::string name,int sizehint) const
00088 {
00089
00090
00091
00092
00093 typename internal::ArrayDataSource<T>::shared_ptr ads = new internal::UnboundDataSource<internal::ArrayDataSource<T> >();
00094 ads->newArray( sizehint );
00095 return new Attribute<T>( name, ads.get() );
00096 }
00097
00098
00099
00100
00101
00102 virtual std::vector<std::string> getMemberNames() const {
00103
00104 std::vector<std::string> result;
00105 result.push_back("size");
00106 result.push_back("capacity");
00107 return result;
00108 }
00109
00110 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item, const std::string& name) const {
00111 using namespace internal;
00112 typename DataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< DataSource<T> >( item );
00113
00114
00115 if (name == "size" || name == "capacity") {
00116 return new ConstantDataSource<int>( data->rvalue().count() );
00117 }
00118
00119 typename AssignableDataSource<T>::shared_ptr adata = boost::dynamic_pointer_cast< AssignableDataSource<T> >( item );
00120 if ( !adata ) {
00121 return base::DataSourceBase::shared_ptr();
00122 }
00123
00124
00125 try {
00126 unsigned int indx = boost::lexical_cast<unsigned int>(name);
00127
00128 return new ArrayPartDataSource<typename T::value_type>( *adata->set().address(), new ConstantDataSource<unsigned int>(indx), item, data->rvalue().count() );
00129 } catch(...) {}
00130 log(Error) << "CArrayTypeInfo: No such part (or invalid index): " << name << endlog();
00131 return base::DataSourceBase::shared_ptr();
00132 }
00133
00134 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item,
00135 base::DataSourceBase::shared_ptr id) const {
00136 using namespace internal;
00137 typename DataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< DataSource<T> >( item );
00138 if ( !data ) {
00139 return base::DataSourceBase::shared_ptr();
00140 }
00141
00142
00143 typename DataSource<std::string>::shared_ptr id_name = DataSource<std::string>::narrow( id.get() );
00144 if ( id_name ) {
00145
00146 if (id_name->get() == "size" || id_name->get() == "capacity") {
00147 return new ConstantDataSource<int>( data->rvalue().count() );
00148 } else {
00149 log(Error) << "CArrayTypeInfo: No such part : " << id_name->get() << endlog();
00150 return base::DataSourceBase::shared_ptr();
00151 }
00152 }
00153
00154 typename AssignableDataSource<T>::shared_ptr adata = boost::dynamic_pointer_cast< AssignableDataSource<T> >( item );
00155 if ( !adata ) {
00156 log(Error) << "CArrayTypeInfo: need assignable data type for indexing " << this->getTypeName() << endlog();
00157 return base::DataSourceBase::shared_ptr();
00158 }
00159
00160 typename DataSource<unsigned int>::shared_ptr id_indx = DataSource<unsigned int>::narrow( DataSourceTypeInfo<unsigned int>::getTypeInfo()->convert(id).get() );
00161 if ( id_indx ) {
00162 return new ArrayPartDataSource<typename T::value_type>( *adata->set().address(), id_indx, item, data->rvalue().count() );
00163 }
00164 log(Error) << "CArrayTypeInfo: Invalid index) for type " << this->getTypeName() << endlog();
00165 return base::DataSourceBase::shared_ptr();
00166 }
00167
00171 virtual base::DataSourceBase::shared_ptr decomposeType(base::DataSourceBase::shared_ptr source) const
00172 {
00173 return base::DataSourceBase::shared_ptr();
00174 }
00175
00176 virtual bool composeType( base::DataSourceBase::shared_ptr dssource, base::DataSourceBase::shared_ptr dsresult) const {
00177 const internal::DataSource<PropertyBag>* pb = dynamic_cast< const internal::DataSource<PropertyBag>* > (dssource.get() );
00178 if ( !pb )
00179 return false;
00180 typename internal::AssignableDataSource<T>::shared_ptr ads = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >( dsresult );
00181 if ( !ads )
00182 return false;
00183
00184 PropertyBag const& source = pb->rvalue();
00185 typename internal::AssignableDataSource<T>::reference_t result = ads->set();
00186
00187
00188 if(result.count() != source.size()) {
00189 log(Error) << "Refusing to compose C Arrays from a property list of different size. Use the same number of properties as the C array size." << endlog();
00190 return false;
00191 }
00192
00193 TypeInfoRepository::shared_ptr tir = Types();
00194 PropertyBag target( source.getType() );
00195 PropertyBag decomp;
00196 internal::ReferenceDataSource<T> rds(result);
00197 rds.ref();
00198
00199
00200
00201 if ( composePropertyBag(source, target) && typeDecomposition( &rds, decomp, false) && ( tir->type( decomp.getType() ) == tir->type( target.getType() ) ) && refreshProperties(decomp, target, true) ) {
00202 assert(result.count() == source.size());
00203 assert(source.size() == target.size());
00204 assert(source.size() == decomp.size());
00205 return true;
00206 }
00207 return false;
00208 }
00209
00210 };
00211 }
00212 }
00213
00214 #endif