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 virtual base::AttributeBase* buildVariable(std::string name,int sizehint) const
00087 {
00088
00089
00090
00091
00092 typename internal::ArrayDataSource<T>::shared_ptr ads = new internal::UnboundDataSource<internal::ArrayDataSource<T> >();
00093 ads->newArray( sizehint );
00094 return new Attribute<T>( name, ads.get() );
00095 }
00096
00097
00098
00099
00100
00101 virtual std::vector<std::string> getMemberNames() const {
00102
00103 std::vector<std::string> result;
00104 result.push_back("size");
00105 result.push_back("capacity");
00106 return result;
00107 }
00108
00109 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item, const std::string& name) const {
00110 using namespace internal;
00111 typename DataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< DataSource<T> >( item );
00112
00113
00114 if (name == "size" || name == "capacity") {
00115 return new ConstantDataSource<int>( data->rvalue().count() );
00116 }
00117
00118 typename AssignableDataSource<T>::shared_ptr adata = boost::dynamic_pointer_cast< AssignableDataSource<T> >( item );
00119 if ( !adata ) {
00120 return base::DataSourceBase::shared_ptr();
00121 }
00122
00123
00124 try {
00125 unsigned int indx = boost::lexical_cast<unsigned int>(name);
00126
00127 return new ArrayPartDataSource<typename T::value_type>( *adata->set().address(), new ConstantDataSource<unsigned int>(indx), item, data->rvalue().count() );
00128 } catch(...) {}
00129 log(Error) << "CArrayTypeInfo: No such part (or invalid index): " << name << endlog();
00130 return base::DataSourceBase::shared_ptr();
00131 }
00132
00133 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item,
00134 base::DataSourceBase::shared_ptr id) const {
00135 using namespace internal;
00136 typename DataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< DataSource<T> >( item );
00137 if ( !data ) {
00138 return base::DataSourceBase::shared_ptr();
00139 }
00140
00141
00142 typename DataSource<std::string>::shared_ptr id_name = DataSource<std::string>::narrow( id.get() );
00143 if ( id_name ) {
00144
00145 if (id_name->get() == "size" || id_name->get() == "capacity") {
00146 return new ConstantDataSource<int>( data->rvalue().count() );
00147 } else {
00148 log(Error) << "CArrayTypeInfo: No such part : " << id_name->get() << endlog();
00149 return base::DataSourceBase::shared_ptr();
00150 }
00151 }
00152
00153 typename AssignableDataSource<T>::shared_ptr adata = boost::dynamic_pointer_cast< AssignableDataSource<T> >( item );
00154 if ( !adata ) {
00155 log(Error) << "CArrayTypeInfo: need assignable data type for indexing " << this->getTypeName() << endlog();
00156 return base::DataSourceBase::shared_ptr();
00157 }
00158
00159 typename DataSource<unsigned int>::shared_ptr id_indx = DataSource<unsigned int>::narrow( DataSourceTypeInfo<unsigned int>::getTypeInfo()->convert(id).get() );
00160 if ( id_indx ) {
00161 return new ArrayPartDataSource<typename T::value_type>( *adata->set().address(), id_indx, item, data->rvalue().count() );
00162 }
00163 log(Error) << "CArrayTypeInfo: Invalid index) for type " << this->getTypeName() << endlog();
00164 return base::DataSourceBase::shared_ptr();
00165 }
00166
00170 virtual base::DataSourceBase::shared_ptr decomposeType(base::DataSourceBase::shared_ptr source) const
00171 {
00172 return base::DataSourceBase::shared_ptr();
00173 }
00174
00175 virtual bool composeType( base::DataSourceBase::shared_ptr dssource, base::DataSourceBase::shared_ptr dsresult) const {
00176 const internal::DataSource<PropertyBag>* pb = dynamic_cast< const internal::DataSource<PropertyBag>* > (dssource.get() );
00177 if ( !pb )
00178 return false;
00179 typename internal::AssignableDataSource<T>::shared_ptr ads = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >( dsresult );
00180 if ( !ads )
00181 return false;
00182
00183 PropertyBag const& source = pb->rvalue();
00184 typename internal::AssignableDataSource<T>::reference_t result = ads->set();
00185
00186
00187 if(result.count() != source.size()) {
00188 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();
00189 return false;
00190 }
00191
00192 TypeInfoRepository::shared_ptr tir = Types();
00193 PropertyBag target( source.getType() );
00194 PropertyBag decomp;
00195 internal::ReferenceDataSource<T> rds(result);
00196 rds.ref();
00197
00198
00199
00200 if ( composePropertyBag(source, target) && typeDecomposition( &rds, decomp, false) && ( tir->type( decomp.getType() ) == tir->type( target.getType() ) ) && refreshProperties(decomp, target, true) ) {
00201 assert(result.count() == source.size());
00202 assert(source.size() == target.size());
00203 assert(source.size() == decomp.size());
00204 return true;
00205 }
00206 return false;
00207 }
00208
00209 };
00210 }
00211 }
00212
00213 #endif