diff --git a/src/contrib/attribute-iterator.cc b/src/contrib/attribute-iterator.cc index a6cd0c77c..53d844b7e 100644 --- a/src/contrib/attribute-iterator.cc +++ b/src/contrib/attribute-iterator.cc @@ -21,6 +21,7 @@ #include "ns3/log.h" #include "ns3/pointer.h" #include "ns3/object-vector.h" +#include "ns3/object-map.h" #include "ns3/string.h" #include @@ -125,6 +126,28 @@ AttributeIterator::DoEndVisitArrayItem (void) { } +void +AttributeIterator::DoStartVisitMapAttribute (Ptr object, std::string name, const ObjectMapValue &map) +{ + +} +void +AttributeIterator::DoEndVisitMapAttribute (void) +{ + +} + +void +AttributeIterator::DoStartVisitMapItem (const ObjectMapValue &vector, uint32_t index, Ptr item) +{ + +} +void +AttributeIterator::DoEndVisitMapItem (void) +{ + +} + void AttributeIterator::VisitAttribute (Ptr object, std::string name) { @@ -189,6 +212,37 @@ AttributeIterator::EndVisitArrayItem (void) DoEndVisitArrayItem (); } +void +AttributeIterator::StartVisitMapAttribute (Ptr object, std::string name, const ObjectMapValue &map) +{ + m_currentPath.push_back (name); + DoStartVisitMapAttribute (object, name, map); +} + +void +AttributeIterator::EndVisitMapAttribute (void) +{ + m_currentPath.pop_back (); + DoEndVisitArrayAttribute (); +} + +void +AttributeIterator::StartVisitMapItem (const ObjectMapValue &map, uint32_t index, Ptr item) +{ + std::ostringstream oss; + oss << index; + m_currentPath.push_back (oss.str ()); + m_currentPath.push_back ("$" + item->GetInstanceTypeId ().GetName ()); + DoStartVisitMapItem (map, index, item); +} + +void +AttributeIterator::EndVisitMapItem (void) +{ + m_currentPath.pop_back (); + m_currentPath.pop_back (); + DoEndVisitMapItem (); +} void AttributeIterator::DoIterate (Ptr object) @@ -243,6 +297,27 @@ AttributeIterator::DoIterate (Ptr object) EndVisitArrayAttribute (); continue; } + // attempt to cast to an object map. + const ObjectMapChecker *mapChecker = dynamic_cast (PeekPointer (checker)); + if (mapChecker != 0) + { + NS_LOG_DEBUG ("map attribute " << tid.GetAttributeName (i)); + ObjectMapValue map; + object->GetAttribute (tid.GetAttributeName (i), map); + // JNG Fix this + StartVisitMapAttribute (object, tid.GetAttributeName (i), map); + for (ObjectMapValue::Iterator it = map.Begin () ; it != map.End(); it++ ) + { + NS_LOG_DEBUG ("map attribute item " << (*it).first << (*it).second ); + StartVisitMapItem (map, (*it).first, (*it).second); + m_examined.push_back (object); + DoIterate ((*it).second); + m_examined.pop_back (); + EndVisitMapItem (); + } + EndVisitMapAttribute (); + continue; + } uint32_t flags = tid.GetAttributeFlags (i); Ptr accessor = tid.GetAttributeAccessor (i); if ((flags & TypeId::ATTR_GET) && accessor->HasGetter () && diff --git a/src/contrib/attribute-iterator.h b/src/contrib/attribute-iterator.h index 84912d207..4b34ec984 100644 --- a/src/contrib/attribute-iterator.h +++ b/src/contrib/attribute-iterator.h @@ -26,6 +26,7 @@ namespace ns3 { class ObjectVectorValue; +class ObjectMapValue; // This class is used internally by ConfigStore and GtkConfigStore. class AttributeIterator @@ -48,6 +49,11 @@ private: virtual void DoStartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr item); virtual void DoEndVisitArrayItem (void); + virtual void DoStartVisitMapAttribute (Ptr object, std::string name, const ObjectMapValue &map); + virtual void DoEndVisitMapAttribute (void); + virtual void DoStartVisitMapItem (const ObjectMapValue &vector, uint32_t index, Ptr item); + virtual void DoEndVisitMapItem (void); + void DoIterate (Ptr object); bool IsExamined (Ptr object); std::string GetCurrentPath (std::string attr) const; @@ -62,6 +68,10 @@ private: void StartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr item); void EndVisitArrayItem (void); + void StartVisitMapAttribute (Ptr object, std::string name, const ObjectMapValue &map); + void EndVisitMapAttribute (void); + void StartVisitMapItem (const ObjectMapValue &vector, uint32_t index, Ptr item); + void EndVisitMapItem (void); std::vector > m_examined; std::vector m_currentPath; diff --git a/src/core/model/object-map.cc b/src/core/model/object-map.cc new file mode 100644 index 000000000..1434c6cf6 --- /dev/null +++ b/src/core/model/object-map.cc @@ -0,0 +1,109 @@ +#include "object-map.h" +#include + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("ObjectMapValue"); + +ObjectMapValue::ObjectMapValue () +{} + +ObjectMapValue::Iterator +ObjectMapValue::Begin (void) const +{ + NS_LOG_FUNCTION (this); + return m_objects.begin (); +} +ObjectMapValue::Iterator +ObjectMapValue::End (void) const +{ + NS_LOG_FUNCTION (this); + return m_objects.end (); +} +uint32_t +ObjectMapValue::GetN (void) const +{ + NS_LOG_FUNCTION (this); + return m_objects.size (); +} +Ptr +ObjectMapValue::Get (uint32_t i) const +{ + NS_LOG_FUNCTION (this); + return m_objects.find(i)->second; +} + +Ptr +ObjectMapValue::Copy (void) const +{ + NS_LOG_FUNCTION (this); + return ns3::Create (*this); +} +std::string +ObjectMapValue::SerializeToString (Ptr checker) const +{ + NS_LOG_FUNCTION (this); + std::ostringstream oss; + for (ObjectMapValue::Iterator it = Begin () ; it != End(); it++ ) + { + oss << (*it).first << "-" << (*it).second; + if (it != End () ) + { + oss << " "; + } + } + return oss.str (); +} + +bool +ObjectMapValue::DeserializeFromString (std::string value, Ptr checker) +{ + NS_FATAL_ERROR ("cannot deserialize a map of object pointers."); + return true; +} + +bool +ObjectMapAccessor::Set (ObjectBase * object, const AttributeValue & value) const +{ + // not allowed. + return false; +} +bool +ObjectMapAccessor::Get (const ObjectBase * object, AttributeValue &value) const +{ + NS_LOG_FUNCTION (this); + ObjectMapValue *v = dynamic_cast (&value); + if (v == 0) + { + return false; + } + v->m_objects.clear (); + uint32_t n; + bool ok = DoGetN (object, &n); + if (!ok) + { + return false; + } + for (uint32_t i = 0; i < n; i++) + { + + std::pair > element = DoGet (object, i); + NS_LOG_FUNCTION(i << object << element.first << element.second); + + v->m_objects.insert ( DoGet (object, i)); + } + + return true; +} +bool +ObjectMapAccessor::HasGetter (void) const +{ + return true; +} +bool +ObjectMapAccessor::HasSetter (void) const +{ + return false; +} + +} // name diff --git a/src/core/model/object-map.h b/src/core/model/object-map.h new file mode 100644 index 000000000..5777e3ab9 --- /dev/null +++ b/src/core/model/object-map.h @@ -0,0 +1,217 @@ +#ifndef OBJECT_MAP_H +#define OBJECT_MAP_H + +#include "object.h" +#include "ptr.h" +#include "attribute.h" + +#include + +namespace ns3 { + +/** + * \ingroup object + * + * \brief contain a map of ns3::Object pointers. + * + * This class it used to get attribute access to an array of + * ns3::Object pointers. + */ +class ObjectMapValue : public AttributeValue +{ + + +public: + typedef std::map >::const_iterator Iterator; + + ObjectMapValue (); + + /** + * \returns an iterator to the first object contained in this map + */ + Iterator Begin (void) const; + /** + * \returns an iterator to the last object contained in this map + */ + Iterator End (void) const; + /** + * \returns the number of objects contained in this map. + */ + uint32_t GetN (void) const; + /** + * \param i the index of the requested object. + * \returns the requested object + */ + Ptr Get (uint32_t i) const; + + virtual Ptr Copy (void) const; + virtual std::string SerializeToString (Ptr checker) const; + virtual bool DeserializeFromString (std::string value, Ptr checker); + +private: + friend class ObjectMapAccessor; + std::map > m_objects; +}; + +template +Ptr +MakeObjectMapAccessor (U T::*memberMap); + +template +Ptr +MakeObjectMapAccessor (Ptr (T::*get) (INDEX) const, + INDEX (T::*getN) (void) const); + +template +Ptr +MakeObjectMapAccessor (INDEX (T::*getN) (void) const, + Ptr (T::*get) (INDEX) const); + +class ObjectMapChecker : public AttributeChecker +{ +public: + virtual TypeId GetItemTypeId (void) const = 0; +}; + +template +Ptr MakeObjectMapChecker (void); + +} // namespace ns3 + +namespace ns3 { + +namespace internal { + +template +class AnObjectMapChecker : public ObjectMapChecker +{ +public: + virtual TypeId GetItemTypeId (void) const { + return T::GetTypeId (); + } + virtual bool Check (const AttributeValue &value) const { + return dynamic_cast (&value) != 0; + } + virtual std::string GetValueTypeName (void) const { + return "ns3::ObjectMapValue"; + } + virtual bool HasUnderlyingTypeInformation (void) const { + return true; + } + virtual std::string GetUnderlyingTypeInformation (void) const { + return "ns3::Ptr< " + T::GetTypeId ().GetName () + " >"; + } + virtual Ptr Create (void) const { + return ns3::Create (); + } + virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const { + const ObjectMapValue *src = dynamic_cast (&source); + ObjectMapValue *dst = dynamic_cast (&destination); + if (src == 0 || dst == 0) + { + return false; + } + *dst = *src; + return true; + } +}; + +} // namespace internal + +class ObjectMapAccessor : public AttributeAccessor +{ +public: + virtual bool Set (ObjectBase * object, const AttributeValue &value) const; + virtual bool Get (const ObjectBase * object, AttributeValue &value) const; + virtual bool HasGetter (void) const; + virtual bool HasSetter (void) const; +private: + virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const = 0; + virtual std::pair > DoGet (const ObjectBase *object, uint32_t i) const = 0; +}; + +template +Ptr +MakeObjectMapAccessor (U T::*memberMap) +{ + struct MemberStdContainer : public ObjectMapAccessor + { + virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const { + const T *obj = dynamic_cast (object); + if (obj == 0) + { + return false; + } + *n = (obj->*m_memberMap).size (); + return true; + } + virtual std::pair > DoGet (const ObjectBase *object, uint32_t i) const { + const T *obj = static_cast (object); + typename U::const_iterator begin = (obj->*m_memberMap).begin (); + typename U::const_iterator end = (obj->*m_memberMap).end (); + uint32_t k = 0; + for (typename U::const_iterator j = begin; j != end; j++, k++) + { + if (k == i) + { + return std::pair > ( k, (*j).second); + break; + } + } + NS_ASSERT (false); + // quiet compiler. + std::pair > empty; + return empty; + } + U T::*m_memberMap; + } *spec = new MemberStdContainer (); + spec->m_memberMap = memberMap; + return Ptr (spec, false); +} + +template +Ptr +MakeObjectMapAccessor (Ptr (T::*get) (INDEX) const, + INDEX (T::*getN) (void) const) +{ + struct MemberGetters : public ObjectMapAccessor + { + virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const { + const T *obj = dynamic_cast (object); + if (obj == 0) + { + return false; + } + *n = (obj->*m_getN) (); + return true; + } + virtual Ptr DoGet (const ObjectBase *object, uint32_t i) const { + const T *obj = static_cast (object); + return (obj->*m_get) (i); + } + Ptr (T::*m_get) (INDEX) const; + INDEX (T::*m_getN) (void) const; + } *spec = new MemberGetters (); + spec->m_get = get; + spec->m_getN = getN; + return Ptr (spec, false); +} + +template +Ptr +MakeObjectMapAccessor (INDEX (T::*getN) (void) const, + Ptr (T::*get) (INDEX) const) +{ + return MakeObjectMapAccessor (get, getN); +} + +template +Ptr MakeObjectMapChecker (void) +{ + return Create > (); +} + + +} // namespace ns3 + +#endif /* OBJECT_MAP_H */ diff --git a/src/core/wscript b/src/core/wscript index e68a09e34..ba14bc77d 100644 --- a/src/core/wscript +++ b/src/core/wscript @@ -130,6 +130,7 @@ def build(bld): 'model/string.cc', 'model/pointer.cc', 'model/object-vector.cc', + 'model/object-map.cc', 'model/object-factory.cc', 'model/global-value.cc', 'model/trace-source-accessor.cc', @@ -207,6 +208,7 @@ def build(bld): 'model/trace-source-accessor.h', 'model/config.h', 'model/object-vector.h', + 'model/object-map.h', 'model/deprecated.h', 'model/abort.h', 'model/names.h',