Added support for map objects in the attribute system.

This commit is contained in:
jnin
2011-03-18 08:58:50 +01:00
parent c32afcf2f1
commit 034b5076d4
5 changed files with 413 additions and 0 deletions

View File

@@ -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 <fstream>
@@ -125,6 +126,28 @@ AttributeIterator::DoEndVisitArrayItem (void)
{
}
void
AttributeIterator::DoStartVisitMapAttribute (Ptr<Object> object, std::string name, const ObjectMapValue &map)
{
}
void
AttributeIterator::DoEndVisitMapAttribute (void)
{
}
void
AttributeIterator::DoStartVisitMapItem (const ObjectMapValue &vector, uint32_t index, Ptr<Object> item)
{
}
void
AttributeIterator::DoEndVisitMapItem (void)
{
}
void
AttributeIterator::VisitAttribute (Ptr<Object> object, std::string name)
{
@@ -189,6 +212,37 @@ AttributeIterator::EndVisitArrayItem (void)
DoEndVisitArrayItem ();
}
void
AttributeIterator::StartVisitMapAttribute (Ptr<Object> 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<Object> 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> object)
@@ -243,6 +297,27 @@ AttributeIterator::DoIterate (Ptr<Object> object)
EndVisitArrayAttribute ();
continue;
}
// attempt to cast to an object map.
const ObjectMapChecker *mapChecker = dynamic_cast<const ObjectMapChecker *> (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<const AttributeAccessor> accessor = tid.GetAttributeAccessor (i);
if ((flags & TypeId::ATTR_GET) && accessor->HasGetter () &&

View File

@@ -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<Object> item);
virtual void DoEndVisitArrayItem (void);
virtual void DoStartVisitMapAttribute (Ptr<Object> object, std::string name, const ObjectMapValue &map);
virtual void DoEndVisitMapAttribute (void);
virtual void DoStartVisitMapItem (const ObjectMapValue &vector, uint32_t index, Ptr<Object> item);
virtual void DoEndVisitMapItem (void);
void DoIterate (Ptr<Object> object);
bool IsExamined (Ptr<const Object> object);
std::string GetCurrentPath (std::string attr) const;
@@ -62,6 +68,10 @@ private:
void StartVisitArrayItem (const ObjectVectorValue &vector, uint32_t index, Ptr<Object> item);
void EndVisitArrayItem (void);
void StartVisitMapAttribute (Ptr<Object> object, std::string name, const ObjectMapValue &map);
void EndVisitMapAttribute (void);
void StartVisitMapItem (const ObjectMapValue &vector, uint32_t index, Ptr<Object> item);
void EndVisitMapItem (void);
std::vector<Ptr<Object> > m_examined;
std::vector<std::string> m_currentPath;

View File

@@ -0,0 +1,109 @@
#include "object-map.h"
#include <ns3/log.h>
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<Object>
ObjectMapValue::Get (uint32_t i) const
{
NS_LOG_FUNCTION (this);
return m_objects.find(i)->second;
}
Ptr<AttributeValue>
ObjectMapValue::Copy (void) const
{
NS_LOG_FUNCTION (this);
return ns3::Create<ObjectMapValue> (*this);
}
std::string
ObjectMapValue::SerializeToString (Ptr<const AttributeChecker> 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<const AttributeChecker> 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<ObjectMapValue *> (&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<uint32_t, Ptr<Object> > 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

217
src/core/model/object-map.h Normal file
View File

@@ -0,0 +1,217 @@
#ifndef OBJECT_MAP_H
#define OBJECT_MAP_H
#include "object.h"
#include "ptr.h"
#include "attribute.h"
#include <map>
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<uint32_t, Ptr<Object> >::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<Object> Get (uint32_t i) const;
virtual Ptr<AttributeValue> Copy (void) const;
virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
private:
friend class ObjectMapAccessor;
std::map<uint32_t, Ptr<Object> > m_objects;
};
template <typename T, typename U>
Ptr<const AttributeAccessor>
MakeObjectMapAccessor (U T::*memberMap);
template <typename T, typename U, typename INDEX>
Ptr<const AttributeAccessor>
MakeObjectMapAccessor (Ptr<U> (T::*get) (INDEX) const,
INDEX (T::*getN) (void) const);
template <typename T, typename U, typename INDEX>
Ptr<const AttributeAccessor>
MakeObjectMapAccessor (INDEX (T::*getN) (void) const,
Ptr<U> (T::*get) (INDEX) const);
class ObjectMapChecker : public AttributeChecker
{
public:
virtual TypeId GetItemTypeId (void) const = 0;
};
template <typename T>
Ptr<const AttributeChecker> MakeObjectMapChecker (void);
} // namespace ns3
namespace ns3 {
namespace internal {
template <typename T>
class AnObjectMapChecker : public ObjectMapChecker
{
public:
virtual TypeId GetItemTypeId (void) const {
return T::GetTypeId ();
}
virtual bool Check (const AttributeValue &value) const {
return dynamic_cast<const ObjectMapValue *> (&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<AttributeValue> Create (void) const {
return ns3::Create<ObjectMapValue> ();
}
virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const {
const ObjectMapValue *src = dynamic_cast<const ObjectMapValue *> (&source);
ObjectMapValue *dst = dynamic_cast<ObjectMapValue *> (&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<uint32_t, Ptr<Object> > DoGet (const ObjectBase *object, uint32_t i) const = 0;
};
template <typename T, typename U>
Ptr<const AttributeAccessor>
MakeObjectMapAccessor (U T::*memberMap)
{
struct MemberStdContainer : public ObjectMapAccessor
{
virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const {
const T *obj = dynamic_cast<const T *> (object);
if (obj == 0)
{
return false;
}
*n = (obj->*m_memberMap).size ();
return true;
}
virtual std::pair<uint32_t, Ptr<Object> > DoGet (const ObjectBase *object, uint32_t i) const {
const T *obj = static_cast<const T *> (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<uint32_t, Ptr<Object> > ( k, (*j).second);
break;
}
}
NS_ASSERT (false);
// quiet compiler.
std::pair<uint32_t, Ptr<Object> > empty;
return empty;
}
U T::*m_memberMap;
} *spec = new MemberStdContainer ();
spec->m_memberMap = memberMap;
return Ptr<const AttributeAccessor> (spec, false);
}
template <typename T, typename U, typename INDEX>
Ptr<const AttributeAccessor>
MakeObjectMapAccessor (Ptr<U> (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<const T *> (object);
if (obj == 0)
{
return false;
}
*n = (obj->*m_getN) ();
return true;
}
virtual Ptr<Object> DoGet (const ObjectBase *object, uint32_t i) const {
const T *obj = static_cast<const T *> (object);
return (obj->*m_get) (i);
}
Ptr<U> (T::*m_get) (INDEX) const;
INDEX (T::*m_getN) (void) const;
} *spec = new MemberGetters ();
spec->m_get = get;
spec->m_getN = getN;
return Ptr<const AttributeAccessor> (spec, false);
}
template <typename T, typename U, typename INDEX>
Ptr<const AttributeAccessor>
MakeObjectMapAccessor (INDEX (T::*getN) (void) const,
Ptr<U> (T::*get) (INDEX) const)
{
return MakeObjectMapAccessor (get, getN);
}
template <typename T>
Ptr<const AttributeChecker> MakeObjectMapChecker (void)
{
return Create<internal::AnObjectMapChecker<T> > ();
}
} // namespace ns3
#endif /* OBJECT_MAP_H */

View File

@@ -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',