split code from object.h/object.cc

This commit is contained in:
Mathieu Lacage
2008-03-16 20:55:18 +01:00
parent 1806cbede9
commit 660e414f36
11 changed files with 1332 additions and 1287 deletions

View File

@@ -21,7 +21,6 @@
#define ATTRIBUTE_HELPER_H
#include "attribute.h"
#include "object-base.h"
#include "attribute-accessor-helper.h"
#include <sstream>
#include "fatal-error.h"
@@ -57,8 +56,6 @@ MakeSimpleAttributeChecker (std::string name)
}
/**
* \defgroup AttributeHelper
*
@@ -281,5 +278,4 @@ MakeSimpleAttributeChecker (std::string name)
ATTRIBUTE_VALUE_IMPLEMENT (type);
#endif /* ATTRIBUTE_HELPER_H */

237
src/core/attribute-list.cc Normal file
View File

@@ -0,0 +1,237 @@
#include "attribute-list.h"
#include "string.h"
#include "singleton.h"
namespace ns3 {
/*********************************************************************
* The AttributeList container implementation
*********************************************************************/
AttributeList::AttributeList ()
{}
AttributeList::AttributeList (const AttributeList &o)
{
for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
{
struct Attr attr;
attr.checker = i->checker;
attr.value = i->value.Copy ();
m_attributes.push_back (attr);
}
}
AttributeList &
AttributeList::operator = (const AttributeList &o)
{
Reset ();
for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
{
struct Attr attr;
attr.checker = i->checker;
attr.value = i->value.Copy ();
m_attributes.push_back (attr);
}
return *this;
}
AttributeList::~AttributeList ()
{
Reset ();
}
void
AttributeList::Set (std::string name, Attribute value)
{
struct TypeId::AttributeInfo info;
bool ok = TypeId::LookupAttributeByFullName (name, &info);
if (!ok)
{
NS_FATAL_ERROR ("Could not find attribute "<<name);
}
ok = DoSet (&info, value);
if (!ok)
{
NS_FATAL_ERROR ("Could not set value for attribute "<<name);
}
}
bool
AttributeList::SetFailSafe (std::string name, Attribute value)
{
struct TypeId::AttributeInfo info;
bool ok = TypeId::LookupAttributeByFullName (name, &info);
if (!ok)
{
return false;
}
ok = DoSet (&info, value);
return ok;
}
void
AttributeList::SetWithTid (TypeId tid, std::string name, Attribute value)
{
struct TypeId::AttributeInfo info;
bool ok = tid.LookupAttributeByName (name, &info);
if (!ok)
{
NS_FATAL_ERROR ("Could not find attribute "<<tid.GetName ()<<"::"<<name);
}
ok = DoSet (&info, value);
if (!ok)
{
NS_FATAL_ERROR ("Could not set value for attribute "<<tid.GetName ()<<"::"<<name);
}
}
void
AttributeList::DoSetOne (Ptr<const AttributeChecker> checker, Attribute value)
{
// get rid of any previous value stored in this
// vector of values.
for (Attrs::iterator k = m_attributes.begin (); k != m_attributes.end (); k++)
{
if (k->checker == checker)
{
m_attributes.erase (k);
break;
}
}
// store the new value.
struct Attr attr;
attr.checker = checker;
attr.value = value.Copy ();
m_attributes.push_back (attr);
}
bool
AttributeList::DoSet (struct TypeId::AttributeInfo *info, Attribute value)
{
if (info->checker == 0)
{
return false;
}
bool ok = info->checker->Check (value);
if (!ok)
{
// attempt to convert to string.
const StringValue *str = value.DynCast<const StringValue *> ();
if (str == 0)
{
return false;
}
// attempt to convert back to value.
Attribute v = info->checker->Create ();
ok = v.DeserializeFromString (str->Get ().Get (), info->checker);
if (!ok)
{
return false;
}
ok = info->checker->Check (v);
if (!ok)
{
return false;
}
value = v;
}
DoSetOne (info->checker, value);
return true;
}
void
AttributeList::Reset (void)
{
m_attributes.clear ();
}
AttributeList *
AttributeList::GetGlobal (void)
{
return Singleton<AttributeList>::Get ();
}
std::string
AttributeList::LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const
{
for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
{
TypeId tid = TypeId::GetRegistered (i);
for (uint32_t j = 0; j < tid.GetAttributeListN (); j++)
{
if (checker == tid.GetAttributeChecker (j))
{
return tid.GetAttributeFullName (j);
}
}
}
NS_FATAL_ERROR ("Could not find requested Accessor.");
// quiet compiler.
return "";
}
std::string
AttributeList::SerializeToString (void) const
{
std::ostringstream oss;
for (Attrs::const_iterator i = m_attributes.begin (); i != m_attributes.end (); i++)
{
std::string name = LookupAttributeFullNameByChecker (i->checker);
oss << name << "=" << i->value.SerializeToString (i->checker);
if (i != m_attributes.end ())
{
oss << "|";
}
}
return oss.str ();
}
bool
AttributeList::DeserializeFromString (std::string str)
{
Reset ();
std::string::size_type cur;
cur = 0;
do {
std::string::size_type equal = str.find ("=", cur);
if (equal == std::string::npos)
{
// XXX: invalid attribute.
break;
}
else
{
std::string name = str.substr (cur, equal-cur);
struct TypeId::AttributeInfo info;
if (!TypeId::LookupAttributeByFullName (name, &info))
{
// XXX invalid name.
break;
}
else
{
std::string::size_type next = str.find ("|", cur);
std::string value;
if (next == std::string::npos)
{
value = str.substr (equal+1, str.size () - (equal+1));
cur = str.size ();
}
else
{
value = str.substr (equal+1, next - (equal+1));
cur++;
}
Attribute val = info.checker->Create ();
bool ok = val.DeserializeFromString (value, info.checker);
if (!ok)
{
// XXX invalid value
break;
}
else
{
DoSetOne (info.checker, val);
}
}
}
} while (cur != str.size ());
return true;
}
} // namespace ns3

93
src/core/attribute-list.h Normal file
View File

@@ -0,0 +1,93 @@
#ifndef ATTRIBUTE_LIST_H
#define ATTRIBUTE_LIST_H
#include <string>
#include <vector>
#include "attribute.h"
#include "type-id.h"
namespace ns3 {
/**
* \brief a container of attributes to be used during object's construction
* and in ns3::Object::Set.
*
*/
class AttributeList
{
public:
AttributeList ();
AttributeList (const AttributeList &o);
AttributeList &operator = (const AttributeList &o);
~AttributeList ();
/**
* \param name the full name of the attribute to set
* \param value the value to set
*
* This method checks that a attribute with the requested
* name exists and that the value specified is an acceptable
* value of that attribute. If any of these checks fails,
* the program terminates with a message.
*/
void Set (std::string name, Attribute value);
/**
* \param name the full name of the attribute to set
* \param value the value to set
* \returns true if the requested attribute exists and could be
* stored, false otherwise.
*/
bool SetFailSafe (std::string name, Attribute value);
/**
* \param tid the TypeId associated to this attribute
* \param name the name (not full!) of the attribute
* \param value the value to set
*
* This method checks that a attribute with the requested
* name exists and that the value specified is an acceptable
* value of that attribute. If any of these checks fails,
* the program terminates with a message.
*/
void SetWithTid (TypeId tid, std::string name, Attribute value);
/**
* Clear the content of this instance.
*/
void Reset (void);
/**
* \returns the global attribute container
*
* The global attribute container can be used to specify
* a set of attribute values without having to re-specify
* them for each object when it is created. This container
* is checked only during object construction and
* it is always checked last, after any per-object
* container is checked.
*/
static AttributeList *GetGlobal (void);
// XXX: untested.
std::string SerializeToString (void) const;
bool DeserializeFromString (std::string value);
private:
friend class Object;
struct Attr {
Ptr<const AttributeChecker> checker;
Attribute value;
};
typedef std::vector<struct Attr> Attrs;
typedef Attrs::iterator Iterator;
typedef Attrs::const_iterator CIterator;
bool DoSet (struct TypeId::AttributeInfo *info, Attribute param);
void DoSetOne (Ptr<const AttributeChecker> checker, Attribute param);
std::string LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const;
Attrs m_attributes;
};
} // namespace ns3
#endif /* ATTRIBUTE_LIST_H */

View File

@@ -23,13 +23,13 @@
#include <string>
#include <stdint.h>
#include "ptr.h"
#include "object-base.h"
namespace ns3 {
class AttributeAccessor;
class AttributeChecker;
class Attribute;
class ObjectBase;
/**
* \brief Hold a value for an Attribute.
@@ -159,7 +159,7 @@ private:
* of this base class are usually provided through the MakeAccessorHelper
* template functions, hidden behind an ATTRIBUTE_HELPER_* macro.
*/
class AttributeAccessor : public ObjectBase
class AttributeAccessor
{
public:
AttributeAccessor ();
@@ -202,7 +202,7 @@ private:
* Most subclasses of this base class are implemented by the
* ATTRIBUTE_HELPER_* macros.
*/
class AttributeChecker : public ObjectBase
class AttributeChecker
{
public:
AttributeChecker ();

View File

@@ -26,7 +26,6 @@
#include "fatal-error.h"
#include "empty.h"
#include "type-traits.h"
#include "object-base.h"
namespace ns3 {

View File

@@ -1,6 +1,21 @@
#ifndef OBJECT_BASE_H
#define OBJECT_BASE_H
#include "type-id.h"
/**
* This macro should be invoked once for every class which
* defines a new GetTypeId method.
*/
#define NS_OBJECT_ENSURE_REGISTERED(type) \
static struct X##type##RegistrationClass \
{ \
X##type##RegistrationClass () { \
ns3::TypeId tid = type::GetTypeId (); \
tid.GetParent (); \
} \
} x_##type##RegistrationVariable
namespace ns3 {
/**

View File

@@ -30,917 +30,8 @@
NS_LOG_COMPONENT_DEFINE ("Object");
/*********************************************************************
* Helper code
*********************************************************************/
namespace {
class IidManager
{
public:
IidManager ();
uint16_t AllocateUid (std::string name);
void SetParent (uint16_t uid, uint16_t parent);
void SetTypeName (uint16_t uid, std::string typeName);
void SetGroupName (uint16_t uid, std::string groupName);
void AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback);
void HideFromDocumentation (uint16_t uid);
uint16_t GetUid (std::string name) const;
std::string GetName (uint16_t uid) const;
uint16_t GetParent (uint16_t uid) const;
std::string GetTypeName (uint16_t uid) const;
std::string GetGroupName (uint16_t uid) const;
ns3::Callback<ns3::ObjectBase *> GetConstructor (uint16_t uid) const;
bool HasConstructor (uint16_t uid) const;
uint32_t GetRegisteredN (void) const;
uint16_t GetRegistered (uint32_t i) const;
void AddAttribute (uint16_t uid,
std::string name,
std::string help,
uint32_t flags,
ns3::Attribute initialValue,
ns3::Ptr<const ns3::AttributeAccessor> spec,
ns3::Ptr<const ns3::AttributeChecker> checker);
uint32_t GetAttributeListN (uint16_t uid) const;
std::string GetAttributeName (uint16_t uid, uint32_t i) const;
std::string GetAttributeHelp (uint16_t uid, uint32_t i) const;
uint32_t GetAttributeFlags (uint16_t uid, uint32_t i) const;
ns3::Attribute GetAttributeInitialValue (uint16_t uid, uint32_t i) const;
ns3::Ptr<const ns3::AttributeAccessor> GetAttributeAccessor (uint16_t uid, uint32_t i) const;
ns3::Ptr<const ns3::AttributeChecker> GetAttributeChecker (uint16_t uid, uint32_t i) const;
void AddTraceSource (uint16_t uid,
std::string name,
std::string help,
ns3::Ptr<const ns3::TraceSourceAccessor> accessor);
uint32_t GetTraceSourceN (uint16_t uid) const;
std::string GetTraceSourceName (uint16_t uid, uint32_t i) const;
std::string GetTraceSourceHelp (uint16_t uid, uint32_t i) const;
ns3::Ptr<const ns3::TraceSourceAccessor> GetTraceSourceAccessor (uint16_t uid, uint32_t i) const;
bool MustHideFromDocumentation (uint16_t uid) const;
private:
struct AttributeInformation {
std::string name;
std::string help;
uint32_t flags;
ns3::Attribute initialValue;
ns3::Ptr<const ns3::AttributeAccessor> param;
ns3::Ptr<const ns3::AttributeChecker> checker;
};
struct TraceSourceInformation {
std::string name;
std::string help;
ns3::Ptr<const ns3::TraceSourceAccessor> accessor;
};
struct IidInformation {
std::string name;
uint16_t parent;
std::string typeName;
std::string groupName;
bool hasConstructor;
ns3::Callback<ns3::ObjectBase *> constructor;
bool mustHideFromDocumentation;
std::vector<struct AttributeInformation> attributes;
std::vector<struct TraceSourceInformation> traceSources;
};
typedef std::vector<struct IidInformation>::const_iterator Iterator;
struct IidManager::IidInformation *LookupInformation (uint16_t uid) const;
std::vector<struct IidInformation> m_information;
};
IidManager::IidManager ()
{}
uint16_t
IidManager::AllocateUid (std::string name)
{
uint16_t j = 1;
for (Iterator i = m_information.begin (); i != m_information.end (); i++)
{
if (i->name == name)
{
NS_FATAL_ERROR ("Trying to allocate twice the same uid: " << name);
return 0;
}
j++;
}
struct IidInformation information;
information.name = name;
information.parent = 0;
information.typeName = "";
information.groupName = "";
information.hasConstructor = false;
information.mustHideFromDocumentation = false;
m_information.push_back (information);
uint32_t uid = m_information.size ();
NS_ASSERT (uid <= 0xffff);
return uid;
}
struct IidManager::IidInformation *
IidManager::LookupInformation (uint16_t uid) const
{
NS_ASSERT (uid <= m_information.size ());
return const_cast<struct IidInformation *> (&m_information[uid-1]);
}
void
IidManager::SetParent (uint16_t uid, uint16_t parent)
{
NS_ASSERT (parent <= m_information.size ());
struct IidInformation *information = LookupInformation (uid);
information->parent = parent;
}
void
IidManager::SetTypeName (uint16_t uid, std::string typeName)
{
struct IidInformation *information = LookupInformation (uid);
information->typeName = typeName;
}
void
IidManager::SetGroupName (uint16_t uid, std::string groupName)
{
struct IidInformation *information = LookupInformation (uid);
information->groupName = groupName;
}
void
IidManager::HideFromDocumentation (uint16_t uid)
{
struct IidInformation *information = LookupInformation (uid);
information->mustHideFromDocumentation = true;
}
void
IidManager::AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback)
{
struct IidInformation *information = LookupInformation (uid);
if (information->hasConstructor)
{
NS_FATAL_ERROR (information->name<<" already has a constructor.");
}
information->hasConstructor = true;
information->constructor = callback;
}
uint16_t
IidManager::GetUid (std::string name) const
{
uint32_t j = 1;
for (Iterator i = m_information.begin (); i != m_information.end (); i++)
{
if (i->name == name)
{
NS_ASSERT (j <= 0xffff);
return j;
}
j++;
}
return 0;
}
std::string
IidManager::GetName (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->name;
}
uint16_t
IidManager::GetParent (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->parent;
}
std::string
IidManager::GetTypeName (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->typeName;
}
std::string
IidManager::GetGroupName (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->groupName;
}
ns3::Callback<ns3::ObjectBase *>
IidManager::GetConstructor (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
if (!information->hasConstructor)
{
NS_FATAL_ERROR ("Requested constructor for "<<information->name<<" but it does not have one.");
}
return information->constructor;
}
bool
IidManager::HasConstructor (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->hasConstructor;
}
uint32_t
IidManager::GetRegisteredN (void) const
{
return m_information.size ();
}
uint16_t
IidManager::GetRegistered (uint32_t i) const
{
return i + 1;
}
void
IidManager::AddAttribute (uint16_t uid,
std::string name,
std::string help,
uint32_t flags,
ns3::Attribute initialValue,
ns3::Ptr<const ns3::AttributeAccessor> spec,
ns3::Ptr<const ns3::AttributeChecker> checker)
{
struct IidInformation *information = LookupInformation (uid);
for (std::vector<struct AttributeInformation>::const_iterator j = information->attributes.begin ();
j != information->attributes.end (); j++)
{
if (j->name == name)
{
NS_FATAL_ERROR ("Registered the same attribute twice name=\""<<name<<"\" in TypeId=\""<<information->name<<"\"");
return;
}
}
struct AttributeInformation param;
param.name = name;
param.help = help;
param.flags = flags;
param.initialValue = initialValue;
param.param = spec;
param.checker = checker;
information->attributes.push_back (param);
}
uint32_t
IidManager::GetAttributeListN (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->attributes.size ();
}
std::string
IidManager::GetAttributeName (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->attributes.size ());
return information->attributes[i].name;
}
std::string
IidManager::GetAttributeHelp (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->attributes.size ());
return information->attributes[i].help;
}
uint32_t
IidManager::GetAttributeFlags (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->attributes.size ());
return information->attributes[i].flags;
}
ns3::Attribute
IidManager::GetAttributeInitialValue (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->attributes.size ());
return information->attributes[i].initialValue;
}
ns3::Ptr<const ns3::AttributeAccessor>
IidManager::GetAttributeAccessor (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->attributes.size ());
return information->attributes[i].param;
}
ns3::Ptr<const ns3::AttributeChecker>
IidManager::GetAttributeChecker (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->attributes.size ());
return information->attributes[i].checker;
}
void
IidManager::AddTraceSource (uint16_t uid,
std::string name,
std::string help,
ns3::Ptr<const ns3::TraceSourceAccessor> accessor)
{
struct IidInformation *information = LookupInformation (uid);
struct TraceSourceInformation source;
source.name = name;
source.help = help;
source.accessor = accessor;
information->traceSources.push_back (source);
}
uint32_t
IidManager::GetTraceSourceN (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->traceSources.size ();
}
std::string
IidManager::GetTraceSourceName (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->traceSources.size ());
return information->traceSources[i].name;
}
std::string
IidManager::GetTraceSourceHelp (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->traceSources.size ());
return information->traceSources[i].help;
}
ns3::Ptr<const ns3::TraceSourceAccessor>
IidManager::GetTraceSourceAccessor (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->traceSources.size ());
return information->traceSources[i].accessor;
}
bool
IidManager::MustHideFromDocumentation (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->mustHideFromDocumentation;
}
} // anonymous namespace
namespace ns3 {
/*********************************************************************
* The TypeId class
*********************************************************************/
TypeId::TypeId ()
: m_tid (0)
{}
TypeId::TypeId (const char *name)
{
uint16_t uid = Singleton<IidManager>::Get ()->AllocateUid (name);
NS_ASSERT (uid != 0);
m_tid = uid;
}
TypeId::TypeId (uint16_t tid)
: m_tid (tid)
{}
TypeId::~TypeId ()
{}
TypeId
TypeId::LookupByName (std::string name)
{
uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
NS_ASSERT (uid != 0);
return TypeId (uid);
}
bool
TypeId::LookupByNameFailSafe (std::string name, TypeId *tid)
{
uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
if (uid == 0)
{
return false;
}
*tid = TypeId (uid);
return true;
}
bool
TypeId::LookupAttributeByFullName (std::string fullName, struct TypeId::AttributeInfo *info)
{
std::string::size_type pos = fullName.rfind ("::");
if (pos == std::string::npos)
{
return 0;
}
std::string tidName = fullName.substr (0, pos);
std::string paramName = fullName.substr (pos+2, fullName.size () - (pos+2));
TypeId tid;
bool ok = LookupByNameFailSafe (tidName, &tid);
if (!ok)
{
return false;
}
return tid.LookupAttributeByName (paramName, info);
}
uint32_t
TypeId::GetRegisteredN (void)
{
return Singleton<IidManager>::Get ()->GetRegisteredN ();
}
TypeId
TypeId::GetRegistered (uint32_t i)
{
return TypeId (Singleton<IidManager>::Get ()->GetRegistered (i));
}
bool
TypeId::LookupAttributeByName (std::string name, struct TypeId::AttributeInfo *info) const
{
TypeId tid;
TypeId nextTid = *this;
do {
tid = nextTid;
for (uint32_t i = 0; i < tid.GetAttributeListN (); i++)
{
std::string paramName = tid.GetAttributeName (i);
if (paramName == name)
{
info->accessor = tid.GetAttributeAccessor (i);
info->flags = tid.GetAttributeFlags (i);
info->initialValue = tid.GetAttributeInitialValue (i);
info->checker = tid.GetAttributeChecker (i);
return true;
}
}
nextTid = tid.GetParent ();
} while (nextTid != tid);
return false;
}
TypeId
TypeId::SetParent (TypeId tid)
{
Singleton<IidManager>::Get ()->SetParent (m_tid, tid.m_tid);
return *this;
}
TypeId
TypeId::SetGroupName (std::string groupName)
{
Singleton<IidManager>::Get ()->SetGroupName (m_tid, groupName);
return *this;
}
TypeId
TypeId::SetTypeName (std::string typeName)
{
Singleton<IidManager>::Get ()->SetTypeName (m_tid, typeName);
return *this;
}
TypeId
TypeId::GetParent (void) const
{
uint16_t parent = Singleton<IidManager>::Get ()->GetParent (m_tid);
return TypeId (parent);
}
std::string
TypeId::GetGroupName (void) const
{
std::string groupName = Singleton<IidManager>::Get ()->GetGroupName (m_tid);
return groupName;
}
std::string
TypeId::GetTypeName (void) const
{
std::string typeName = Singleton<IidManager>::Get ()->GetTypeName (m_tid);
return typeName;
}
std::string
TypeId::GetName (void) const
{
std::string name = Singleton<IidManager>::Get ()->GetName (m_tid);
return name;
}
bool
TypeId::HasConstructor (void) const
{
bool hasConstructor = Singleton<IidManager>::Get ()->HasConstructor (m_tid);
return hasConstructor;
}
void
TypeId::DoAddConstructor (Callback<ObjectBase *> cb)
{
Singleton<IidManager>::Get ()->AddConstructor (m_tid, cb);
}
TypeId
TypeId::AddAttribute (std::string name,
std::string help,
Attribute initialValue,
Ptr<const AttributeAccessor> param,
Ptr<const AttributeChecker> checker)
{
Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, initialValue, param, checker);
return *this;
}
TypeId
TypeId::AddAttribute (std::string name,
std::string help,
uint32_t flags,
Attribute initialValue,
Ptr<const AttributeAccessor> param,
Ptr<const AttributeChecker> checker)
{
Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, flags, initialValue, param, checker);
return *this;
}
Callback<ObjectBase *>
TypeId::GetConstructor (void) const
{
Callback<ObjectBase *> cb = Singleton<IidManager>::Get ()->GetConstructor (m_tid);
return cb;
}
bool
TypeId::MustHideFromDocumentation (void) const
{
bool mustHide = Singleton<IidManager>::Get ()->MustHideFromDocumentation (m_tid);
return mustHide;
}
uint32_t
TypeId::GetAttributeListN (void) const
{
uint32_t n = Singleton<IidManager>::Get ()->GetAttributeListN (m_tid);
return n;
}
std::string
TypeId::GetAttributeName (uint32_t i) const
{
std::string name = Singleton<IidManager>::Get ()->GetAttributeName (m_tid, i);
return name;
}
std::string
TypeId::GetAttributeHelp (uint32_t i) const
{
std::string help = Singleton<IidManager>::Get ()->GetAttributeHelp (m_tid, i);
return help;
}
std::string
TypeId::GetAttributeFullName (uint32_t i) const
{
return GetName () + "::" + GetAttributeName (i);
}
Attribute
TypeId::GetAttributeInitialValue (uint32_t i) const
{
Attribute value = Singleton<IidManager>::Get ()->GetAttributeInitialValue (m_tid, i);
return value;
}
Ptr<const AttributeAccessor>
TypeId::GetAttributeAccessor (uint32_t i) const
{
// Used exclusively by the Object class.
Ptr<const AttributeAccessor> param = Singleton<IidManager>::Get ()->GetAttributeAccessor (m_tid, i);
return param;
}
uint32_t
TypeId::GetAttributeFlags (uint32_t i) const
{
// Used exclusively by the Object class.
uint32_t flags = Singleton<IidManager>::Get ()->GetAttributeFlags (m_tid, i);
return flags;
}
Ptr<const AttributeChecker>
TypeId::GetAttributeChecker (uint32_t i) const
{
// Used exclusively by the Object class.
Ptr<const AttributeChecker> checker = Singleton<IidManager>::Get ()->GetAttributeChecker (m_tid, i);
return checker;
}
uint32_t
TypeId::GetTraceSourceN (void) const
{
return Singleton<IidManager>::Get ()->GetTraceSourceN (m_tid);
}
std::string
TypeId::GetTraceSourceName (uint32_t i) const
{
return Singleton<IidManager>::Get ()->GetTraceSourceName (m_tid, i);
}
std::string
TypeId::GetTraceSourceHelp (uint32_t i) const
{
return Singleton<IidManager>::Get ()->GetTraceSourceHelp (m_tid, i);
}
Ptr<const TraceSourceAccessor>
TypeId::GetTraceSourceAccessor (uint32_t i) const
{
return Singleton<IidManager>::Get ()->GetTraceSourceAccessor (m_tid, i);
}
TypeId
TypeId::AddTraceSource (std::string name,
std::string help,
Ptr<const TraceSourceAccessor> accessor)
{
Singleton<IidManager>::Get ()->AddTraceSource (m_tid, name, help, accessor);
return *this;
}
TypeId
TypeId::HideFromDocumentation (void)
{
Singleton<IidManager>::Get ()->HideFromDocumentation (m_tid);
return *this;
}
Ptr<const TraceSourceAccessor>
TypeId::LookupTraceSourceByName (std::string name) const
{
TypeId tid;
TypeId nextTid = *this;
do {
tid = nextTid;
for (uint32_t i = 0; i < tid.GetTraceSourceN (); i++)
{
std::string srcName = tid.GetTraceSourceName (i);
if (srcName == name)
{
return tid.GetTraceSourceAccessor (i);
}
}
nextTid = tid.GetParent ();
} while (nextTid != tid);
return 0;
}
std::ostream & operator << (std::ostream &os, TypeId tid)
{
os << tid.GetName ();
return os;
}
std::istream & operator >> (std::istream &is, TypeId &tid)
{
std::string tidString;
is >> tidString;
bool ok = TypeId::LookupByNameFailSafe (tidString, &tid);
if (!ok)
{
is.setstate (std::ios_base::badbit);
}
return is;
}
ATTRIBUTE_HELPER_CPP (TypeId);
bool operator == (TypeId a, TypeId b)
{
return a.m_tid == b.m_tid;
}
bool operator != (TypeId a, TypeId b)
{
return a.m_tid != b.m_tid;
}
/*********************************************************************
* The AttributeList container implementation
*********************************************************************/
AttributeList::AttributeList ()
{}
AttributeList::AttributeList (const AttributeList &o)
{
for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
{
struct Attr attr;
attr.checker = i->checker;
attr.value = i->value.Copy ();
m_attributes.push_back (attr);
}
}
AttributeList &
AttributeList::operator = (const AttributeList &o)
{
Reset ();
for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
{
struct Attr attr;
attr.checker = i->checker;
attr.value = i->value.Copy ();
m_attributes.push_back (attr);
}
return *this;
}
AttributeList::~AttributeList ()
{
Reset ();
}
void
AttributeList::Set (std::string name, Attribute value)
{
struct TypeId::AttributeInfo info;
bool ok = TypeId::LookupAttributeByFullName (name, &info);
if (!ok)
{
NS_FATAL_ERROR ("Could not find attribute "<<name);
}
ok = DoSet (&info, value);
if (!ok)
{
NS_FATAL_ERROR ("Could not set value for attribute "<<name);
}
}
bool
AttributeList::SetFailSafe (std::string name, Attribute value)
{
struct TypeId::AttributeInfo info;
bool ok = TypeId::LookupAttributeByFullName (name, &info);
if (!ok)
{
return false;
}
ok = DoSet (&info, value);
return ok;
}
void
AttributeList::SetWithTid (TypeId tid, std::string name, Attribute value)
{
struct TypeId::AttributeInfo info;
bool ok = tid.LookupAttributeByName (name, &info);
if (!ok)
{
NS_FATAL_ERROR ("Could not find attribute "<<tid.GetName ()<<"::"<<name);
}
ok = DoSet (&info, value);
if (!ok)
{
NS_FATAL_ERROR ("Could not set value for attribute "<<tid.GetName ()<<"::"<<name);
}
}
void
AttributeList::DoSetOne (Ptr<const AttributeChecker> checker, Attribute value)
{
// get rid of any previous value stored in this
// vector of values.
for (Attrs::iterator k = m_attributes.begin (); k != m_attributes.end (); k++)
{
if (k->checker == checker)
{
m_attributes.erase (k);
break;
}
}
// store the new value.
struct Attr attr;
attr.checker = checker;
attr.value = value.Copy ();
m_attributes.push_back (attr);
}
bool
AttributeList::DoSet (struct TypeId::AttributeInfo *info, Attribute value)
{
if (info->checker == 0)
{
return false;
}
bool ok = info->checker->Check (value);
if (!ok)
{
// attempt to convert to string.
const StringValue *str = value.DynCast<const StringValue *> ();
if (str == 0)
{
return false;
}
// attempt to convert back to value.
Attribute v = info->checker->Create ();
ok = v.DeserializeFromString (str->Get ().Get (), info->checker);
if (!ok)
{
return false;
}
ok = info->checker->Check (v);
if (!ok)
{
return false;
}
value = v;
}
DoSetOne (info->checker, value);
return true;
}
void
AttributeList::Reset (void)
{
m_attributes.clear ();
}
AttributeList *
AttributeList::GetGlobal (void)
{
return Singleton<AttributeList>::Get ();
}
std::string
AttributeList::LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const
{
for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
{
TypeId tid = TypeId::GetRegistered (i);
for (uint32_t j = 0; j < tid.GetAttributeListN (); j++)
{
if (checker == tid.GetAttributeChecker (j))
{
return tid.GetAttributeFullName (j);
}
}
}
NS_FATAL_ERROR ("Could not find requested Accessor.");
// quiet compiler.
return "";
}
std::string
AttributeList::SerializeToString (void) const
{
std::ostringstream oss;
for (Attrs::const_iterator i = m_attributes.begin (); i != m_attributes.end (); i++)
{
std::string name = LookupAttributeFullNameByChecker (i->checker);
oss << name << "=" << i->value.SerializeToString (i->checker);
if (i != m_attributes.end ())
{
oss << "|";
}
}
return oss.str ();
}
bool
AttributeList::DeserializeFromString (std::string str)
{
Reset ();
std::string::size_type cur;
cur = 0;
do {
std::string::size_type equal = str.find ("=", cur);
if (equal == std::string::npos)
{
// XXX: invalid attribute.
break;
}
else
{
std::string name = str.substr (cur, equal-cur);
struct TypeId::AttributeInfo info;
if (!TypeId::LookupAttributeByFullName (name, &info))
{
// XXX invalid name.
break;
}
else
{
std::string::size_type next = str.find ("|", cur);
std::string value;
if (next == std::string::npos)
{
value = str.substr (equal+1, str.size () - (equal+1));
cur = str.size ();
}
else
{
value = str.substr (equal+1, next - (equal+1));
cur++;
}
Attribute val = info.checker->Create ();
bool ok = val.DeserializeFromString (value, info.checker);
if (!ok)
{
// XXX invalid value
break;
}
else
{
DoSetOne (info.checker, val);
}
}
}
} while (cur != str.size ());
return true;
}
/*********************************************************************
* The Object implementation
*********************************************************************/

View File

@@ -29,19 +29,7 @@
#include "attribute.h"
#include "object-base.h"
#include "attribute-helper.h"
/**
* This macro should be invoked once for every class which
* defines a new GetTypeId method.
*/
#define NS_OBJECT_ENSURE_REGISTERED(type) \
static struct X##type##RegistrationClass \
{ \
X##type##RegistrationClass () { \
ns3::TypeId tid = type::GetTypeId (); \
tid.GetParent (); \
} \
} x_##type##RegistrationVariable
#include "attribute-list.h"
namespace ns3 {
@@ -53,363 +41,6 @@ class AttributeValue;
class AttributeList;
class TraceSourceAccessor;
/**
* \brief a unique identifier for an interface.
*
* This class records a lot of meta-information about a
* subclass of the Object base class:
* - the base class of the subclass
* - the set of accessible constructors in the subclass
* - the set of 'attributes' accessible in the subclass
*/
class TypeId
{
public:
enum {
/**
* The attribute can be read
*/
ATTR_GET = 1<<0,
/**
* The attribute can be written
*/
ATTR_SET = 1<<1,
/**
* The attribute can be written at construction-time.
*/
ATTR_CONSTRUCT = 1<<2,
/**
* The attribute can be read, and written at any time.
*/
ATTR_SGC = ATTR_GET | ATTR_SET | ATTR_CONSTRUCT,
};
/**
* \param name the name of the requested TypeId
* \returns the unique id associated with the requested
* name.
*
* This method cannot fail: it will crash if the input
* name is not a valid TypeId name.
*/
static TypeId LookupByName (std::string name);
/**
* \param name the name of the requested TypeId
* \param tid a pointer to the TypeId instance where the
* result of this function should be stored.
* \returns true if the requested name was found, false otherwise.
*/
static bool LookupByNameFailSafe (std::string name, TypeId *tid);
/**
* \returns the number of TypeId instances registered.
*/
static uint32_t GetRegisteredN (void);
/**
* \param i index
* \returns the TypeId instance whose index is i.
*/
static TypeId GetRegistered (uint32_t i);
/**
* \param name the name of the interface to construct.
*
* No two instances can share the same name. The name is expected to be
* the full c++ typename of associated c++ object.
*/
TypeId (const char * name);
/**
* \returns the parent of this TypeId
*
* This method cannot fail. It will return itself
* if this TypeId has no parent. i.e., it is at the top
* of the TypeId hierarchy. Currently, this is the
* case for the TypeId associated to the Object class
* only.
*/
TypeId GetParent (void) const;
/**
* \returns the name of the group associated to this TypeId.
*/
std::string GetGroupName (void) const;
/**
* \returns the fully-qualified C++ typename of this TypeId.
*/
std::string GetTypeName (void) const;
/**
* \returns the name of this interface.
*/
std::string GetName (void) const;
/**
* \returns true if this TypeId has a constructor
*/
bool HasConstructor (void) const;
/**
* \returns the number of attributes associated to this TypeId
*/
uint32_t GetAttributeListN (void) const;
/**
* \param i index into attribute array
* \returns the name associated to the attribute whose
* index is i.
*/
std::string GetAttributeName (uint32_t i) const;
std::string GetAttributeHelp (uint32_t i) const;
/**
* \param i index into attribute array
* \returns the full name associated to the attribute whose
* index is i.
*/
std::string GetAttributeFullName (uint32_t i) const;
Attribute GetAttributeInitialValue (uint32_t i) const;
uint32_t GetAttributeFlags (uint32_t i) const;
Ptr<const AttributeChecker> GetAttributeChecker (uint32_t i) const;
uint32_t GetTraceSourceN (void) const;
std::string GetTraceSourceName (uint32_t i) const;
std::string GetTraceSourceHelp (uint32_t i) const;
Ptr<const TraceSourceAccessor> GetTraceSourceAccessor (uint32_t i) const;
Callback<ObjectBase *> GetConstructor (void) const;
bool MustHideFromDocumentation (void) const;
/**
* \param tid the TypeId of the base class.
* \return this TypeId instance.
*
* Record in this TypeId which TypeId is the TypeId
* of the base class of the subclass.
*/
TypeId SetParent (TypeId tid);
/**
* \return this TypeId instance.
*
* Record in this TypeId which TypeId is the TypeId
* of the base class of the subclass.
*/
template <typename T>
TypeId SetParent (void);
/**
* \param groupName the name of the group this TypeId belongs to.
* \returns this TypeId instance.
*
* The group name is purely an advisory information used to
* group together types according to a user-specific grouping
* scheme.
*/
TypeId SetGroupName (std::string groupName);
/**
* \param typeName the fully-qualified C++ typename of this TypeId.
* \returns this TypeId instance.
*/
TypeId SetTypeName (std::string typeName);
/**
* \returns this TypeId instance
*
* Record in this TypeId the fact that the default constructor
* is accessible.
*/
template <typename T>
TypeId AddConstructor (void);
/**
* \param name the name of the new attribute
* \param help some help text which describes the purpose of this
* attribute.
* \param initialValue the initial value for this attribute.
* \param accessor an instance of the associated AttributeAccessor subclass.
* \param checker an instance of the associated AttributeChecker subclass.
* \returns this TypeId instance
*
* Record in this TypeId the fact that a new attribute exists.
*/
TypeId AddAttribute (std::string name,
std::string help,
Attribute initialValue,
Ptr<const AttributeAccessor> accessor,
Ptr<const AttributeChecker> checker);
/**
* \param name the name of the new attribute
* \param help some help text which describes the purpose of this
* attribute
* \param flags flags which describe how this attribute can be read and/or written.
* \param initialValue the initial value for this attribute.
* \param accessor an instance of the associated AttributeAccessor subclass.
* \param checker an instance of the associated AttributeChecker subclass.
* \returns this TypeId instance
*
* Record in this TypeId the fact that a new attribute exists.
*/
TypeId AddAttribute (std::string name,
std::string help,
uint32_t flags,
Attribute initialValue,
Ptr<const AttributeAccessor> accessor,
Ptr<const AttributeChecker> checker);
/**
* \param name the name of the new trace source
* \param help some help text which describes the purpose of this
* trace source.
* \param accessor a pointer to a TraceSourceAccessor which can be
* used to connect/disconnect sinks to this trace source.
* \returns this TypeId instance.
*/
TypeId AddTraceSource (std::string name,
std::string help,
Ptr<const TraceSourceAccessor> accessor);
TypeId HideFromDocumentation (void);
/**
* \brief store together a set of attribute properties.
*/
struct AttributeInfo {
// The accessor associated to the attribute.
Ptr<const AttributeAccessor> accessor;
// The initial value associated to the attribute.
Attribute initialValue;
// The set of access control flags associated to the attribute.
uint32_t flags;
// The checker associated to the attribute.
Ptr<const AttributeChecker> checker;
};
/**
* \param name the name of the requested attribute
* \param info a pointer to the TypeId::AttributeInfo data structure
* where the result value of this method will be stored.
* \returns true if the requested attribute could be found, false otherwise.
*/
bool LookupAttributeByName (std::string name, struct AttributeInfo *info) const;
// construct an invalid TypeId.
TypeId ();
~TypeId ();
ATTRIBUTE_HELPER_HEADER_1 (TypeId);
private:
friend class Object;
friend class AttributeList;
friend bool operator == (TypeId a, TypeId b);
friend bool operator != (TypeId a, TypeId b);
Ptr<const TraceSourceAccessor> LookupTraceSourceByName (std::string name) const;
/**
* \param fullName the full name of the requested attribute
* \param info a pointer to the TypeId::AttributeInfo data structure
* where the result value of this method will be stored.
* \returns the Accessor associated to the requested attribute
*/
static bool LookupAttributeByFullName (std::string fullName, struct AttributeInfo *info);
explicit TypeId (uint16_t tid);
void DoAddConstructor (Callback<ObjectBase *> callback);
Ptr<const AttributeAccessor> GetAttributeAccessor (uint32_t i) const;
uint16_t m_tid;
};
std::ostream & operator << (std::ostream &os, TypeId tid);
std::istream & operator >> (std::istream &is, TypeId &tid);
ATTRIBUTE_HELPER_HEADER_2 (TypeId);
/**
* \brief a container of attributes to be used during object's construction
* and in ns3::Object::Set.
*
*/
class AttributeList
{
public:
AttributeList ();
AttributeList (const AttributeList &o);
AttributeList &operator = (const AttributeList &o);
~AttributeList ();
/**
* \param name the full name of the attribute to set
* \param value the value to set
*
* This method checks that a attribute with the requested
* name exists and that the value specified is an acceptable
* value of that attribute. If any of these checks fails,
* the program terminates with a message.
*/
void Set (std::string name, Attribute value);
/**
* \param name the full name of the attribute to set
* \param value the value to set
* \returns true if the requested attribute exists and could be
* stored, false otherwise.
*/
bool SetFailSafe (std::string name, Attribute value);
/**
* \param tid the TypeId associated to this attribute
* \param name the name (not full!) of the attribute
* \param value the value to set
*
* This method checks that a attribute with the requested
* name exists and that the value specified is an acceptable
* value of that attribute. If any of these checks fails,
* the program terminates with a message.
*/
void SetWithTid (TypeId tid, std::string name, Attribute value);
/**
* Clear the content of this instance.
*/
void Reset (void);
/**
* \returns the global attribute container
*
* The global attribute container can be used to specify
* a set of attribute values without having to re-specify
* them for each object when it is created. This container
* is checked only during object construction and
* it is always checked last, after any per-object
* container is checked.
*/
static AttributeList *GetGlobal (void);
// XXX: untested.
std::string SerializeToString (void) const;
bool DeserializeFromString (std::string value);
private:
friend class Object;
struct Attr {
Ptr<const AttributeChecker> checker;
Attribute value;
};
typedef std::vector<struct Attr> Attrs;
typedef Attrs::iterator Iterator;
typedef Attrs::const_iterator CIterator;
bool DoSet (struct TypeId::AttributeInfo *info, Attribute param);
void DoSetOne (Ptr<const AttributeChecker> checker, Attribute param);
std::string LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const;
Attrs m_attributes;
};
/**
* \brief a base class which provides memory management and object aggregation
*

687
src/core/type-id.cc Normal file
View File

@@ -0,0 +1,687 @@
#include "type-id.h"
#include "singleton.h"
#include "trace-source-accessor.h"
#include <vector>
#include <sstream>
/*********************************************************************
* Helper code
*********************************************************************/
namespace {
class IidManager
{
public:
IidManager ();
uint16_t AllocateUid (std::string name);
void SetParent (uint16_t uid, uint16_t parent);
void SetTypeName (uint16_t uid, std::string typeName);
void SetGroupName (uint16_t uid, std::string groupName);
void AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback);
void HideFromDocumentation (uint16_t uid);
uint16_t GetUid (std::string name) const;
std::string GetName (uint16_t uid) const;
uint16_t GetParent (uint16_t uid) const;
std::string GetTypeName (uint16_t uid) const;
std::string GetGroupName (uint16_t uid) const;
ns3::Callback<ns3::ObjectBase *> GetConstructor (uint16_t uid) const;
bool HasConstructor (uint16_t uid) const;
uint32_t GetRegisteredN (void) const;
uint16_t GetRegistered (uint32_t i) const;
void AddAttribute (uint16_t uid,
std::string name,
std::string help,
uint32_t flags,
ns3::Attribute initialValue,
ns3::Ptr<const ns3::AttributeAccessor> spec,
ns3::Ptr<const ns3::AttributeChecker> checker);
uint32_t GetAttributeListN (uint16_t uid) const;
std::string GetAttributeName (uint16_t uid, uint32_t i) const;
std::string GetAttributeHelp (uint16_t uid, uint32_t i) const;
uint32_t GetAttributeFlags (uint16_t uid, uint32_t i) const;
ns3::Attribute GetAttributeInitialValue (uint16_t uid, uint32_t i) const;
ns3::Ptr<const ns3::AttributeAccessor> GetAttributeAccessor (uint16_t uid, uint32_t i) const;
ns3::Ptr<const ns3::AttributeChecker> GetAttributeChecker (uint16_t uid, uint32_t i) const;
void AddTraceSource (uint16_t uid,
std::string name,
std::string help,
ns3::Ptr<const ns3::TraceSourceAccessor> accessor);
uint32_t GetTraceSourceN (uint16_t uid) const;
std::string GetTraceSourceName (uint16_t uid, uint32_t i) const;
std::string GetTraceSourceHelp (uint16_t uid, uint32_t i) const;
ns3::Ptr<const ns3::TraceSourceAccessor> GetTraceSourceAccessor (uint16_t uid, uint32_t i) const;
bool MustHideFromDocumentation (uint16_t uid) const;
private:
struct AttributeInformation {
std::string name;
std::string help;
uint32_t flags;
ns3::Attribute initialValue;
ns3::Ptr<const ns3::AttributeAccessor> param;
ns3::Ptr<const ns3::AttributeChecker> checker;
};
struct TraceSourceInformation {
std::string name;
std::string help;
ns3::Ptr<const ns3::TraceSourceAccessor> accessor;
};
struct IidInformation {
std::string name;
uint16_t parent;
std::string typeName;
std::string groupName;
bool hasConstructor;
ns3::Callback<ns3::ObjectBase *> constructor;
bool mustHideFromDocumentation;
std::vector<struct AttributeInformation> attributes;
std::vector<struct TraceSourceInformation> traceSources;
};
typedef std::vector<struct IidInformation>::const_iterator Iterator;
struct IidManager::IidInformation *LookupInformation (uint16_t uid) const;
std::vector<struct IidInformation> m_information;
};
IidManager::IidManager ()
{}
uint16_t
IidManager::AllocateUid (std::string name)
{
uint16_t j = 1;
for (Iterator i = m_information.begin (); i != m_information.end (); i++)
{
if (i->name == name)
{
NS_FATAL_ERROR ("Trying to allocate twice the same uid: " << name);
return 0;
}
j++;
}
struct IidInformation information;
information.name = name;
information.parent = 0;
information.typeName = "";
information.groupName = "";
information.hasConstructor = false;
information.mustHideFromDocumentation = false;
m_information.push_back (information);
uint32_t uid = m_information.size ();
NS_ASSERT (uid <= 0xffff);
return uid;
}
struct IidManager::IidInformation *
IidManager::LookupInformation (uint16_t uid) const
{
NS_ASSERT (uid <= m_information.size ());
return const_cast<struct IidInformation *> (&m_information[uid-1]);
}
void
IidManager::SetParent (uint16_t uid, uint16_t parent)
{
NS_ASSERT (parent <= m_information.size ());
struct IidInformation *information = LookupInformation (uid);
information->parent = parent;
}
void
IidManager::SetTypeName (uint16_t uid, std::string typeName)
{
struct IidInformation *information = LookupInformation (uid);
information->typeName = typeName;
}
void
IidManager::SetGroupName (uint16_t uid, std::string groupName)
{
struct IidInformation *information = LookupInformation (uid);
information->groupName = groupName;
}
void
IidManager::HideFromDocumentation (uint16_t uid)
{
struct IidInformation *information = LookupInformation (uid);
information->mustHideFromDocumentation = true;
}
void
IidManager::AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback)
{
struct IidInformation *information = LookupInformation (uid);
if (information->hasConstructor)
{
NS_FATAL_ERROR (information->name<<" already has a constructor.");
}
information->hasConstructor = true;
information->constructor = callback;
}
uint16_t
IidManager::GetUid (std::string name) const
{
uint32_t j = 1;
for (Iterator i = m_information.begin (); i != m_information.end (); i++)
{
if (i->name == name)
{
NS_ASSERT (j <= 0xffff);
return j;
}
j++;
}
return 0;
}
std::string
IidManager::GetName (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->name;
}
uint16_t
IidManager::GetParent (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->parent;
}
std::string
IidManager::GetTypeName (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->typeName;
}
std::string
IidManager::GetGroupName (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->groupName;
}
ns3::Callback<ns3::ObjectBase *>
IidManager::GetConstructor (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
if (!information->hasConstructor)
{
NS_FATAL_ERROR ("Requested constructor for "<<information->name<<" but it does not have one.");
}
return information->constructor;
}
bool
IidManager::HasConstructor (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->hasConstructor;
}
uint32_t
IidManager::GetRegisteredN (void) const
{
return m_information.size ();
}
uint16_t
IidManager::GetRegistered (uint32_t i) const
{
return i + 1;
}
void
IidManager::AddAttribute (uint16_t uid,
std::string name,
std::string help,
uint32_t flags,
ns3::Attribute initialValue,
ns3::Ptr<const ns3::AttributeAccessor> spec,
ns3::Ptr<const ns3::AttributeChecker> checker)
{
struct IidInformation *information = LookupInformation (uid);
for (std::vector<struct AttributeInformation>::const_iterator j = information->attributes.begin ();
j != information->attributes.end (); j++)
{
if (j->name == name)
{
NS_FATAL_ERROR ("Registered the same attribute twice name=\""<<name<<"\" in TypeId=\""<<information->name<<"\"");
return;
}
}
struct AttributeInformation param;
param.name = name;
param.help = help;
param.flags = flags;
param.initialValue = initialValue;
param.param = spec;
param.checker = checker;
information->attributes.push_back (param);
}
uint32_t
IidManager::GetAttributeListN (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->attributes.size ();
}
std::string
IidManager::GetAttributeName (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->attributes.size ());
return information->attributes[i].name;
}
std::string
IidManager::GetAttributeHelp (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->attributes.size ());
return information->attributes[i].help;
}
uint32_t
IidManager::GetAttributeFlags (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->attributes.size ());
return information->attributes[i].flags;
}
ns3::Attribute
IidManager::GetAttributeInitialValue (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->attributes.size ());
return information->attributes[i].initialValue;
}
ns3::Ptr<const ns3::AttributeAccessor>
IidManager::GetAttributeAccessor (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->attributes.size ());
return information->attributes[i].param;
}
ns3::Ptr<const ns3::AttributeChecker>
IidManager::GetAttributeChecker (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->attributes.size ());
return information->attributes[i].checker;
}
void
IidManager::AddTraceSource (uint16_t uid,
std::string name,
std::string help,
ns3::Ptr<const ns3::TraceSourceAccessor> accessor)
{
struct IidInformation *information = LookupInformation (uid);
struct TraceSourceInformation source;
source.name = name;
source.help = help;
source.accessor = accessor;
information->traceSources.push_back (source);
}
uint32_t
IidManager::GetTraceSourceN (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->traceSources.size ();
}
std::string
IidManager::GetTraceSourceName (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->traceSources.size ());
return information->traceSources[i].name;
}
std::string
IidManager::GetTraceSourceHelp (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->traceSources.size ());
return information->traceSources[i].help;
}
ns3::Ptr<const ns3::TraceSourceAccessor>
IidManager::GetTraceSourceAccessor (uint16_t uid, uint32_t i) const
{
struct IidInformation *information = LookupInformation (uid);
NS_ASSERT (i < information->traceSources.size ());
return information->traceSources[i].accessor;
}
bool
IidManager::MustHideFromDocumentation (uint16_t uid) const
{
struct IidInformation *information = LookupInformation (uid);
return information->mustHideFromDocumentation;
}
} // anonymous namespace
namespace ns3 {
/*********************************************************************
* The TypeId class
*********************************************************************/
TypeId::TypeId ()
: m_tid (0)
{}
TypeId::TypeId (const char *name)
{
uint16_t uid = Singleton<IidManager>::Get ()->AllocateUid (name);
NS_ASSERT (uid != 0);
m_tid = uid;
}
TypeId::TypeId (uint16_t tid)
: m_tid (tid)
{}
TypeId::~TypeId ()
{}
TypeId
TypeId::LookupByName (std::string name)
{
uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
NS_ASSERT (uid != 0);
return TypeId (uid);
}
bool
TypeId::LookupByNameFailSafe (std::string name, TypeId *tid)
{
uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
if (uid == 0)
{
return false;
}
*tid = TypeId (uid);
return true;
}
bool
TypeId::LookupAttributeByFullName (std::string fullName, struct TypeId::AttributeInfo *info)
{
std::string::size_type pos = fullName.rfind ("::");
if (pos == std::string::npos)
{
return 0;
}
std::string tidName = fullName.substr (0, pos);
std::string paramName = fullName.substr (pos+2, fullName.size () - (pos+2));
TypeId tid;
bool ok = LookupByNameFailSafe (tidName, &tid);
if (!ok)
{
return false;
}
return tid.LookupAttributeByName (paramName, info);
}
uint32_t
TypeId::GetRegisteredN (void)
{
return Singleton<IidManager>::Get ()->GetRegisteredN ();
}
TypeId
TypeId::GetRegistered (uint32_t i)
{
return TypeId (Singleton<IidManager>::Get ()->GetRegistered (i));
}
bool
TypeId::LookupAttributeByName (std::string name, struct TypeId::AttributeInfo *info) const
{
TypeId tid;
TypeId nextTid = *this;
do {
tid = nextTid;
for (uint32_t i = 0; i < tid.GetAttributeListN (); i++)
{
std::string paramName = tid.GetAttributeName (i);
if (paramName == name)
{
info->accessor = tid.GetAttributeAccessor (i);
info->flags = tid.GetAttributeFlags (i);
info->initialValue = tid.GetAttributeInitialValue (i);
info->checker = tid.GetAttributeChecker (i);
return true;
}
}
nextTid = tid.GetParent ();
} while (nextTid != tid);
return false;
}
TypeId
TypeId::SetParent (TypeId tid)
{
Singleton<IidManager>::Get ()->SetParent (m_tid, tid.m_tid);
return *this;
}
TypeId
TypeId::SetGroupName (std::string groupName)
{
Singleton<IidManager>::Get ()->SetGroupName (m_tid, groupName);
return *this;
}
TypeId
TypeId::SetTypeName (std::string typeName)
{
Singleton<IidManager>::Get ()->SetTypeName (m_tid, typeName);
return *this;
}
TypeId
TypeId::GetParent (void) const
{
uint16_t parent = Singleton<IidManager>::Get ()->GetParent (m_tid);
return TypeId (parent);
}
std::string
TypeId::GetGroupName (void) const
{
std::string groupName = Singleton<IidManager>::Get ()->GetGroupName (m_tid);
return groupName;
}
std::string
TypeId::GetTypeName (void) const
{
std::string typeName = Singleton<IidManager>::Get ()->GetTypeName (m_tid);
return typeName;
}
std::string
TypeId::GetName (void) const
{
std::string name = Singleton<IidManager>::Get ()->GetName (m_tid);
return name;
}
bool
TypeId::HasConstructor (void) const
{
bool hasConstructor = Singleton<IidManager>::Get ()->HasConstructor (m_tid);
return hasConstructor;
}
void
TypeId::DoAddConstructor (Callback<ObjectBase *> cb)
{
Singleton<IidManager>::Get ()->AddConstructor (m_tid, cb);
}
TypeId
TypeId::AddAttribute (std::string name,
std::string help,
Attribute initialValue,
Ptr<const AttributeAccessor> param,
Ptr<const AttributeChecker> checker)
{
Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, initialValue, param, checker);
return *this;
}
TypeId
TypeId::AddAttribute (std::string name,
std::string help,
uint32_t flags,
Attribute initialValue,
Ptr<const AttributeAccessor> param,
Ptr<const AttributeChecker> checker)
{
Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, flags, initialValue, param, checker);
return *this;
}
Callback<ObjectBase *>
TypeId::GetConstructor (void) const
{
Callback<ObjectBase *> cb = Singleton<IidManager>::Get ()->GetConstructor (m_tid);
return cb;
}
bool
TypeId::MustHideFromDocumentation (void) const
{
bool mustHide = Singleton<IidManager>::Get ()->MustHideFromDocumentation (m_tid);
return mustHide;
}
uint32_t
TypeId::GetAttributeListN (void) const
{
uint32_t n = Singleton<IidManager>::Get ()->GetAttributeListN (m_tid);
return n;
}
std::string
TypeId::GetAttributeName (uint32_t i) const
{
std::string name = Singleton<IidManager>::Get ()->GetAttributeName (m_tid, i);
return name;
}
std::string
TypeId::GetAttributeHelp (uint32_t i) const
{
std::string help = Singleton<IidManager>::Get ()->GetAttributeHelp (m_tid, i);
return help;
}
std::string
TypeId::GetAttributeFullName (uint32_t i) const
{
return GetName () + "::" + GetAttributeName (i);
}
Attribute
TypeId::GetAttributeInitialValue (uint32_t i) const
{
Attribute value = Singleton<IidManager>::Get ()->GetAttributeInitialValue (m_tid, i);
return value;
}
Ptr<const AttributeAccessor>
TypeId::GetAttributeAccessor (uint32_t i) const
{
// Used exclusively by the Object class.
Ptr<const AttributeAccessor> param = Singleton<IidManager>::Get ()->GetAttributeAccessor (m_tid, i);
return param;
}
uint32_t
TypeId::GetAttributeFlags (uint32_t i) const
{
// Used exclusively by the Object class.
uint32_t flags = Singleton<IidManager>::Get ()->GetAttributeFlags (m_tid, i);
return flags;
}
Ptr<const AttributeChecker>
TypeId::GetAttributeChecker (uint32_t i) const
{
// Used exclusively by the Object class.
Ptr<const AttributeChecker> checker = Singleton<IidManager>::Get ()->GetAttributeChecker (m_tid, i);
return checker;
}
uint32_t
TypeId::GetTraceSourceN (void) const
{
return Singleton<IidManager>::Get ()->GetTraceSourceN (m_tid);
}
std::string
TypeId::GetTraceSourceName (uint32_t i) const
{
return Singleton<IidManager>::Get ()->GetTraceSourceName (m_tid, i);
}
std::string
TypeId::GetTraceSourceHelp (uint32_t i) const
{
return Singleton<IidManager>::Get ()->GetTraceSourceHelp (m_tid, i);
}
Ptr<const TraceSourceAccessor>
TypeId::GetTraceSourceAccessor (uint32_t i) const
{
return Singleton<IidManager>::Get ()->GetTraceSourceAccessor (m_tid, i);
}
TypeId
TypeId::AddTraceSource (std::string name,
std::string help,
Ptr<const TraceSourceAccessor> accessor)
{
Singleton<IidManager>::Get ()->AddTraceSource (m_tid, name, help, accessor);
return *this;
}
TypeId
TypeId::HideFromDocumentation (void)
{
Singleton<IidManager>::Get ()->HideFromDocumentation (m_tid);
return *this;
}
Ptr<const TraceSourceAccessor>
TypeId::LookupTraceSourceByName (std::string name) const
{
TypeId tid;
TypeId nextTid = *this;
do {
tid = nextTid;
for (uint32_t i = 0; i < tid.GetTraceSourceN (); i++)
{
std::string srcName = tid.GetTraceSourceName (i);
if (srcName == name)
{
return tid.GetTraceSourceAccessor (i);
}
}
nextTid = tid.GetParent ();
} while (nextTid != tid);
return 0;
}
std::ostream & operator << (std::ostream &os, TypeId tid)
{
os << tid.GetName ();
return os;
}
std::istream & operator >> (std::istream &is, TypeId &tid)
{
std::string tidString;
is >> tidString;
bool ok = TypeId::LookupByNameFailSafe (tidString, &tid);
if (!ok)
{
is.setstate (std::ios_base::badbit);
}
return is;
}
ATTRIBUTE_HELPER_CPP (TypeId);
bool operator == (TypeId a, TypeId b)
{
return a.m_tid == b.m_tid;
}
bool operator != (TypeId a, TypeId b)
{
return a.m_tid != b.m_tid;
}
} // namespace ns3

292
src/core/type-id.h Normal file
View File

@@ -0,0 +1,292 @@
#ifndef TYPE_ID_H
#define TYPE_ID_H
#include "attribute.h"
#include "attribute-accessor-helper.h"
#include "attribute-helper.h"
#include "callback.h"
#include <string>
#include <stdint.h>
namespace ns3 {
class ObjectBase;
class TraceSourceAccessor;
/**
* \brief a unique identifier for an interface.
*
* This class records a lot of meta-information about a
* subclass of the Object base class:
* - the base class of the subclass
* - the set of accessible constructors in the subclass
* - the set of 'attributes' accessible in the subclass
*/
class TypeId
{
public:
enum {
/**
* The attribute can be read
*/
ATTR_GET = 1<<0,
/**
* The attribute can be written
*/
ATTR_SET = 1<<1,
/**
* The attribute can be written at construction-time.
*/
ATTR_CONSTRUCT = 1<<2,
/**
* The attribute can be read, and written at any time.
*/
ATTR_SGC = ATTR_GET | ATTR_SET | ATTR_CONSTRUCT,
};
/**
* \param name the name of the requested TypeId
* \returns the unique id associated with the requested
* name.
*
* This method cannot fail: it will crash if the input
* name is not a valid TypeId name.
*/
static TypeId LookupByName (std::string name);
/**
* \param name the name of the requested TypeId
* \param tid a pointer to the TypeId instance where the
* result of this function should be stored.
* \returns true if the requested name was found, false otherwise.
*/
static bool LookupByNameFailSafe (std::string name, TypeId *tid);
/**
* \returns the number of TypeId instances registered.
*/
static uint32_t GetRegisteredN (void);
/**
* \param i index
* \returns the TypeId instance whose index is i.
*/
static TypeId GetRegistered (uint32_t i);
/**
* \param name the name of the interface to construct.
*
* No two instances can share the same name. The name is expected to be
* the full c++ typename of associated c++ object.
*/
TypeId (const char * name);
/**
* \returns the parent of this TypeId
*
* This method cannot fail. It will return itself
* if this TypeId has no parent. i.e., it is at the top
* of the TypeId hierarchy. Currently, this is the
* case for the TypeId associated to the Object class
* only.
*/
TypeId GetParent (void) const;
/**
* \returns the name of the group associated to this TypeId.
*/
std::string GetGroupName (void) const;
/**
* \returns the fully-qualified C++ typename of this TypeId.
*/
std::string GetTypeName (void) const;
/**
* \returns the name of this interface.
*/
std::string GetName (void) const;
/**
* \returns true if this TypeId has a constructor
*/
bool HasConstructor (void) const;
/**
* \returns the number of attributes associated to this TypeId
*/
uint32_t GetAttributeListN (void) const;
/**
* \param i index into attribute array
* \returns the name associated to the attribute whose
* index is i.
*/
std::string GetAttributeName (uint32_t i) const;
std::string GetAttributeHelp (uint32_t i) const;
/**
* \param i index into attribute array
* \returns the full name associated to the attribute whose
* index is i.
*/
std::string GetAttributeFullName (uint32_t i) const;
Attribute GetAttributeInitialValue (uint32_t i) const;
uint32_t GetAttributeFlags (uint32_t i) const;
Ptr<const AttributeChecker> GetAttributeChecker (uint32_t i) const;
uint32_t GetTraceSourceN (void) const;
std::string GetTraceSourceName (uint32_t i) const;
std::string GetTraceSourceHelp (uint32_t i) const;
Ptr<const TraceSourceAccessor> GetTraceSourceAccessor (uint32_t i) const;
Ptr<const AttributeAccessor> GetAttributeAccessor (uint32_t i) const;
Callback<ObjectBase *> GetConstructor (void) const;
bool MustHideFromDocumentation (void) const;
/**
* \param tid the TypeId of the base class.
* \return this TypeId instance.
*
* Record in this TypeId which TypeId is the TypeId
* of the base class of the subclass.
*/
TypeId SetParent (TypeId tid);
/**
* \return this TypeId instance.
*
* Record in this TypeId which TypeId is the TypeId
* of the base class of the subclass.
*/
template <typename T>
TypeId SetParent (void);
/**
* \param groupName the name of the group this TypeId belongs to.
* \returns this TypeId instance.
*
* The group name is purely an advisory information used to
* group together types according to a user-specific grouping
* scheme.
*/
TypeId SetGroupName (std::string groupName);
/**
* \param typeName the fully-qualified C++ typename of this TypeId.
* \returns this TypeId instance.
*/
TypeId SetTypeName (std::string typeName);
/**
* \returns this TypeId instance
*
* Record in this TypeId the fact that the default constructor
* is accessible.
*/
template <typename T>
TypeId AddConstructor (void);
/**
* \param name the name of the new attribute
* \param help some help text which describes the purpose of this
* attribute.
* \param initialValue the initial value for this attribute.
* \param accessor an instance of the associated AttributeAccessor subclass.
* \param checker an instance of the associated AttributeChecker subclass.
* \returns this TypeId instance
*
* Record in this TypeId the fact that a new attribute exists.
*/
TypeId AddAttribute (std::string name,
std::string help,
Attribute initialValue,
Ptr<const AttributeAccessor> accessor,
Ptr<const AttributeChecker> checker);
/**
* \param name the name of the new attribute
* \param help some help text which describes the purpose of this
* attribute
* \param flags flags which describe how this attribute can be read and/or written.
* \param initialValue the initial value for this attribute.
* \param accessor an instance of the associated AttributeAccessor subclass.
* \param checker an instance of the associated AttributeChecker subclass.
* \returns this TypeId instance
*
* Record in this TypeId the fact that a new attribute exists.
*/
TypeId AddAttribute (std::string name,
std::string help,
uint32_t flags,
Attribute initialValue,
Ptr<const AttributeAccessor> accessor,
Ptr<const AttributeChecker> checker);
/**
* \param name the name of the new trace source
* \param help some help text which describes the purpose of this
* trace source.
* \param accessor a pointer to a TraceSourceAccessor which can be
* used to connect/disconnect sinks to this trace source.
* \returns this TypeId instance.
*/
TypeId AddTraceSource (std::string name,
std::string help,
Ptr<const TraceSourceAccessor> accessor);
TypeId HideFromDocumentation (void);
/**
* \brief store together a set of attribute properties.
*/
struct AttributeInfo {
// The accessor associated to the attribute.
Ptr<const AttributeAccessor> accessor;
// The initial value associated to the attribute.
Attribute initialValue;
// The set of access control flags associated to the attribute.
uint32_t flags;
// The checker associated to the attribute.
Ptr<const AttributeChecker> checker;
};
/**
* \param name the name of the requested attribute
* \param info a pointer to the TypeId::AttributeInfo data structure
* where the result value of this method will be stored.
* \returns true if the requested attribute could be found, false otherwise.
*/
bool LookupAttributeByName (std::string name, struct AttributeInfo *info) const;
Ptr<const TraceSourceAccessor> LookupTraceSourceByName (std::string name) const;
// construct an invalid TypeId.
TypeId ();
~TypeId ();
ATTRIBUTE_HELPER_HEADER_1 (TypeId);
private:
friend class AttributeList;
friend bool operator == (TypeId a, TypeId b);
friend bool operator != (TypeId a, TypeId b);
/**
* \param fullName the full name of the requested attribute
* \param info a pointer to the TypeId::AttributeInfo data structure
* where the result value of this method will be stored.
* \returns the Accessor associated to the requested attribute
*/
static bool LookupAttributeByFullName (std::string fullName, struct AttributeInfo *info);
explicit TypeId (uint16_t tid);
void DoAddConstructor (Callback<ObjectBase *> callback);
uint16_t m_tid;
};
std::ostream & operator << (std::ostream &os, TypeId tid);
std::istream & operator >> (std::istream &is, TypeId &tid);
ATTRIBUTE_HELPER_HEADER_2 (TypeId);
} // namespace ns3
#endif /* TYPE_ID_H */

View File

@@ -31,6 +31,8 @@ def build(bld):
'callback-test.cc',
'log.cc',
'breakpoint.cc',
'type-id.cc',
'attribute-list.cc',
'object-base.cc',
'ptr.cc',
'object.cc',
@@ -73,6 +75,8 @@ def build(bld):
'empty.h',
'callback.h',
'object-base.h',
'type-id.h',
'attribute-list.h',
'ptr.h',
'object.h',
'log.h',