--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/attribute.cc Wed Feb 20 21:45:42 2008 +0100
@@ -0,0 +1,226 @@
+#include "attribute.h"
+#include "log.h"
+#include "fatal-error.h"
+#include <sstream>
+
+NS_LOG_COMPONENT_DEFINE ("AttributeValue");
+
+namespace ns3 {
+
+AttributeValue::AttributeValue ()
+ : m_count (1)
+{}
+AttributeValue::AttributeValue (const AttributeValue &o)
+ : m_count (1)
+{}
+AttributeValue &
+AttributeValue::operator = (const AttributeValue &o)
+{
+ return *this;
+}
+AttributeValue::~AttributeValue ()
+{}
+
+/***************************************************************
+ * Big interesting warning.
+ * ------------------------
+ *
+ * One might wonder why we re-implement a smart pointer below
+ * in the Attribute class. This is a very good question and the answer
+ * is unfortunately pretty complicated.
+ *
+ * 1) We could have requested the user to use Ptr<AttributeValue> and save us
+ * a lot of pain. This, however, does not work because our smart
+ * pointer needs a special constructor which can be used to convert
+ * objects of type Ptr<T> into a PtrValue<T> to hold the pointer.
+ *
+ * 2) We could have made the m_value member variable below a Ptr<AttributeValue>
+ * rather than store a raw pointer. This, however, does not work
+ * because this would mean that the constructor Attribute (AttributeValue *)
+ * should be morphed into Attribute (Ptr<AttributeValue>) which, unfortunately,
+ * would conflict with the template constructor Attribute (Ptr<T>)...
+ *
+ * This is definitely not fun.
+ */
+Attribute::Attribute ()
+ : m_value (0)
+{}
+Attribute::Attribute (const Attribute &o)
+ : m_value (o.m_value)
+{
+ if (m_value != 0)
+ {
+ m_value->m_count++;
+ NS_LOG_DEBUG ("this="<<m_value<<" ++count="<<m_value->m_count);
+ }
+}
+Attribute &
+Attribute::operator = (const Attribute &o)
+{
+ if (&o != this)
+ {
+ if (m_value != 0)
+ {
+ m_value->m_count--;
+ NS_LOG_DEBUG ("this="<<m_value<<" --count="<<m_value->m_count);
+ if (m_value->m_count == 0)
+ {
+ delete m_value;
+ m_value = 0;
+ }
+ }
+ m_value = o.m_value;
+ if (m_value != 0)
+ {
+ m_value->m_count++;
+ NS_LOG_DEBUG ("this="<<m_value<<" ++count="<<m_value->m_count);
+ }
+ }
+ return *this;
+}
+Attribute::~Attribute ()
+{
+ if (m_value != 0)
+ {
+ m_value->m_count--;
+ NS_LOG_DEBUG ("this="<<m_value<<" --count="<<m_value->m_count);
+ if (m_value->m_count == 0)
+ {
+ delete m_value;
+ m_value = 0;
+ }
+ }
+}
+Attribute::Attribute (AttributeValue *value)
+ : m_value (value)
+{
+ NS_LOG_DEBUG ("this="<<m_value<<" count="<<((m_value!=0)?m_value->m_count:666));
+}
+
+Attribute
+Attribute::Copy (void) const
+{
+ return m_value->Copy ();
+}
+std::string
+Attribute::SerializeToString (Ptr<const AttributeChecker> checker) const
+{
+ return m_value->SerializeToString (checker);
+}
+bool
+Attribute::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
+{
+ return m_value->DeserializeFromString (value, checker);
+}
+
+Attribute::Attribute (const char *value)
+ : m_value (new StringValue (value))
+{}
+Attribute::Attribute (std::string value)
+ : m_value (new StringValue (value))
+{}
+
+
+AttributeAccessor::AttributeAccessor ()
+ : m_count (1)
+{}
+void
+AttributeAccessor::Ref (void) const
+{
+ m_count++;
+}
+void
+AttributeAccessor::Unref (void) const
+{
+ m_count--;
+ if (m_count == 0)
+ {
+ delete this;
+ }
+}
+AttributeAccessor::~AttributeAccessor ()
+{}
+
+AttributeChecker::AttributeChecker ()
+ : m_count (1)
+{}
+void
+AttributeChecker::Ref (void) const
+{
+ m_count++;
+}
+void
+AttributeChecker::Unref (void) const
+{
+ m_count--;
+ if (m_count == 0)
+ {
+ delete this;
+ }
+}
+AttributeChecker::~AttributeChecker ()
+{}
+
+StringValue::StringValue (const char *value)
+ : m_value (value)
+{}
+StringValue::StringValue (std::string value)
+ : m_value (value)
+{}
+void
+StringValue::Set (std::string value)
+{
+ m_value = value;
+}
+std::string
+StringValue::Get (void) const
+{
+ return m_value;
+}
+Attribute
+StringValue::Copy (void) const
+{
+ return Attribute::Create<StringValue> (*this);
+}
+std::string
+StringValue::SerializeToString (Ptr<const AttributeChecker> checker) const
+{
+ return m_value;
+}
+bool
+StringValue::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
+{
+ m_value = value;
+ return true;
+}
+StringValue::StringValue (Attribute value)
+{
+ const StringValue *v = value.DynCast<const StringValue *> ();
+ if (v == 0)
+ {
+ NS_FATAL_ERROR ("Expected value of type String.");
+ }
+ m_value = v->Get ();
+}
+StringValue::operator Attribute () const
+{
+ return Attribute::Create<StringValue> (*this);
+}
+
+
+std::string
+PtrValueBase::SerializeToString (Ptr<const AttributeChecker> checker) const
+{
+ std::ostringstream oss;
+ oss << PeekObjectBase ();
+ return oss.str ();
+}
+
+bool
+PtrValueBase::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker)
+{
+ // XXX
+ return false;
+}
+
+} // namespace ns3