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 "TemplateTypeInfo.hpp"
00043 #include "../internal/ArrayPartDataSource.hpp"
00044 #include "type_discovery.hpp"
00045 #include <boost/lexical_cast.hpp>
00046 #include "carray.hpp"
00047 #include "../internal/carray.hpp"
00048 #include "PropertyComposition.hpp"
00049
00050 namespace RTT
00051 {
00052 namespace types
00053 {
00061 template<typename T, bool has_ostream = false>
00062 class CArrayTypeInfo: public TemplateTypeInfo<T, has_ostream>
00063 {
00064 public:
00065 CArrayTypeInfo(std::string name) :
00066 TemplateTypeInfo<T, has_ostream> (name)
00067 {
00068 }
00069
00070 virtual std::vector<std::string> getMemberNames() const {
00071
00072 std::vector<std::string> result;
00073 result.push_back("size");
00074 result.push_back("capacity");
00075 return result;
00076 }
00077
00078 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item, const std::string& name) const {
00079 using namespace internal;
00080 typename DataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< DataSource<T> >( item );
00081
00082
00083 if (name == "size" || name == "capacity") {
00084 return new ConstantDataSource<int>( data->rvalue().count() );
00085 }
00086
00087 typename AssignableDataSource<T>::shared_ptr adata = boost::dynamic_pointer_cast< AssignableDataSource<T> >( item );
00088 if ( !adata ) {
00089 return base::DataSourceBase::shared_ptr();
00090 }
00091
00092
00093 try {
00094 unsigned int indx = boost::lexical_cast<unsigned int>(name);
00095
00096 return new ArrayPartDataSource<typename T::value_type>( *adata->set().address(), new ConstantDataSource<unsigned int>(indx), item, data->rvalue().count() );
00097 } catch(...) {}
00098 log(Error) << "CArrayTypeInfo: No such part (or invalid index): " << name << endlog();
00099 return base::DataSourceBase::shared_ptr();
00100 }
00101
00102 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item,
00103 base::DataSourceBase::shared_ptr id) const {
00104 using namespace internal;
00105 typename DataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< DataSource<T> >( item );
00106 if ( !data ) {
00107 return base::DataSourceBase::shared_ptr();
00108 }
00109
00110
00111 typename DataSource<string>::shared_ptr id_name = DataSource<string>::narrow( id.get() );
00112 if ( id_name ) {
00113
00114 if (id_name->get() == "size" || id_name->get() == "capacity") {
00115 return new ConstantDataSource<int>( data->rvalue().count() );
00116 } else {
00117 log(Error) << "CArrayTypeInfo: No such part : " << id_name->get() << endlog();
00118 return base::DataSourceBase::shared_ptr();
00119 }
00120 }
00121
00122 typename AssignableDataSource<T>::shared_ptr adata = boost::dynamic_pointer_cast< AssignableDataSource<T> >( item );
00123 if ( !adata ) {
00124 log(Error) << "CArrayTypeInfo: need assignable data type for indexing " << this->getTypeName() << endlog();
00125 return base::DataSourceBase::shared_ptr();
00126 }
00127
00128 typename DataSource<unsigned int>::shared_ptr id_indx = DataSource<unsigned int>::narrow( DataSourceTypeInfo<unsigned int>::getTypeInfo()->convert(id).get() );
00129 if ( id_indx ) {
00130 return new ArrayPartDataSource<typename T::value_type>( *adata->set().address(), id_indx, item, data->rvalue().count() );
00131 }
00132 log(Error) << "CArrayTypeInfo: Invalid index) for type " << this->getTypeName() << endlog();
00133 return base::DataSourceBase::shared_ptr();
00134 }
00135
00139 virtual bool composeTypeImpl(const PropertyBag& source, typename internal::AssignableDataSource<T>::reference_t result) const
00140 {
00141
00142 if(result.count() != source.size()) {
00143 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();
00144 return false;
00145 }
00146
00147 PropertyBag target( source.getType() );
00148 PropertyBag decomp;
00149 internal::ReferenceDataSource<T> rds(result);
00150 rds.ref();
00151
00152
00153
00154 if ( composePropertyBag(source, target) && typeDecomposition( &rds, decomp, false) && ( decomp.getType() == target.getType() ) && refreshProperties(decomp, target, true) ) {
00155 assert(result.count() == source.size());
00156 assert(source.size() == target.size());
00157 assert(source.size() == decomp.size());
00158 return true;
00159 }
00160 return false;
00161 }
00162
00163 };
00164 }
00165 }
00166
00167 #endif