PropertyBag.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Mon May 10 19:10:30 CEST 2004 PropertyBag.cxx
3 
4  PropertyBag.cxx - description
5  -------------------
6  begin : Mon May 10 2004
7  copyright : (C) 2004 Peter Soetens
8  email : peter.soetens@mech.kuleuven.ac.be
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 #ifdef ORO_PRAGMA_INTERFACE
39 #pragma implementation
40 #endif
41 #include "PropertyBag.hpp"
42 #include "Property.hpp"
44 #include "types/Types.hpp"
45 #include "Logger.hpp"
46 #include <algorithm>
47 #include "rtt-fwd.hpp"
48 
49 #include <boost/scoped_ptr.hpp>
50 
51 namespace RTT
52 {
53  using namespace detail;
54  using namespace std;
55 
57  : mproperties(), type("PropertyBag")
58  {}
59 
60  PropertyBag::PropertyBag( const std::string& _type)
61  : mproperties(), type(_type)
62  {}
63 
65  : mproperties()
66  {
67  *this = orig;
68  }
69 
71  {
72  this->clear();
73  }
74 
76  {
77  this->addProperty(*p);
78  }
79 
81  {
82  this->removeProperty(p);
83  }
84 
86  {
87  if (p == 0)
88  return false;
89  if ( ! p->ready() )
90  return false;
91  removeProperty(p);
92  mproperties.push_back(p);
93  mowned_props.push_back(p);
94  return true;
95  }
96 
98  {
99  if (p == 0)
100  return false;
101  const_iterator i = std::find(mowned_props.begin(), mowned_props.end(), p);
102  if ( i != mowned_props.end() )
103  return true;
104  return false;
105  }
106 
108  {
109  if (&p == 0)
110  return false;
111  if ( ! p.ready() )
112  return false;
113  mproperties.push_back(&p);
114  return true;
115  }
116 
118  {
119  if (p == 0)
120  return false;
121  iterator i = std::find(mproperties.begin(), mproperties.end(), p);
122  if ( i != mproperties.end() ) {
123  mproperties.erase(i);
124  i = std::find(mowned_props.begin(), mowned_props.end(), p);
125  if ( i != mowned_props.end() ) {
126  delete *i;
127  mowned_props.erase(i); // invalidates i
128  }
129  return true;
130  }
131  return false;
132  }
133 
135  {
136  mproperties.clear();
137  for ( iterator i = mowned_props.begin();
138  i != mowned_props.end();
139  i++ )
140  {
141  delete *i;
142  }
143  mowned_props.clear();
144  }
145 
146  void PropertyBag::list(std::vector<std::string> &names) const
147  {
148  for ( const_iterator i = mproperties.begin();
149  i != mproperties.end();
150  i++ )
151  {
152  names.push_back( (*i)->getName() );
153  }
154  }
155 
156  std::vector<std::string> PropertyBag::list() const
157  {
158  std::vector<std::string> names;
159  for ( const_iterator i = mproperties.begin();
160  i != mproperties.end();
161  i++ )
162  {
163  names.push_back( (*i)->getName() );
164  }
165  return names;
166  }
167 
169  {
170  Properties names;
171  for ( const_iterator i = mproperties.begin();
172  i != mproperties.end();
173  i++ )
174  {
175  if ( (*i)->getName() == name )
176  names.push_back( (*i) );
177  }
178  return names;
179  }
180 
181 
183  {
184  for ( const_iterator i = mproperties.begin();
185  i != mproperties.end();
186  i++ )
187  {
188  (*i)->identify(pi);
189  }
190  }
191 
193  {
194  for ( const_iterator i = mproperties.begin();
195  i != mproperties.end();
196  i++ )
197  {
198  (*i)->identify(pi);
199  }
200  }
201 
206  struct FindProp : public std::binary_function<const base::PropertyBase*,const std::string, bool>
207  {
208  bool operator()(const base::PropertyBase* b1, const std::string& b2) const { return b1->getName() == b2; }
209  };
212  PropertyBase* PropertyBag::find(const std::string& name) const
213  {
214  const_iterator i( std::find_if(mproperties.begin(), mproperties.end(), std::bind2nd(FindProp(), name ) ) );
215  if ( i != mproperties.end() )
216  return ( *i );
217  return 0;
218  }
219 
220  base::PropertyBase* PropertyBag::getProperty(const std::string& name) const
221  {
222  const_iterator i( std::find_if(mproperties.begin(), mproperties.end(), std::bind2nd(FindProp(), name ) ) );
223  if ( i != mproperties.end() )
224  return *i;
225  return 0;
226  }
227 
228 
230  {
231  if(this == &orig)
232  return *this;
233 
234  this->clear();
235 
236  for( const_iterator i = orig.mproperties.begin(); i != orig.mproperties.end(); ++i) {
237  if ( orig.ownsProperty( *i ) ) {
238  PropertyBase* copy = (*i)->create( (*i)->getDataSource() );
239  this->ownProperty( copy );
240  } else {
241  this->add( *i );
242  }
243  }
244 
245  this->setType( orig.getType() );
246  return *this;
247  }
248 
250  {
251  //iterate over orig, update or clone PropertyBases
252  const_iterator it(source.getProperties().begin());
253  while ( it != source.getProperties().end() )
254  {
255  PropertyBase* mine = find( (*it)->getName() );
256  if (mine != 0)
257  remove(mine);
258  add( (*it) );
259  ++it;
260  }
261  this->setType( source.getType() );
262  return *this;
263  }
264 
265  template<>
267  {
268  if ( !ready() )
269  return false;
270  if ( _description.empty() )
271  _description = orig.getDescription();
272  return updateProperties( this->_value->set(), orig.rvalue() );
273  }
274 
275  template<>
277  {
278  if ( !ready() )
279  return false;
280  return refreshProperties( this->_value->set(), orig.rvalue() );
281  }
282 
283  template<>
285  {
286  if ( !ready() )
287  return false;
288  _name = orig.getName();
289  _description = orig.getDescription();
290  return copyProperties( this->_value->set(), orig.rvalue() );
291  }
292 
293  std::ostream& operator<<(std::ostream& os, const PropertyBag& bag) {
294  int size = bag.size();
295  os << "[[";
296  for(int i=0; i != size; ++i) {
297  os << bag.getItem(i)->getName() << "='"<< bag.getItem(i) <<"'"<<endl;
298  }
299  os << "]]";
300 
301  return os;
302  }
303 
304  std::istream& operator>>(std::istream& is, PropertyBag& bag) { return is; }
305 
306 
307  PropertyBase* findProperty(const PropertyBag& bag, const std::string& nameSequence, const std::string& separator)
308  {
309  PropertyBase* result;
310  Property<PropertyBag>* result_bag;
311  std::string token;
312  std::string::size_type start = 0;
313  if ( separator.length() != 0 && nameSequence.find(separator) == 0 ) // detect 'root' attribute
314  start = separator.length();
315  std::string::size_type len = nameSequence.find(separator, start);
316  if (len != std::string::npos) {
317  token = nameSequence.substr(start,len-start);
318  start = len + separator.length(); // reset start to next token.
319  if ( start >= nameSequence.length() )
320  start = std::string::npos;
321  }
322  else {
323  token = nameSequence.substr(start);
324  start = std::string::npos; // do not look further.
325  }
326  result = bag.find(token);
327  if (result != 0 ) // get the base with this name
328  {
329  result_bag = dynamic_cast<Property<PropertyBag>*>(result);
330  if ( result_bag != 0 && start != std::string::npos ) {
331  return findProperty( result_bag->rvalue(), nameSequence.substr( start ), separator );// a bag so search recursively
332  }
333  else
334  return result; // not a bag, so it is a result.
335  }
336  return 0; // failure
337  }
338 
342  void listPropertiesHelper(const PropertyBag& source, const std::string& separator, const string& prefix, vector<string>& result)
343  {
344  PropertyBag::const_iterator it( source.getProperties().begin() );
345  while ( it != source.getProperties().end() ) {
346  Property<PropertyBag>* sub = dynamic_cast<Property<PropertyBag>*>(*it);
347  string itemname = prefix.empty() ? (*it)->getName() : prefix + separator + (*it)->getName();
348  result.push_back( itemname );
349  if ( sub && sub->ready() ) {
350  listPropertiesHelper( sub->value(), separator, itemname, result );
351  }
352  ++it;
353  }
354  }
355 
358  void listDescriptionsHelper(const PropertyBag& source, const std::string& separator, vector<string>& result)
359  {
360  PropertyBag::const_iterator it( source.getProperties().begin() );
361  while ( it != source.getProperties().end() ) {
362  Property<PropertyBag>* sub = dynamic_cast<Property<PropertyBag>*>(*it);
363  result.push_back( (*it)->getDescription() );
364  if ( sub && sub->ready() ) {
365  listDescriptionsHelper( sub->value(), separator, result );
366  }
367  ++it;
368  }
369  }
372  vector<string> listProperties(const PropertyBag& source, const std::string& separator)
373  {
374  vector<string> result;
375  listPropertiesHelper( source, separator, "", result);
376  return result;
377  }
378 
379  vector<string> listPropertyDescriptions(const PropertyBag& source, const std::string& separator)
380  {
381  vector<string> result;
382  listDescriptionsHelper( source, separator, result);
383  return result;
384  }
385 
386  bool storeProperty(PropertyBag& bag, const std::string& path, base::PropertyBase* item, const std::string& separator )
387  {
388  Logger::In in("storeProperty");
389  if ( path.empty() || path == separator )
390  return bag.ownProperty( item );
391  // find top-level parent
392  string pname, rest;
393  if ( path.find(separator) != string::npos ) {
394  pname = path.substr( 0, path.find(separator));
395  rest = path.substr( path.find(separator) + separator.length() );
396  } else {
397  pname = path;
398  }
399 
400  if ( pname.empty() && !rest.empty() )
401  return storeProperty( bag, rest, item, separator); // recurse
402 
403  // pname is parent
404  PropertyBase* parent = bag.find(pname);
405  if (!parent) {
406  bag.ownProperty( new Property<PropertyBag>(pname,"") );
407  parent = bag.find(pname);
408  }
409  Property<PropertyBag>* parentbag = dynamic_cast<Property<PropertyBag>* >(parent);
410  if ( !parentbag ) {
411  log(Error) << "Path component '" << pname << "' in path '"<<path<<"' does not point to a PropertyBag."<<endlog();
412  return false;
413  }
414  // recurse using new parentbag and rest.
415  return storeProperty( parentbag->value(), rest, item, separator);
416  }
417 
418  bool removeProperty(PropertyBag& bag, const std::string& path, const std::string& separator )
419  {
420  // empty path
421  if ( path.empty() || path == separator )
422  return false;
423  // single item path
424  if ( path.find( separator ) == string::npos)
425  return bag.removeProperty( bag.find(path) );
426  // multi item path
427  string prefix = path.substr( 0, path.rfind(separator));
428  string pname = path.substr( path.rfind(separator) + separator.length() );
429  // '.item' form:
430  if ( prefix.empty() )
431  return bag.removeProperty( bag.find(pname) );
432  // 'bag.item' form:
433  Property<PropertyBag> parent = findProperty( bag, prefix);
434  if ( !parent.ready() )
435  return false;
436  return parent.value().removeProperty( parent.value().find( pname ) );
437  }
438 
440  {
441 #ifndef NDEBUG
442  if (update)
443  log(Debug) << "updateProperties: updating Property "
444  << source->getType() << " "<< source->getName()
445  << "." << endlog();
446  else
447  log(Debug) << "refreshProperties: refreshing Property "
448  << source->getType() << " "<< source->getName()
449  << "." << endlog();
450 #endif
451  // no need to make new one, just update existing one
452  if ( (update && target->update( source ) == false ) || (!update && target->refresh( source ) == false ) ) {
453  // try conversion
454  DataSourceBase::shared_ptr converted = target->getTypeInfo()->convert( source->getDataSource() );
455  if ( !converted || converted == source->getDataSource() ) {
456  // no conversion, try composition:
457  converted = target->getDataSource();
458  if (target->getTypeInfo()->composeType( source->getDataSource(), converted ) ) {
459  // case where there is a type composition -> target was updated by composeType
460  log(Debug) << "Composed Property "
461  << target->getType() << " "<< source->getName() << " to type " <<target->getType()
462  << " from type " << source->getType() << endlog();
463  return true;
464  } else {
465  //if ( !target->getTypeInfo()->composeType( source->getDataSource(), target->getDataSource() ) )
466  log(Error) << (update ? "updateProperties: " : "refreshProperties: ") << " Could not update, nor convert Property "
467  << target->getType() << " "<< target->getName()
468  << ": type mismatch, can not update with "
469  << source->getType() << " "<< source->getName() << endlog();
470  return false;
471  }
472  } else {
473  // conversion: update with converted value:
474  // case where there is a type conversion -> do the update of the target
475  // since 'converted' might be a non-Assignable DataSource, we need a work-around:
476  boost::scoped_ptr<PropertyBase> dummy(target->getTypeInfo()->buildProperty("",""));
477  dummy->getDataSource()->update( converted.get() );
478  assert(dummy->getTypeInfo() == converted->getTypeInfo() );
479  // we need to use the PropertyBase API and not the DataSource API !
480  if (update)
481  target->update(dummy.get());
482  else
483  target->refresh(dummy.get());
484  log(Debug) << "Converted Property "
485  << target->getType() << " "<< source->getName() << " to type " <<dummy->getType()
486  << " from type " << source->getType() << endlog();
487  }
488  }
489  return true;
490  }
491 
492  bool refreshProperties(const PropertyBag& target, const PropertyBag& source, bool allprops)
493  {
494  Logger::In in("refreshProperties");
495 
496  // if the target is of different type than source, it is replaced by source.
497  if ( Types()->type(target.getType()) != Types()->getTypeInfo<PropertyBag>() && Types()->type( target.getType() ) != Types()->type( source.getType() ) ) {
498  log(Error) << "Can not populate typed PropertyBag '"<< target.getType() <<"' from '"<<source.getType()<<"' (source and target type differed)."<<endlog();
499  return false;
500  }
501 
502  //iterate over source, update PropertyBases
503  PropertyBag::const_iterator it( target.getProperties().begin() );
504  bool failure = false;
505  while ( it != target.getProperties().end() )
506  {
507  PropertyBase* srcprop;
508  if ( (*it)->getName() == "" ) //&& target.getType() == "Sequence" )
509  srcprop = source.getItem( it - target.getProperties().begin() );
510  else
511  srcprop = source.find( (*it)->getName() );
512  PropertyBase* tgtprop = *it;
513  if (srcprop != 0)
514  {
515  if (updateOrRefreshProperty( srcprop, tgtprop, false) == false)
516  return false;
517  // ok.
518  } else if (allprops) {
519  log(Error) << "Could not find Property "
520  << tgtprop->getType() << " "<< tgtprop->getName()
521  << " in source."<< endlog();
522  failure = true;
523  }
524  ++it;
525  }
526  return !failure;
527  }
528 
529  bool refreshProperty(const PropertyBag& target, const PropertyBase& source)
530  {
531  PropertyBase* target_prop;
532  // dynamic_cast ?
533  if ( 0 != (target_prop = target.find( source.getName() ) ) )
534  {
535  return target_prop->refresh( &source );
536  }
537  return false;
538  }
539 
540  bool copyProperties(PropertyBag& target, const PropertyBag& source)
541  {
542  // Make a full deep copy.
543  //iterate over source, clone all PropertyBases
544  PropertyBag::const_iterator it( source.getProperties().begin() );
545  while ( it != source.getProperties().end() )
546  {
547  // step 1 : clone a new instance (non deep copy)
548  PropertyBase* temp = (*it)->create();
549  // step 2 : deep copy clone with original.
550  temp->copy( *it );
551  // step 3 : add result to target bag.
552  target.ownProperty( temp );
553  ++it;
554  }
555  return true;
556  }
557 
558 
559  bool updateProperties(PropertyBag& target, const PropertyBag& source)
560  {
561  // check type consistency...
562  if ( target.getType() == "" || target.getType() == "type_less" )
563  target.setType("PropertyBag"); // RTT 1.2.0
564 
565  // if the target is of different type than source, it is replaced by source.
566  if ( Types()->type( target.getType() ) != Types()->getTypeInfo<PropertyBag>() && Types()->type(target.getType()) != Types()->type(source.getType()) ) {
567  log(Error) << "Can not populate typed PropertyBag '"<< target.getType() <<"' from '"<<source.getType()<<"' (source and target type differed)."<<endlog();
568  return false;
569  }
570 
571  target.setType( source.getType() );
572 
573  // Make an updated if present, create if not present
574  //iterate over source, update or clone PropertyBases
575 
576  PropertyBag::Names allnames = source.list();
577  PropertyBag::Names::const_iterator endnames = std::unique(allnames.begin(), allnames.end());
578  PropertyBag::Names::const_iterator it( allnames.begin() );
579  while ( it != endnames )
580  {
581  PropertyBag::Properties sources = source.getProperties(*it);
582  PropertyBag::Properties mines = target.getProperties(*it);
583  PropertyBag::iterator mit = mines.begin();
584  for( PropertyBag::const_iterator sit = sources.begin(); sit != sources.end(); ++sit ) {
585  if ( mit != mines.end() ) {
586  assert( (*sit)->getName() == (*mit)->getName());
587  if ( updateOrRefreshProperty( *sit, *mit, true) == false)
588  return false;
589  // ok.
590  ++mit;
591  }
592  else
593  {
594 #ifndef NDEBUG
596  Logger::log() << "updateProperties: creating Property "
597  << (*sit)->getType() << " "<< (*sit)->getName()
598  << "." << Logger::endl;
599 #endif
600  // step 1: test for composing a typed property bag:
601  PropertyBase* temp = 0;
602 #if 0
603  Property<PropertyBag>* tester = dynamic_cast<Property<PropertyBag>* >(*sit);
604  if (tester && Types()->type( tester->value().getType() ) != Types()->getTypeInfo<PropertyBag>()) {
605  if (TypeInfo* ti = types::Types()->type(tester->value().getType())) {
606  temp = ti->buildProperty( tester->getName(), tester->getDescription() );
607  assert(temp);
608  bool res = temp->getTypeInfo()->composeType( tester->getDataSource(), temp->getDataSource() );
609  if (!res ) return false;
610  }
611  }
612 #endif
613  if (!temp) {
614  // fallback : clone a new instance (non deep copy)
615  temp = (*sit)->create();
616  // deep copy clone with original, will never fail.
617  temp->update( (*sit) );
618  }
619  // step 3 : add result to target bag.
620  target.ownProperty( temp );
621  }
622  }
623  ++it;
624  }
625  return true;
626  }
627 
628  bool updateProperty(PropertyBag& target, const PropertyBag& source, const std::string& name, const std::string& separator)
629  {
630  Logger::In in("updateProperty");
631  // this code has been copied&modified from findProperty().
632  PropertyBase* source_walker;
633  PropertyBase* target_walker;
634  std::string token;
635  std::string::size_type start = 0;
636  if ( separator.length() != 0 && name.find(separator) == 0 ) // detect 'root' attribute
637  start = separator.length();
638  std::string::size_type len = name.find(separator, start);
639  if (len != std::string::npos) {
640  token = name.substr(start,len-start);
641  start = len + separator.length(); // reset start to next token.
642  if ( start >= name.length() )
643  start = std::string::npos;
644  }
645  else {
646  token = name.substr(start);
647  start = std::string::npos; // do not look further.
648  }
649  source_walker = source.find(token);
650  target_walker = target.find(token);
651  if (source_walker != 0 )
652  {
653  if ( target_walker == 0 ) {
654  // if not present in target, create it !
655  target_walker = source_walker->create();
656  target.ownProperty( target_walker );
657  }
658  Property<PropertyBag>* source_walker_bag;
659  Property<PropertyBag>* target_walker_bag;
660  source_walker_bag = dynamic_cast<Property<PropertyBag>*>(source_walker);
661  target_walker_bag = dynamic_cast<Property<PropertyBag>*>(target_walker);
662  if ( source_walker_bag != 0 && start != std::string::npos ) {
663  if ( target_walker_bag == 0 ) {
664  log(Error) << "Property '"<<target_walker->getName()<<"' is not a PropertyBag !"<<endlog();
665  return false;
666  }
667  return updateProperty( target_walker_bag->value(), source_walker_bag->rvalue(), name.substr( start ), separator );// a bag so search recursively
668  }
669  else {
670  // found it, update !
671  if (updateOrRefreshProperty( source_walker, target_walker, true) == false)
672  return false;
673  log(Debug) << "Found Property '"<<target_walker->getName() <<"': update done." << endlog();
674  return true;
675  }
676  } else {
677  // error wrong path, not present in source !
678  log(Error) << "Property '"<< token <<"' is not present in the source PropertyBag !"<<endlog();
679  return false;
680  }
681  // not reached.
682  return false; // failure
683  }
684 
685  bool refreshProperty(PropertyBag& target, const PropertyBag& source, const std::string& name, const std::string& separator)
686  {
687  Logger::In in("refreshProperty");
688  // this code has been copied&modified from findProperty().
689  PropertyBase* source_walker;
690  PropertyBase* target_walker;
691  std::string token;
692  std::string::size_type start = 0;
693  if ( separator.length() != 0 && name.find(separator) == 0 ) // detect 'root' attribute
694  start = separator.length();
695  std::string::size_type len = name.find(separator, start);
696  if (len != std::string::npos) {
697  token = name.substr(start,len-start);
698  start = len + separator.length(); // reset start to next token.
699  if ( start >= name.length() )
700  start = std::string::npos;
701  }
702  else {
703  token = name.substr(start);
704  start = std::string::npos; // do not look further.
705  }
706  source_walker = source.find(token);
707  target_walker = target.find(token);
708  if (source_walker != 0 )
709  {
710  if ( target_walker == 0 ) {
711  log(Error) << "Property '"<<source_walker->getName()<<"' was not found in target !"<<endlog();
712  return false;
713  }
714  Property<PropertyBag>* source_walker_bag;
715  Property<PropertyBag>* target_walker_bag;
716  source_walker_bag = dynamic_cast<Property<PropertyBag>*>(source_walker);
717  target_walker_bag = dynamic_cast<Property<PropertyBag>*>(target_walker);
718  if ( source_walker_bag != 0 && start != std::string::npos ) {
719  if ( target_walker_bag == 0 ) {
720  log(Error) << "Property '"<<target_walker->getName()<<"' is not a PropertyBag !"<<endlog();
721  return false;
722  }
723  return refreshProperty( target_walker_bag->value(), source_walker_bag->rvalue(), name.substr( start ), separator );// a bag so search recursively
724  }
725  else {
726  if (updateOrRefreshProperty( source_walker, target_walker, false) == false)
727  return false;
728  log(Debug) << "Found Property '"<<target_walker->getName() <<"': refresh done." << endlog();
729  return true;
730  }
731  } else {
732  // error wrong path, not present in source !
733  log(Error) << "Property '"<< token <<"' is not present in the source PropertyBag !"<<endlog();
734  return false;
735  }
736  // not reached.
737  return false; // failure
738  }
739 
741  {
742  //non-recursive delete.
743  PropertyBag::const_iterator it( target.getProperties().begin() );
744  while ( it != target.getProperties().end() )
745  {
746  // This loop is solely for deleting not owned properties.
747  if (!target.ownsProperty( *it ))
748  delete (*it);
749  ++it;
750  }
751  target.clear();
752  }
753 
755  {
756  //iterate over target, delete PropertyBases
757  PropertyBag::const_iterator it( target.getProperties().begin() );
758  while ( it != target.getProperties().end() )
759  {
760  // This loop is solely for deleting not owned properties and recursing
761  Property<PropertyBag>* result = dynamic_cast< Property<PropertyBag>* >( *it );
762  if ( result != 0 )
763  deletePropertyBag( result->value() );
764  if (!target.ownsProperty( *it ))
765  delete (*it);
766  ++it;
767  }
768  // deletes owned properties.
769  target.clear();
770  }
771 
772  void flattenPropertyBag(PropertyBag& target, const std::string& separator)
773  {
774  //iterate over target, recursively flatten bags.
775  Property<PropertyBag>* result;
776  PropertyBag::const_iterator it( target.getProperties().begin() );
777  while ( it != target.getProperties().end() )
778  {
779  result = dynamic_cast< Property<PropertyBag>* >( *it );
780  if ( result != 0 )
781  {
782  flattenPropertyBag( result->value(), separator );// a bag so flatten recursively
783  // copy all elements from result to target.
784  PropertyBag::const_iterator flat_it( result->value().getProperties().begin() ) ;
785  if ( flat_it != result->value().getProperties().end() )
786  {
787  while (flat_it != result->value().getProperties().end() )
788  {
789  (*flat_it)->setName( result->getName() + separator + (*flat_it)->getName() );
790  target.add( (*flat_it) );
791  result->value().remove( *flat_it );
792  flat_it = result->value().getProperties().begin();
793  }
794  it = target.getProperties().begin(); // reset iterator
795  continue; // do not increase it
796  }
797  // the bag is empty now, but it must stay in target.
798  }
799  ++it;
800  }
801  }
802 
803 }
virtual base::DataSourceBase::shared_ptr getDataSource() const
Definition: Property.hpp:393
Names list() const
void remove(base::PropertyBase *p)
Definition: PropertyBag.cpp:80
bool composeType(base::DataSourceBase::shared_ptr source, base::DataSourceBase::shared_ptr target) const
Definition: TypeInfo.hpp:386
base::DataSourceBase::shared_ptr convert(base::DataSourceBase::shared_ptr arg) const
Definition: TypeInfo.cpp:118
bool updateProperty(PropertyBag &target, const PropertyBag &source, const std::string &name, const std::string &separator)
void add(base::PropertyBase *p)
Definition: PropertyBag.cpp:75
virtual bool refresh(const base::PropertyBase *other)
Definition: Property.hpp:314
bool updateOrRefreshProperty(PropertyBase *source, PropertyBase *target, bool update)
bool updateProperties(PropertyBag &target, const PropertyBag &source)
PropertyBag & operator<<(base::PropertyBase *item)
std::istream & operator>>(std::istream &is, BufferPolicy &bp)
const std::string & getType() const
virtual bool copy(const base::PropertyBase *other)
Definition: Property.hpp:323
bool refreshProperties(const PropertyBag &target, const PropertyBag &source, bool allprops)
bool copyProperties(PropertyBag &target, const PropertyBag &source)
void setType(const std::string &newtype)
Definition: mystd.hpp:163
const_reference_t rvalue() const
Definition: Property.hpp:285
virtual PropertyBase * create() const =0
void list(Names &names) const
A container for holding references to properties.
Definition: PropertyBag.hpp:96
void flattenPropertyBag(PropertyBag &target, const std::string &separator)
reference_t value()
Definition: Property.hpp:277
bool ownProperty(base::PropertyBase *p)
Definition: PropertyBag.cpp:85
PropertyBase * findProperty(const PropertyBag &bag, const std::string &nameSequence, const std::string &separator)
virtual bool refresh(const PropertyBase *other)=0
void deletePropertyBag(PropertyBag &target)
PropertyBag & operator<<=(const PropertyBag &source)
Property< T > & addProperty(const std::string &name, T &attr)
base::PropertyBase * find(const std::string &name) const
static std::ostream & endl(std::ostream &__os)
Definition: Logger.cpp:383
virtual std::string getType() const =0
bool removeProperty(base::PropertyBase *p)
PropertyBag & operator=(const PropertyBag &orig)
const std::string & getDescription() const
Properties mowned_props
base::PropertyBase * buildProperty(const std::string &name, const std::string &desc, base::DataSourceBase::shared_ptr source=0) const
Definition: TypeInfo.hpp:214
std::string type
Properties & getProperties()
TypeInfoRepository::shared_ptr Types()
Definition: Types.cpp:48
Properties::const_iterator const_iterator
basic_ostreams & endl(basic_ostreams &s)
Definition: rtstreams.cpp:110
bool refreshProperty(const PropertyBag &target, const PropertyBase &source)
base::PropertyBase * getProperty(const std::string &name) const
vector< string > listProperties(const PropertyBag &source, const std::string &separator)
bool storeProperty(PropertyBag &bag, const std::string &path, base::PropertyBase *item, const std::string &separator)
base::PropertyBase * getItem(int i) const
void identify(base::PropertyIntrospection *pi) const
void deleteProperties(PropertyBag &target)
std::vector< std::string > Names
static Logger & log()
Definition: Logger.cpp:117
virtual bool update(const base::PropertyBase *other)
Definition: Property.hpp:305
const std::string & getName() const
vector< string > listPropertyDescriptions(const PropertyBag &source, const std::string &separator)
Properties::iterator iterator
boost::intrusive_ptr< DataSourceBase > shared_ptr
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:53
size_t size() const
virtual bool copy(const PropertyBase *other)=0
static Logger & log()
Definition: Logger.hpp:350
virtual bool update(const PropertyBase *other)=0
bool ownsProperty(base::PropertyBase *p) const
Definition: PropertyBag.cpp:97
Properties mproperties
static Logger::LogFunction endlog()
Definition: Logger.hpp:362
static bool update(TaskContext *tc)
virtual DataSourceBase::shared_ptr getDataSource() const =0
std::vector< base::PropertyBase * > Properties
virtual const types::TypeInfo * getTypeInfo() const =0


rtt
Author(s): RTT Developers
autogenerated on Fri Oct 25 2019 03:59:34