use FailSafe postfix in a more rigorous way.
--- a/src/core/attribute-test.cc Mon Mar 24 13:04:27 2008 -0700
+++ b/src/core/attribute-test.cc Mon Mar 24 13:04:55 2008 -0700
@@ -231,20 +231,22 @@
};
-#define CHECK_GET_STR(p,name,value) \
- { \
- std::string expected = value; \
- std::string got; \
- bool ok = p->GetAttribute (name, got); \
- NS_TEST_ASSERT (ok); \
- NS_TEST_ASSERT_EQUAL (got, expected); \
+#define CHECK_GET_STR(p,name,value) \
+ { \
+ std::string expected = value; \
+ std::string got; \
+ bool ok = p->GetAttributeAsStringFailSafe (name, got); \
+ NS_TEST_ASSERT (ok); \
+ NS_TEST_ASSERT_EQUAL (got, expected); \
}
#define CHECK_GET_PARAM(p,name,type,value) \
{ \
const type expected = value; \
type got = value; \
- Attribute v = p->GetAttribute (name); \
- got = v; \
+ Attribute v; \
+ bool ok = p->GetAttributeFailSafe (name, v); \
+ NS_TEST_ASSERT (ok); \
+ got = v; \
NS_TEST_ASSERT_EQUAL (got.Get (), expected.Get ()); \
}
--- a/src/core/object-base.cc Mon Mar 24 13:04:27 2008 -0700
+++ b/src/core/object-base.cc Mon Mar 24 13:04:55 2008 -0700
@@ -156,26 +156,27 @@
}
return DoSet (info.accessor, info.initialValue, info.checker, value);
}
-bool
-ObjectBase::GetAttribute (std::string name, std::string &value) const
+std::string
+ObjectBase::GetAttributeAsString (std::string name) const
{
struct TypeId::AttributeInfo info;
TypeId tid = GetInstanceTypeId ();
if (!tid.LookupAttributeByName (name, &info))
{
- return false;
+ NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
}
if (!(info.flags & TypeId::ATTR_GET))
{
- return false;
+ NS_FATAL_ERROR ("Attribute name="<<name<<" is not gettable for this object: tid="<<tid.GetName ());
}
Attribute v = info.checker->Create ();
bool ok = info.accessor->Get (this, v);
- if (ok)
+ if (!ok)
{
- value = v.SerializeToString (info.checker);
+ NS_FATAL_ERROR ("Attribute name="<<name<<" is not gettable for this object: tid="<<tid.GetName ());
}
- return ok;
+ std::string value = v.SerializeToString (info.checker);
+ return value;
}
Attribute
@@ -200,6 +201,46 @@
return value;
}
+bool
+ObjectBase::GetAttributeAsStringFailSafe (std::string name, std::string &value) const
+{
+ struct TypeId::AttributeInfo info;
+ TypeId tid = GetInstanceTypeId ();
+ if (!tid.LookupAttributeByName (name, &info))
+ {
+ return false;
+ }
+ if (!(info.flags & TypeId::ATTR_GET))
+ {
+ return false;
+ }
+ Attribute v = info.checker->Create ();
+ bool ok = info.accessor->Get (this, v);
+ if (ok)
+ {
+ value = v.SerializeToString (info.checker);
+ }
+ return ok;
+}
+
+bool
+ObjectBase::GetAttributeFailSafe (std::string name, Attribute &value) const
+{
+ struct TypeId::AttributeInfo info;
+ TypeId tid = GetInstanceTypeId ();
+ if (!tid.LookupAttributeByName (name, &info))
+ {
+ return false;
+ }
+ if (!(info.flags & TypeId::ATTR_GET))
+ {
+ return false;
+ }
+ value = info.checker->Create ();
+ bool ok = info.accessor->Get (this, value);
+ return ok;
+}
+
bool
ObjectBase::TraceConnectWithoutContext (std::string name, const CallbackBase &cb)
{
--- a/src/core/object-base.h Mon Mar 24 13:04:27 2008 -0700
+++ b/src/core/object-base.h Mon Mar 24 13:04:55 2008 -0700
@@ -33,6 +33,15 @@
static TypeId GetTypeId (void);
virtual ~ObjectBase ();
+
+ /**
+ * \returns the TypeId associated to the most-derived type
+ * of this instance.
+ *
+ * This method is typically implemented by ns3::Object::GetInstanceTypeId
+ * but some classes which derive from ns3::ObjectBase directly
+ * have to implement it themselves.
+ */
virtual TypeId GetInstanceTypeId (void) const = 0;
/**
@@ -52,11 +61,11 @@
bool SetAttributeFailSafe (std::string name, Attribute value);
/**
* \param name the name of the attribute to read
- * \param value a reference to the string where the value of the
- * attribute should be stored.
* \returns true if the requested attribute was found, false otherwise.
+ *
+ * If the input attribute name does not exist, this method crashes.
*/
- bool GetAttribute (std::string name, std::string &value) const;
+ std::string GetAttributeAsString (std::string name) const;
/**
* \param name the name of the attribute to read
* \returns the attribute read.
@@ -65,6 +74,21 @@
*/
Attribute GetAttribute (std::string name) const;
+ /**
+ * \param name the name of the attribute to read
+ * \param value the string where the result value should be stored
+ * \returns true if the requested attribute was found, false otherwise.
+ */
+ bool GetAttributeAsStringFailSafe (std::string name, std::string &value) const;
+ /**
+ * \param name the name of the attribute to read
+ * \param attribute the attribute where the result value should be stored
+ * \returns true if the requested attribute was found, false otherwise.
+ *
+ * If the input attribute name does not exist, this method crashes.
+ */
+ bool GetAttributeFailSafe (std::string name, Attribute &attribute) const;
+
bool TraceConnectWithoutContext (std::string name, const CallbackBase &cb);
bool TraceConnectWithoutContext (std::string name, std::string context, const CallbackBase &cb);
bool TraceDisconnectWithoutContext (std::string name, const CallbackBase &cb);