$search
00001 /*************************************************************************** 00002 tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 OffsetPartDataSource.hpp 00003 00004 OffsetPartDataSource.hpp - 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 #ifndef ORO_OFFSETPARTDATASOURCE_HPP_ 00040 #define ORO_OFFSETPARTDATASOURCE_HPP_ 00041 00042 #include "DataSource.hpp" 00043 00044 namespace RTT 00045 { 00046 namespace internal 00047 { 00056 class OffsetDataSource 00057 : public DataSource<unsigned int> 00058 { 00059 public: 00060 typedef unsigned int offset_type; 00061 00062 ~OffsetDataSource() {} 00063 00064 typedef boost::intrusive_ptr<OffsetDataSource > shared_ptr; 00065 00072 OffsetDataSource( offset_type size, 00073 DataSource<unsigned int>::shared_ptr index, 00074 DataSource<offset_type>::shared_ptr parent_offset) 00075 : msize(size), mindex(index), mparent_offset(parent_offset) 00076 { 00077 } 00078 00079 DataSource<offset_type>::result_t get() const 00080 { 00081 // calculates the location of the element sequence. 00082 if (mparent_offset) 00083 return mdata = msize * mindex->get() + mparent_offset->get(); 00084 return mdata = msize * mindex->get(); 00085 } 00086 00087 DataSource<offset_type>::result_t value() const 00088 { 00089 return mdata; 00090 } 00091 00092 DataSource<offset_type>::const_reference_t rvalue() const 00093 { 00094 return mdata; 00095 } 00096 00097 virtual OffsetDataSource* clone() const { 00098 return new OffsetDataSource(msize, mindex, mparent_offset); 00099 } 00100 00101 virtual OffsetDataSource* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& replace ) const { 00102 // if somehow a copy exists, return the copy, otherwise return this (see Attribute copy) 00103 if ( replace[this] != 0 ) { 00104 assert ( dynamic_cast<OffsetDataSource*>( replace[this] ) == static_cast<OffsetDataSource*>( replace[this] ) ); 00105 return static_cast<OffsetDataSource*>( replace[this] ); 00106 } 00107 // Other pieces in the code rely on insertion in the map : 00108 replace[this] = new OffsetDataSource(msize, mindex->copy(replace), mparent_offset->copy(replace)); 00109 // return this instead of a copy. 00110 return static_cast<OffsetDataSource*>(replace[this]); 00111 00112 } 00113 private: 00114 // size of one element. 00115 const unsigned int msize; 00116 mutable unsigned int mdata; 00117 // [] index 00118 DataSource<unsigned int>::shared_ptr mindex; 00119 // parent offset 00120 DataSource<offset_type>::shared_ptr mparent_offset; 00121 }; 00122 00138 template<typename T> 00139 class OffsetPartDataSource 00140 : public AssignableDataSource<T> 00141 { 00142 // a reference to a value_t 00143 typename AssignableDataSource<T>::value_t* mref; 00144 // [] index 00145 DataSource<unsigned int>::shared_ptr mindex; 00146 // parent data source, for updating after set(). 00147 base::DataSourceBase::shared_ptr mparent; 00148 // offset in memory, calculated by external means. 00149 DataSource<unsigned int>::shared_ptr moffset; 00150 public: 00151 ~OffsetPartDataSource(); 00152 00153 typedef boost::intrusive_ptr<OffsetPartDataSource<T> > shared_ptr; 00154 00163 OffsetPartDataSource( typename AssignableDataSource<T>::reference_t ref, 00164 DataSource<unsigned int>::shared_ptr index, 00165 base::DataSourceBase::shared_ptr parent, 00166 DataSource<unsigned int>::shared_ptr offset) 00167 : mref(&ref), mindex(index), mparent(parent), moffset( offset) 00168 { 00169 } 00170 00171 typename DataSource<T>::result_t get() const 00172 { 00173 // calculates the location of the element sequence. 00174 return static_cast<T*>( static_cast<void*>(mref) + moffset->get() )[ mindex->get() ]; 00175 } 00176 00177 typename DataSource<T>::result_t value() const 00178 { 00179 return get(); 00180 } 00181 00182 void set( typename AssignableDataSource<T>::param_t t ) 00183 { 00184 set() = t; 00185 updated(); 00186 } 00187 00188 typename AssignableDataSource<T>::reference_t set() 00189 { 00190 // calculates the location of the element sequence. 00191 return static_cast<T*>( static_cast<void*>(mref) + moffset->get() )[ mindex->get() ]; 00192 } 00193 00194 typename AssignableDataSource<T>::const_reference_t rvalue() const 00195 { 00196 // calculates the location of the element sequence. 00197 return static_cast<T*>( static_cast<void*>(mref) + moffset->get() )[ mindex->get() ]; 00198 } 00199 00200 void updated() { 00201 mparent->updated(); 00202 } 00203 00210 virtual shared_ptr getParent() { 00211 return mparent; 00212 } 00213 00214 00215 virtual OffsetPartDataSource<T>* clone() const { 00216 return new OffsetPartDataSource<T>(mref, mindex, mparent, moffset); 00217 } 00218 00219 virtual OffsetPartDataSource<T>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& replace ) const { 00220 // if somehow a copy exists, return the copy, otherwise return this (see Attribute copy) 00221 if ( replace[this] != 0 ) { 00222 assert ( dynamic_cast<OffsetPartDataSource<T>*>( replace[this] ) == static_cast<OffsetPartDataSource<T>*>( replace[this] ) ); 00223 return static_cast<OffsetPartDataSource<T>*>( replace[this] ); 00224 } 00225 // Other pieces in the code rely on insertion in the map : 00226 replace[this] = new OffsetPartDataSource<T>(mref, mindex->copy(replace), mparent->copy(replace), moffset->copy(replace)); 00227 // return this instead of a copy. 00228 return static_cast<OffsetPartDataSource<T>*>(replace[this]); 00229 00230 } 00231 }; 00232 00233 } 00234 } 00235 00236 #endif /* ORO_PARTDATASOURCE_HPP_ */