--- a/doc/doxygen.conf Thu Aug 09 13:38:04 2007 +0200
+++ b/doc/doxygen.conf Thu Aug 09 13:42:42 2007 +0200
@@ -999,7 +999,7 @@
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED = RUN_SELF_TESTS NS3_DEBUG_ENABLE
+PREDEFINED = RUN_SELF_TESTS NS3_DEBUG_ENABLE NS3_ASSERT_ENABLE
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
--- a/samples/main-header.cc Thu Aug 09 13:38:04 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-#include "ns3/packet.h"
-#include "ns3/header.h"
-#include <iostream>
-
-using namespace ns3;
-
-/* A sample Header implementation
- */
-class MyHeader : public Header
-{
-public:
- static uint32_t GetUid (void);
-
- MyHeader ();
- virtual ~MyHeader ();
-
- void SetData (uint16_t data);
- uint16_t GetData (void) const;
-private:
- virtual std::string DoGetName (void) const;
- virtual void PrintTo (std::ostream &os) const;
- virtual void SerializeTo (Buffer::Iterator start) const;
- virtual uint32_t DeserializeFrom (Buffer::Iterator start);
- virtual uint32_t GetSerializedSize (void) const;
-
- uint16_t m_data;
-};
-
-MyHeader::MyHeader ()
-{
- // we must provide a public default constructor,
- // implicit or explicit, but never private.
-}
-MyHeader::~MyHeader ()
-{}
-
-uint32_t
-MyHeader::GetUid (void)
-{
- // This string is used by the internals of the packet
- // code to keep track of the packet metadata.
- // You need to make sure that this string is absolutely
- // unique. The code will detect any duplicate string.
- static uint32_t uid = Header::Register<MyHeader> ("MyHeader.test.nsnam.org");
- return uid;
-}
-
-std::string
-MyHeader::DoGetName (void) const
-{
- // This string is used to identify the type of
- // my header by the packet printing routines.
- return "MYHEADER";
-}
-void
-MyHeader::PrintTo (std::ostream &os) const
-{
- // This method is invoked by the packet printing
- // routines to print the content of my header.
- os << "data=" << m_data << std::endl;
-}
-uint32_t
-MyHeader::GetSerializedSize (void) const
-{
- // we reserve 2 bytes for our header.
- return 2;
-}
-void
-MyHeader::SerializeTo (Buffer::Iterator start) const
-{
- // we can serialize two bytes at the start of the buffer.
- // we write them in network byte order.
- start.WriteHtonU16 (m_data);
-}
-uint32_t
-MyHeader::DeserializeFrom (Buffer::Iterator start)
-{
- // we can deserialize two bytes from the start of the buffer.
- // we read them in network byte order and store them
- // in host byte order.
- m_data = start.ReadNtohU16 ();
-
- // we return the number of bytes effectively read.
- return 2;
-}
-
-void
-MyHeader::SetData (uint16_t data)
-{
- m_data = data;
-}
-uint16_t
-MyHeader::GetData (void) const
-{
- return m_data;
-}
-
-
-
-int main (int argc, char *argv[])
-{
- // instantiate a header.
- MyHeader sourceHeader;
- sourceHeader.SetData (2);
-
- // instantiate a packet
- Packet p;
- // and store my header into the packet.
- p.AddHeader (sourceHeader);
-
- // print the content of my packet on the standard output.
- p.Print (std::cout);
-
- // you can now remove the header from the packet:
- MyHeader destinationHeader;
- p.RemoveHeader (destinationHeader);
-
- // and check that the destination and source
- // headers contain the same values.
- NS_ASSERT (sourceHeader.GetData () == destinationHeader.GetData ());
-
- return 0;
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/main-packet-header.cc Thu Aug 09 13:42:42 2007 +0200
@@ -0,0 +1,124 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+#include "ns3/packet.h"
+#include "ns3/header.h"
+#include <iostream>
+
+using namespace ns3;
+
+/* A sample Header implementation
+ */
+class MyHeader : public Header
+{
+public:
+ static uint32_t GetUid (void);
+
+ MyHeader ();
+ virtual ~MyHeader ();
+
+ void SetData (uint16_t data);
+ uint16_t GetData (void) const;
+
+ std::string GetName (void) const;
+ void Print (std::ostream &os) const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
+ uint32_t GetSerializedSize (void) const;
+private:
+ uint16_t m_data;
+};
+
+MyHeader::MyHeader ()
+{
+ // we must provide a public default constructor,
+ // implicit or explicit, but never private.
+}
+MyHeader::~MyHeader ()
+{}
+
+uint32_t
+MyHeader::GetUid (void)
+{
+ // This string is used by the internals of the packet
+ // code to keep track of the packet metadata.
+ // You need to make sure that this string is absolutely
+ // unique. The code will detect any duplicate string.
+ static uint32_t uid = AllocateUid<MyHeader> ("MyHeader.test.nsnam.org");
+ return uid;
+}
+
+std::string
+MyHeader::GetName (void) const
+{
+ // This string is used to identify the type of
+ // my header by the packet printing routines.
+ return "MYHEADER";
+}
+void
+MyHeader::Print (std::ostream &os) const
+{
+ // This method is invoked by the packet printing
+ // routines to print the content of my header.
+ os << "data=" << m_data << std::endl;
+}
+uint32_t
+MyHeader::GetSerializedSize (void) const
+{
+ // we reserve 2 bytes for our header.
+ return 2;
+}
+void
+MyHeader::Serialize (Buffer::Iterator start) const
+{
+ // we can serialize two bytes at the start of the buffer.
+ // we write them in network byte order.
+ start.WriteHtonU16 (m_data);
+}
+uint32_t
+MyHeader::Deserialize (Buffer::Iterator start)
+{
+ // we can deserialize two bytes from the start of the buffer.
+ // we read them in network byte order and store them
+ // in host byte order.
+ m_data = start.ReadNtohU16 ();
+
+ // we return the number of bytes effectively read.
+ return 2;
+}
+
+void
+MyHeader::SetData (uint16_t data)
+{
+ m_data = data;
+}
+uint16_t
+MyHeader::GetData (void) const
+{
+ return m_data;
+}
+
+
+
+int main (int argc, char *argv[])
+{
+ // instantiate a header.
+ MyHeader sourceHeader;
+ sourceHeader.SetData (2);
+
+ // instantiate a packet
+ Packet p;
+ // and store my header into the packet.
+ p.AddHeader (sourceHeader);
+
+ // print the content of my packet on the standard output.
+ p.Print (std::cout);
+
+ // you can now remove the header from the packet:
+ MyHeader destinationHeader;
+ p.RemoveHeader (destinationHeader);
+
+ // and check that the destination and source
+ // headers contain the same values.
+ NS_ASSERT (sourceHeader.GetData () == destinationHeader.GetData ());
+
+ return 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/main-packet-tag.cc Thu Aug 09 13:42:42 2007 +0200
@@ -0,0 +1,136 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006,2007 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ns3/tag.h"
+#include "ns3/packet.h"
+#include <iostream>
+
+using namespace ns3;
+
+// define this class in a public header
+class MyTag : public Tag
+{
+public:
+ // we have to define a public constructor
+ MyTag ();
+ // we have to define a public copy constructor
+ MyTag (const MyTag &other);
+ // we have to define a public destructor
+ ~MyTag ();
+ // we have to define a public static GetUid method
+ static uint32_t GetUid (void);
+ // we have to define a public Print method
+ void Print (std::ostream &os) const;
+ // we have to define a public GetSerializedSize method
+ uint32_t GetSerializedSize (void) const;
+ // we have to define a public Serialize method
+ void Serialize (Buffer::Iterator i) const;
+ // we have to define a public Deserialize method
+ uint32_t Deserialize (Buffer::Iterator i);
+
+ // these are our accessors to our tag structure
+ void SetSimpleValue (uint8_t value);
+ uint8_t GetSimpleValue (void) const;
+private:
+ uint8_t m_simpleValue;
+};
+
+MyTag::MyTag ()
+{}
+MyTag::MyTag (const MyTag &other)
+ : m_simpleValue (other.m_simpleValue)
+{}
+MyTag::~MyTag ()
+{}
+uint32_t
+MyTag::GetUid (void)
+{
+ // we input a unique string to AllocateUid
+ // to avoid name collisions.
+ static uint32_t uid = AllocateUid<MyTag> ("MyTag.tests.nsnam.org");
+ return uid;
+}
+void
+MyTag::Print (std::ostream &os) const
+{
+ // print the content of this tag for Packet::PrintTags
+ os << "MyTag=0x" << std::hex << (uint32_t)m_simpleValue << std::dec;
+}
+uint32_t
+MyTag::GetSerializedSize (void) const
+{
+ // we do not want to deal with parallel simulations
+ // so we return 0.
+ return 0;
+}
+void
+MyTag::Serialize (Buffer::Iterator i) const
+{
+ // we will never be invoked because we are not doing
+ // parallel simulations so, we assert.
+ NS_ASSERT (false);
+}
+uint32_t
+MyTag::Deserialize (Buffer::Iterator i)
+{
+ // we will never be invoked because we are not doing
+ // parallel simulations so, we assert.
+ NS_ASSERT (false);
+ // theoretically, return the number of bytes read
+ return 0;
+}
+
+
+void
+MyTag::SetSimpleValue (uint8_t value)
+{
+ m_simpleValue = value;
+}
+uint8_t
+MyTag::GetSimpleValue (void) const
+{
+ return m_simpleValue;
+}
+
+
+int main (int argc, char *argv[])
+{
+ // create a tag.
+ MyTag tag;
+ tag.SetSimpleValue (0x56);
+
+ // store the tag in a packet.
+ Packet p;
+ p.AddTag (tag);
+
+ // create a copy of the packet
+ Packet aCopy = p;
+
+ // read the tag from the packet copy
+ MyTag tagCopy;
+ p.PeekTag (tagCopy);
+
+ // the copy and the original are the same !
+ NS_ASSERT (tagCopy.GetSimpleValue () == tag.GetSimpleValue ());
+
+ aCopy.PrintTags (std::cout);
+ std::cout << std::endl;
+
+ return 0;
+}
--- a/samples/wscript Thu Aug 09 13:38:04 2007 +0200
+++ b/samples/wscript Thu Aug 09 13:42:42 2007 +0200
@@ -13,8 +13,14 @@
obj = bld.create_ns3_program('main-simulator')
obj.source = 'main-simulator.cc'
- obj = bld.create_ns3_program('main-header', ['common', 'simulator'])
- obj.source = 'main-header.cc'
+ obj = bld.create_ns3_program('main-packet-header', ['common', 'simulator'])
+ obj.source = 'main-packet-header.cc'
+
+ obj = bld.create_ns3_program('main-packet-tag', ['common', 'simulator'])
+ obj.source = 'main-packet-tag.cc'
+
+ obj = bld.create_ns3_program('main-packet-printer', ['common', 'simulator', 'internet-node'])
+ obj.source = 'main-packet-printer.cc'
obj = bld.create_ns3_program('main-test')
obj.source = 'main-test.cc'
--- a/src/common/array-trace-resolver.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/array-trace-resolver.h Thu Aug 09 13:42:42 2007 +0200
@@ -32,39 +32,11 @@
* \brief a helper class to offer trace resolution for an array of objects.
* \ingroup lowleveltracing
*/
-template <typename T>
+template <typename T, typename INDEX>
class ArrayTraceResolver : public TraceResolver
{
public:
/**
- * \brief array index trace context
- *
- * During namespace parsing, ns3::ArrayTraceResolver will
- * embed an instance of this class in the TraceContext
- * associated to every child object of the object stored
- * at the index.
- *
- * The reason why this class exists is to ensure that we
- * need to ensure that we can store a unique type as context
- * into the TraceContext associated to this trace resolver.
- */
- class Index
- {
- public:
- Index ();
- Index (uint32_t index);
- /**
- * The Index is automatically convertible to the
- * uin32_t type such that it really behaves like a uint32_t
- * array index for the user.
- *
- * \returns the index itself
- */
- operator uint32_t ();
- private:
- uint32_t m_index;
- };
- /**
* \param context trace context associated to this trace resolver
* \param getSize callback which returns dynamically the size of underlying array
* \param get callback which returns any element in the underlying array
@@ -91,31 +63,17 @@
namespace ns3 {
-template <typename T>
-ArrayTraceResolver<T>::Index::Index ()
- : m_index ()
-{}
-template <typename T>
-ArrayTraceResolver<T>::Index::Index (uint32_t index)
- : m_index (index)
-{}
-template <typename T>
-ArrayTraceResolver<T>::Index::operator uint32_t ()
-{
- return m_index;
-}
-
-template <typename T>
-ArrayTraceResolver<T>::ArrayTraceResolver (TraceContext const &context,
- Callback<uint32_t> getSize,
- Callback<T, uint32_t> get)
+template <typename T, typename INDEX>
+ArrayTraceResolver<T,INDEX>::ArrayTraceResolver (TraceContext const &context,
+ Callback<uint32_t> getSize,
+ Callback<T, uint32_t> get)
: TraceResolver (context),
m_getSize (getSize),
m_get (get)
{}
-template <typename T>
+template <typename T, typename INDEX>
TraceResolver::TraceResolverList
-ArrayTraceResolver<T>::DoLookup (std::string id) const
+ArrayTraceResolver<T,INDEX>::DoLookup (std::string id) const
{
TraceResolverList list;
if (id == "*")
@@ -123,7 +81,7 @@
for (uint32_t i = 0; i < m_getSize (); i++)
{
TraceContext context = GetContext ();
- typename ArrayTraceResolver<T>::Index index = typename ArrayTraceResolver<T>::Index (i);
+ INDEX index = i;
context.Add (index);
list.push_back (m_get (i)->CreateTraceResolver (context));
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/chunk-registry.cc Thu Aug 09 13:42:42 2007 +0200
@@ -0,0 +1,117 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "chunk-registry.h"
+#include "ns3/assert.h"
+
+namespace ns3 {
+
+ChunkRegistry::InfoVector *
+ChunkRegistry::GetInfoVector (void)
+{
+ static InfoVector vec;
+ return &vec;
+}
+
+std::string
+ChunkRegistry::GetUidStringFromUid (uint32_t uid)
+{
+ InfoVector *vec = GetInfoVector ();
+ NS_ASSERT (uid >= 1 && uid <= vec->size ());
+ Info info = (*vec)[uid - 1];
+ return info.uidString;
+}
+uint32_t
+ChunkRegistry::GetUidFromUidString (std::string uidString)
+{
+ uint32_t uid = 1;
+ InfoVector *vec = GetInfoVector ();
+ for (InfoVector::iterator i = vec->begin (); i != vec->end (); i++)
+ {
+ if (i->uidString == uidString)
+ {
+ return uid;
+ }
+ uid++;
+ }
+ NS_FATAL_ERROR ("Trying to access a non-registered Header or Trailer: \"" << uidString << "\". "<<
+ "You could try calling NS_HEADER_ENSURE_REGISTER somewhere.");
+ return 0;
+}
+
+uint8_t *
+ChunkRegistry::GetStaticInstance (uint32_t uid)
+{
+ InfoVector *vec = GetInfoVector ();
+ NS_ASSERT (uid >= 1 && uid <= vec->size ());
+ Info info = (*vec)[uid - 1];
+ return info.getStaticInstance ();
+}
+bool
+ChunkRegistry::IsHeader (uint32_t uid)
+{
+ InfoVector *vec = GetInfoVector ();
+ NS_ASSERT (uid >= 1 && uid <= vec->size ());
+ Info info = (*vec)[uid - 1];
+ return info.isHeader;
+}
+bool
+ChunkRegistry::IsTrailer (uint32_t uid)
+{
+ return !IsHeader (uid);
+}
+uint32_t
+ChunkRegistry::Deserialize (uint32_t uid, uint8_t *instance, Buffer::Iterator i)
+{
+ InfoVector *vec = GetInfoVector ();
+ NS_ASSERT (uid >= 1 && uid <= vec->size ());
+ Info info = (*vec)[uid - 1];
+ return info.deserialize (instance, i);
+}
+void
+ChunkRegistry::Print (uint32_t uid, uint8_t *instance, std::ostream &os)
+{
+ InfoVector *vec = GetInfoVector ();
+ NS_ASSERT (uid >= 1 && uid <= vec->size ());
+ Info info = (*vec)[uid - 1];
+ return info.print (instance, os);
+}
+std::string
+ChunkRegistry::GetName (uint32_t uid, uint8_t *instance)
+{
+ InfoVector *vec = GetInfoVector ();
+ NS_ASSERT (uid >= 1 && uid <= vec->size ());
+ Info info = (*vec)[uid - 1];
+ return info.getName (instance);
+}
+void
+ChunkRegistry::InvokePrintCallback (uint32_t uid, uint8_t *instance, std::ostream &os,
+ uint32_t packetUid, uint32_t size,
+ Ptr<CallbackImplBase> callback)
+{
+ InfoVector *vec = GetInfoVector ();
+ NS_ASSERT (uid >= 1 && uid <= vec->size ());
+ Info info = (*vec)[uid - 1];
+ info.invokePrintCallback (instance, os, packetUid, size, callback);
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/chunk-registry.h Thu Aug 09 13:42:42 2007 +0200
@@ -0,0 +1,180 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef CHUNK_REGISTRY_H
+#define CHUNK_REGISTRY_H
+
+#include <stdint.h>
+#include <ostream>
+#include "buffer.h"
+#include "ns3/ptr.h"
+#include "ns3/callback.h"
+
+namespace ns3 {
+
+/**
+ * \brief this registry keeps track of all different
+ * types of headers and trailers and assigns to each of them
+ * a unique integer.
+ * \internal
+ */
+class ChunkRegistry
+{
+public:
+ template <typename T>
+ static uint32_t RegisterHeader (std::string uuid);
+ template <typename T>
+ static uint32_t RegisterTrailer (std::string uuid);
+
+ static std::string GetUidStringFromUid (uint32_t uid);
+ static uint32_t GetUidFromUidString (std::string uidString);
+ static uint8_t *GetStaticInstance (uint32_t uid);
+ static uint32_t Deserialize (uint32_t uid, uint8_t *instance, Buffer::Iterator i);
+ static void Print (uint32_t uid, uint8_t *instance, std::ostream &os);
+ static std::string GetName (uint32_t uid, uint8_t *instance);
+ static bool IsHeader (uint32_t uid);
+ static bool IsTrailer (uint32_t uid);
+ static void InvokePrintCallback (uint32_t uid, uint8_t *instance, std::ostream &os,
+ uint32_t packetUid, uint32_t size,
+ Ptr<CallbackImplBase> callback);
+private:
+ typedef uint8_t *(*GetStaticInstanceCb) (void);
+ typedef uint32_t (*DeserializeCb) (uint8_t *, Buffer::Iterator);
+ typedef void (*PrintCb) (uint8_t *,std::ostream &);
+ typedef std::string (*GetNameCb) (uint8_t *);
+ typedef void (*InvokePrintCallbackCb) (uint8_t *instance, std::ostream &os,
+ uint32_t packetUid, uint32_t size,
+ Ptr<CallbackImplBase> callback);
+ struct Info {
+ std::string uidString;
+ bool isHeader;
+ GetStaticInstanceCb getStaticInstance;
+ DeserializeCb deserialize;
+ PrintCb print;
+ GetNameCb getName;
+ InvokePrintCallbackCb invokePrintCallback;
+ };
+ typedef std::vector<struct Info> InfoVector;
+ static InfoVector *GetInfoVector (void);
+ template <typename T>
+ static uint8_t *DoGetStaticInstance (void);
+ template <typename T>
+ static uint32_t DoDeserialize (uint8_t *instance, Buffer::Iterator i);
+ template <typename T>
+ static void DoPrint (uint8_t *instance, std::ostream &os);
+ template <typename T>
+ static std::string DoGetName (uint8_t *instance);
+ template <typename T>
+ static void DoInvokePrintCallback (uint8_t *instance, std::ostream &os,
+ uint32_t packetUid, uint32_t size,
+ Ptr<CallbackImplBase> callback);
+ template <typename T>
+ static uint32_t GetUid (bool isHeader, std::string uidString);
+
+};
+
+
+} // namespace ns3
+
+namespace ns3 {
+
+template <typename T>
+uint32_t
+ChunkRegistry::RegisterHeader (std::string uuid)
+{
+ return GetUid<T> (true, uuid);
+}
+template <typename T>
+uint32_t
+ChunkRegistry::RegisterTrailer (std::string uuid)
+{
+ return GetUid<T> (false, uuid);
+}
+
+template <typename T>
+uint32_t
+ChunkRegistry::GetUid (bool isHeader, std::string uidString)
+{
+ InfoVector *vec = GetInfoVector ();
+ uint32_t uid = 1;
+ for (InfoVector::iterator i = vec->begin (); i != vec->end (); i++)
+ {
+ if (i->uidString == uidString)
+ {
+ return uid;
+ }
+ uid++;
+ }
+ Info info;
+ info.getStaticInstance = &ChunkRegistry::DoGetStaticInstance<T>;
+ info.print = &ChunkRegistry::DoPrint<T>;
+ info.getName = &ChunkRegistry::DoGetName<T>;
+ info.deserialize = &ChunkRegistry::DoDeserialize<T>;
+ info.invokePrintCallback = &ChunkRegistry::DoInvokePrintCallback<T>;
+ info.uidString = uidString;
+ info.isHeader = isHeader;
+ vec->push_back (info);
+ return vec->size ();
+}
+
+template <typename T>
+uint8_t *
+ChunkRegistry::DoGetStaticInstance ()
+{
+ static T instance;
+ return reinterpret_cast<uint8_t *> (&instance);
+}
+template <typename T>
+uint32_t
+ChunkRegistry::DoDeserialize (uint8_t *instance, Buffer::Iterator i)
+{
+ T *obj = reinterpret_cast<T *> (instance);
+ return obj->Deserialize (i);
+}
+template <typename T>
+void
+ChunkRegistry::DoPrint (uint8_t *instance, std::ostream &os)
+{
+ T *obj = reinterpret_cast<T *> (instance);
+ obj->Print (os);
+}
+template <typename T>
+std::string
+ChunkRegistry::DoGetName (uint8_t *instance)
+{
+ T *obj = reinterpret_cast<T *> (instance);
+ return obj->GetName ();
+}
+template <typename T>
+void
+ChunkRegistry::DoInvokePrintCallback (uint8_t *instance, std::ostream &os,
+ uint32_t packetUid, uint32_t size,
+ Ptr<CallbackImplBase> callback)
+{
+ T *obj = reinterpret_cast<T *> (instance);
+ Callback<void,std::ostream&,uint32_t,uint32_t,const T*> cb;
+ cb.Assign (callback);
+ cb (os, packetUid, size, obj);
+}
+
+} // namespace ns3
+
+#endif /* CHUNK_H */
--- a/src/common/chunk.cc Thu Aug 09 13:38:04 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "chunk.h"
-#include "ns3/assert.h"
-
-namespace ns3 {
-
-Chunk::Chunk ()
-{}
-
-Chunk::~Chunk ()
-{}
-
-std::string
-Chunk::GetName (void) const
-{
- return DoGetName ();
-}
-void
-Chunk::Print (std::ostream &os) const
-{
- PrintTo (os);
-}
-uint32_t
-Chunk::GetSize (void) const
-{
- return GetSerializedSize ();
-}
-void
-Chunk::Serialize (Buffer::Iterator start) const
-{
- SerializeTo (start);
-}
-uint32_t
-Chunk::Deserialize (Buffer::Iterator start)
-{
- uint32_t deserialized = DeserializeFrom (start);
- return deserialized;
-}
-std::ostream& operator<< (std::ostream& os, Chunk const& chunk)
-{
- chunk.Print (os);
- return os;
-}
-
-
-/**************************************
- * The Chunk Registry below
- ***************************************/
-
-
-ChunkRegistry::InfoVector *
-ChunkRegistry::GetInfoVector (void)
-{
- static InfoVector vec;
- return &vec;
-}
-
-std::string
-ChunkRegistry::GetUidStringFromUid (uint32_t uid)
-{
- InfoVector *vec = GetInfoVector ();
- NS_ASSERT (uid >= 1 && uid <= vec->size ());
- Info info = (*vec)[uid - 1];
- return info.uidString;
-}
-uint32_t
-ChunkRegistry::GetUidFromUidString (std::string uidString)
-{
- uint32_t uid = 1;
- InfoVector *vec = GetInfoVector ();
- for (InfoVector::iterator i = vec->begin (); i != vec->end (); i++)
- {
- if (i->uidString == uidString)
- {
- return uid;
- }
- uid++;
- }
- NS_FATAL_ERROR ("Trying to access a non-registered Header or Trailer: \"" << uidString << "\". "<<
- "You could try calling NS_HEADER_ENSURE_REGISTER somewhere.");
- return 0;
-}
-
-uint8_t *
-ChunkRegistry::GetStaticInstance (uint32_t uid)
-{
- InfoVector *vec = GetInfoVector ();
- NS_ASSERT (uid >= 1 && uid <= vec->size ());
- Info info = (*vec)[uid - 1];
- return info.getStaticInstance ();
-}
-bool
-ChunkRegistry::IsHeader (uint32_t uid)
-{
- InfoVector *vec = GetInfoVector ();
- NS_ASSERT (uid >= 1 && uid <= vec->size ());
- Info info = (*vec)[uid - 1];
- return info.isHeader;
-}
-bool
-ChunkRegistry::IsTrailer (uint32_t uid)
-{
- return !IsHeader (uid);
-}
-uint32_t
-ChunkRegistry::Deserialize (uint32_t uid, uint8_t *instance, Buffer::Iterator i)
-{
- InfoVector *vec = GetInfoVector ();
- NS_ASSERT (uid >= 1 && uid <= vec->size ());
- Info info = (*vec)[uid - 1];
- return info.deserialize (instance, i);
-}
-void
-ChunkRegistry::Print (uint32_t uid, uint8_t *instance, std::ostream &os)
-{
- InfoVector *vec = GetInfoVector ();
- NS_ASSERT (uid >= 1 && uid <= vec->size ());
- Info info = (*vec)[uid - 1];
- return info.print (instance, os);
-}
-std::string
-ChunkRegistry::GetName (uint32_t uid, uint8_t *instance)
-{
- InfoVector *vec = GetInfoVector ();
- NS_ASSERT (uid >= 1 && uid <= vec->size ());
- Info info = (*vec)[uid - 1];
- return info.getName (instance);
-}
-void
-ChunkRegistry::InvokePrintCallback (uint32_t uid, uint8_t *instance, std::ostream &os,
- uint32_t packetUid, uint32_t size,
- Ptr<CallbackImplBase> callback)
-{
- InfoVector *vec = GetInfoVector ();
- NS_ASSERT (uid >= 1 && uid <= vec->size ());
- Info info = (*vec)[uid - 1];
- info.invokePrintCallback (instance, os, packetUid, size, callback);
-}
-
-
-} // namespace ns3
--- a/src/common/chunk.h Thu Aug 09 13:38:04 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef CHUNK_H
-#define CHUNK_H
-
-#include <stdint.h>
-#include <ostream>
-#include "buffer.h"
-#include "ns3/ptr.h"
-#include "ns3/callback.h"
-
-namespace ns3 {
-
-class Chunk {
-public:
- Chunk ();
- virtual ~Chunk ();
-
- std::string GetName (void) const;
- void Print (std::ostream &os) const;
- uint32_t GetSize (void) const;
- void Serialize (Buffer::Iterator start) const;
- uint32_t Deserialize (Buffer::Iterator start);
-private:
- virtual std::string DoGetName (void) const = 0;
- virtual void PrintTo (std::ostream &os) const = 0;
- virtual uint32_t GetSerializedSize (void) const = 0;
- virtual void SerializeTo (Buffer::Iterator i) const = 0;
- virtual uint32_t DeserializeFrom (Buffer::Iterator i) = 0;
-};
-
-std::ostream& operator<< (std::ostream& os, Chunk const& chunk);
-
-/**
- * \brief this registry keeps track of all different
- * types of headers and trailers and assigns to each of them
- * a unique integer.
- * \internal
- */
-class ChunkRegistry
-{
-public:
- template <typename T>
- static uint32_t RegisterHeader (std::string uuid);
- template <typename T>
- static uint32_t RegisterTrailer (std::string uuid);
-
- static std::string GetUidStringFromUid (uint32_t uid);
- static uint32_t GetUidFromUidString (std::string uidString);
- static uint8_t *GetStaticInstance (uint32_t uid);
- static uint32_t Deserialize (uint32_t uid, uint8_t *instance, Buffer::Iterator i);
- static void Print (uint32_t uid, uint8_t *instance, std::ostream &os);
- static std::string GetName (uint32_t uid, uint8_t *instance);
- static bool IsHeader (uint32_t uid);
- static bool IsTrailer (uint32_t uid);
- static void InvokePrintCallback (uint32_t uid, uint8_t *instance, std::ostream &os,
- uint32_t packetUid, uint32_t size,
- Ptr<CallbackImplBase> callback);
-private:
- typedef uint8_t *(*GetStaticInstanceCb) (void);
- typedef uint32_t (*DeserializeCb) (uint8_t *, Buffer::Iterator);
- typedef void (*PrintCb) (uint8_t *,std::ostream &);
- typedef std::string (*GetNameCb) (uint8_t *);
- typedef void (*InvokePrintCallbackCb) (uint8_t *instance, std::ostream &os,
- uint32_t packetUid, uint32_t size,
- Ptr<CallbackImplBase> callback);
- struct Info {
- std::string uidString;
- bool isHeader;
- GetStaticInstanceCb getStaticInstance;
- DeserializeCb deserialize;
- PrintCb print;
- GetNameCb getName;
- InvokePrintCallbackCb invokePrintCallback;
- };
- typedef std::vector<struct Info> InfoVector;
- static InfoVector *GetInfoVector (void);
- template <typename T>
- static uint8_t *DoGetStaticInstance (void);
- template <typename T>
- static uint32_t DoDeserialize (uint8_t *instance, Buffer::Iterator i);
- template <typename T>
- static void DoPrint (uint8_t *instance, std::ostream &os);
- template <typename T>
- static std::string DoGetName (uint8_t *instance);
- template <typename T>
- static void DoInvokePrintCallback (uint8_t *instance, std::ostream &os,
- uint32_t packetUid, uint32_t size,
- Ptr<CallbackImplBase> callback);
- template <typename T>
- static uint32_t GetUid (bool isHeader, std::string uidString);
-
-};
-
-
-} // namespace ns3
-
-namespace ns3 {
-
-template <typename T>
-uint32_t
-ChunkRegistry::RegisterHeader (std::string uuid)
-{
- return GetUid<T> (true, uuid);
-}
-template <typename T>
-uint32_t
-ChunkRegistry::RegisterTrailer (std::string uuid)
-{
- return GetUid<T> (false, uuid);
-}
-
-template <typename T>
-uint32_t
-ChunkRegistry::GetUid (bool isHeader, std::string uidString)
-{
- InfoVector *vec = GetInfoVector ();
- uint32_t uid = 1;
- for (InfoVector::iterator i = vec->begin (); i != vec->end (); i++)
- {
- if (i->uidString == uidString)
- {
- return uid;
- }
- uid++;
- }
- Info info;
- info.getStaticInstance = &ChunkRegistry::DoGetStaticInstance<T>;
- info.print = &ChunkRegistry::DoPrint<T>;
- info.getName = &ChunkRegistry::DoGetName<T>;
- info.deserialize = &ChunkRegistry::DoDeserialize<T>;
- info.invokePrintCallback = &ChunkRegistry::DoInvokePrintCallback<T>;
- info.uidString = uidString;
- info.isHeader = isHeader;
- vec->push_back (info);
- return vec->size ();
-}
-
-template <typename T>
-uint8_t *
-ChunkRegistry::DoGetStaticInstance ()
-{
- static T instance;
- return reinterpret_cast<uint8_t *> (&instance);
-}
-template <typename T>
-uint32_t
-ChunkRegistry::DoDeserialize (uint8_t *instance, Buffer::Iterator i)
-{
- T *obj = reinterpret_cast<T *> (instance);
- return obj->Deserialize (i);
-}
-template <typename T>
-void
-ChunkRegistry::DoPrint (uint8_t *instance, std::ostream &os)
-{
- T *obj = reinterpret_cast<T *> (instance);
- obj->Print (os);
-}
-template <typename T>
-std::string
-ChunkRegistry::DoGetName (uint8_t *instance)
-{
- T *obj = reinterpret_cast<T *> (instance);
- return obj->GetName ();
-}
-template <typename T>
-void
-ChunkRegistry::DoInvokePrintCallback (uint8_t *instance, std::ostream &os,
- uint32_t packetUid, uint32_t size,
- Ptr<CallbackImplBase> callback)
-{
- T *obj = reinterpret_cast<T *> (instance);
- Callback<void,std::ostream&,uint32_t,uint32_t,const T*> cb;
- cb.Assign (callback);
- cb (os, packetUid, size, obj);
-}
-
-} // namespace ns3
-
-#endif /* CHUNK_H */
--- a/src/common/composite-trace-resolver.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/composite-trace-resolver.cc Thu Aug 09 13:42:42 2007 +0200
@@ -30,6 +30,14 @@
{}
void
+CompositeTraceResolver::Add (std::string name,
+ Callback<TraceResolver *,TraceContext const &> createResolver)
+{
+ TraceContext traceContext = GetContext ();
+ DoAdd (name, createResolver, traceContext);
+}
+
+void
CompositeTraceResolver::DoAdd (std::string name,
Callback<TraceResolver *,TraceContext const &> createResolver,
TraceContext const &context)
@@ -107,20 +115,53 @@
#ifdef RUN_SELF_TESTS
#include "ns3/test.h"
+#include "trace-context-element.h"
namespace ns3 {
+class TraceSourceTest : public TraceContextElement
+{
+public:
+ enum Sources {
+ DOUBLEA,
+ DOUBLEB,
+ SUBRESOLVER,
+ };
+ static uint16_t GetUid (void)
+ {static uint16_t uid = AllocateUid<TraceSourceTest> ("TraceSourceTest"); return uid;}
+ void Print (std::ostream &os)
+ {os << "tracesource=";
+ if (m_sources == DOUBLEA) {os << "doubleA";}
+ else if (m_sources == DOUBLEB) {os << "doubleB";}
+ else if (m_sources == SUBRESOLVER) {os << "subresolver";}
+ }
+ TraceSourceTest () : m_sources (TraceSourceTest::DOUBLEA) {}
+ TraceSourceTest (enum Sources sources) :m_sources (sources) {}
+ bool IsDoubleA (void) {return m_sources == TraceSourceTest::DOUBLEA;}
+ bool IsDoubleB (void) {return m_sources == TraceSourceTest::DOUBLEB;}
+private:
+ enum TraceSourceTest::Sources m_sources;
+};
+
+class SubTraceSourceTest : public TraceContextElement
+{
+public:
+ enum Sources {
+ INT,
+ };
+ static uint16_t GetUid (void)
+ {static uint16_t uid = AllocateUid<SubTraceSourceTest> ("SubTraceSourceTest"); return uid;}
+ void Print (std::ostream &os)
+ {os << "subtracesource=int";}
+ SubTraceSourceTest () : m_sources (SubTraceSourceTest::INT) {}
+ SubTraceSourceTest (enum Sources sources) : m_sources (sources) {}
+private:
+ enum Sources m_sources;
+};
+
class CompositeTraceResolverTest : public Test
{
public:
- enum TraceSources {
- TEST_TRACE_DOUBLEA,
- TEST_TRACE_DOUBLEB,
- TEST_TRACE_SUBRESOLVER,
- };
- enum SubTraceSources {
- TEST_SUBTRACE_INT,
- };
CompositeTraceResolverTest ();
virtual ~CompositeTraceResolverTest ();
virtual bool RunTests (void);
@@ -144,19 +185,19 @@
void
CompositeTraceResolverTest::TraceDouble (TraceContext const &context, double v)
{
- enum CompositeTraceResolverTest::TraceSources source;
+ TraceSourceTest source;
context.Get (source);
- switch (source)
+ if (source.IsDoubleA ())
{
- case TEST_TRACE_DOUBLEA:
m_gotDoubleA = true;
- break;
- case TEST_TRACE_DOUBLEB:
+ }
+ else if (source.IsDoubleB ())
+ {
m_gotDoubleB = true;
- break;
- default:
+ }
+ else
+ {
NS_FATAL_ERROR ("should not get any other trace source in this sink");
- break;
}
}
@@ -171,7 +212,8 @@
CompositeTraceResolverTest::CreateSubResolver (TraceContext const &context)
{
CompositeTraceResolver *subresolver = new CompositeTraceResolver (context);
- subresolver->Add ("trace-int", m_traceInt, TEST_SUBTRACE_INT);
+ subresolver->Add ("trace-int", m_traceInt,
+ SubTraceSourceTest (SubTraceSourceTest::INT));
return subresolver;
}
bool
@@ -185,8 +227,10 @@
CompositeTraceResolver resolver (context) ;
- resolver.Add ("trace-double-a", traceDoubleA, TEST_TRACE_DOUBLEA);
- resolver.Add ("trace-double-b", traceDoubleB, TEST_TRACE_DOUBLEB);
+ resolver.Add ("trace-double-a", traceDoubleA,
+ TraceSourceTest (TraceSourceTest::DOUBLEA));
+ resolver.Add ("trace-double-b", traceDoubleB,
+ TraceSourceTest (TraceSourceTest::DOUBLEB));
resolver.Connect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
@@ -279,7 +323,7 @@
resolver.Add ("subresolver",
MakeCallback (&CompositeTraceResolverTest::CreateSubResolver, this),
- TEST_TRACE_SUBRESOLVER);
+ TraceSourceTest (TraceSourceTest::SUBRESOLVER));
resolver.Connect ("/subresolver/trace-int",
MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
--- a/src/common/composite-trace-resolver.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/composite-trace-resolver.h Thu Aug 09 13:42:42 2007 +0200
@@ -111,6 +111,18 @@
void Add (std::string name,
Callback<TraceResolver *,TraceContext const &> createResolver,
T const &context);
+
+ /**
+ * \param name name of child trace resolver
+ * \param createResolver a trace resolver constructor
+ *
+ * Add a child trace resolver to this resolver. This child
+ * trace resolver will match the name specified during
+ * namespace resolution. When this happens, the constructor
+ * will be invoked to create the child trace resolver.
+ */
+ void Add (std::string name,
+ Callback<TraceResolver *,TraceContext const &> createResolver);
private:
template <typename SOURCE, typename CONTEXT>
void DoAddTraceSource (std::string name,
@@ -205,7 +217,6 @@
DoAdd (name, createResolver, traceContext);
}
-
}//namespace ns3
#endif /* COMPOSITE_TRACE_RESOLVER_H */
--- a/src/common/header.cc Thu Aug 09 13:38:04 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "header.h"
-
-namespace ns3 {
-
-Header::~Header ()
-{}
-
-} // namespace ns3
--- a/src/common/header.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/header.h Thu Aug 09 13:42:42 2007 +0200
@@ -22,10 +22,10 @@
#ifndef HEADER_H
#define HEADER_H
-#include "chunk.h"
+#include "chunk-registry.h"
/**
- * \relates Header
+ * \relates ns3::Header
* \brief this macro should be instantiated exactly once for each
* new type of Header
*
@@ -37,15 +37,14 @@
* Note: This macro is _absolutely_ needed if you try to run a
* distributed simulation.
*/
-#define NS_HEADER_ENSURE_REGISTERED(x) \
-namespace { \
-static class thisisaveryverylongclassname \
-{ \
-public: \
- thisisaveryverylongclassname () \
- { uint32_t uid; uid = x::GetUid ();} \
-} g_thisisanotherveryveryverylongname; \
-}
+#define NS_HEADER_ENSURE_REGISTERED(x) \
+static class thisisaveryverylongclassname ##x \
+{ \
+ public: \
+ thisisaveryverylongclassname ##x () \
+ { uint32_t uid; uid = x::GetUid ();} \
+} g_thisisanotherveryveryverylongname ## x;
+
namespace ns3 {
@@ -53,96 +52,51 @@
* \brief Protocol header serialization and deserialization.
*
* Every Protocol header which needs to be inserted or removed
- * from a Packet instance must derive from this abstract base class
- * and implement the private pure virtual methods listed below:
- * - ns3::Header::SerializeTo
- * - ns3::Header::DeserializeFrom
- * - ns3::Header::GetSerializedSize
- * - ns3::Header::PrintTo
- * - ns3::Header::DoGetName
- *
- * Each header must also make sure that:
- * - it defines a public default constructor
- * - it defines a public static method named GetUid which returns a 32 bit integer
+ * from a Packet instance must derive from this base class and
+ * implement the following public methods:
+ * - a default constructor: is used by the internal implementation
+ * if the Packet class.
+ * - a static method named GetUid: is used to uniquely identify
+ * the type of each header. This method shall return a unique
+ * integer allocated with Header::AllocateUid.
+ * - a method named Serialize: is used by Packet::AddHeader to
+ * store a header into the byte buffer of a packet.
+ * The input iterator points to the start of the byte buffer in
+ * which the header should write its data. The data written
+ * is expected to match bit-for-bit the representation of this
+ * header in a real network.
+ * - a method named GetSerializedSize: is used by Packet::AddHeader
+ * to store a header into the byte buffer of a packet. This method
+ * should return the number of bytes which are needed to store
+ * the full header data by Serialize.
+ * - a method named Deserialize: is used by Packet::RemoveHeader to
+ * re-create a header from the byte buffer of a packet. The input
+ * iterator points to the start of the byte buffer from which
+ * the header should read its data. The data read is expected to
+ * match bit-for-bit the representation of this header in real
+ * networks. This method shall return an integer which identifies
+ * the number of bytes read.
+ * - a method named Print: is used by Packet::Print to print the
+ * content of a header as ascii data to a c++ output stream.
+ * Although the header is free to format its output as it
+ * wishes, it is recommended to follow a few rules to integrate
+ * with the packet pretty printer: start with flags, small field
+ * values located between a pair of parens. Values should be separated
+ * by whitespace. Follow the parens with the important fields,
+ * separated by whitespace.
+ * i.e.: (field1 val1 field2 val2 field3 val3) field4 val4 field5 val5
+ * - a method named GetName: is used by Packet::Print to print
+ * header fragments. This method should return a user-readable
+ * single word as all capitalized letters.
*
- * The latter should look like the following:
- * \code
- * // in the header,
- * class MyHeader : public Header
- * {
- * public:
- * static uint32_t GetUid (void);
- * };
- *
- * // in the source file:
- * NS_HEADER_ENSURE_REGISTERED (MyHeader);
- *
- * uint32_t MyHeader::GetUid (void)
- * {
- * static uint32_t uid = Header::Register<MyHeader> ("MyHeader.unique.prefix");
- * return uid;
- * }
- * \endcode
- *
- * Sample code which shows how to create a new Header, and how to use it,
- * is shown in the sample file samples/main-header.cc
+ * Sample code which shows how to create a new type of Header, and how to use it,
+ * is shown in the sample file samples/main-packet-header.cc
*/
-class Header : public Chunk {
-public:
- virtual ~Header ();
+class Header
+{
protected:
template <typename T>
- static uint32_t Register (std::string uuid);
-private:
- /**
- * \returns a user-readable name to identify this type of header.
- *
- * The string returned is expected to be a single word with
- * all capital letters
- */
- virtual std::string DoGetName (void) const = 0;
- /**
- * \param os the std output stream in which this
- * protocol header must print itself.
- *
- * Although the header is free to format its output as it
- * wishes, it is recommended to follow a few rules to integrate
- * with the packet pretty printer:
- * - start with flags, small field values located between a
- * pair of parens. Values should be separated by whitespace.
- * - follow the parens with the important fields, separated by
- * whitespace.
- * i.e.:
- * (field1 val1 field2 val2 field3 val3) field4 val4 field5 val5
- */
- virtual void PrintTo (std::ostream &os) const = 0;
-
- /**
- * \returns the size of the serialized Header.
- *
- * This method is used by Packet::AddHeader to reserve
- * enough room in the packet byte buffer prior to calling
- * Header::Serialize.
- */
- virtual uint32_t GetSerializedSize (void) const = 0;
-
- /**
- * \param start the buffer iterator in which the protocol header
- * must serialize itself. This iterator identifies
- * the start of the buffer.
- */
- virtual void SerializeTo (Buffer::Iterator start) const = 0;
- /**
- * \param start the buffer iterator from which the protocol header must
- * deserialize itself. This iterator identifies
- * the start of the buffer.
- * \returns the number of bytes read from the buffer
- *
- * The value returned is used to trim the packet byte buffer of the
- * corresponding amount when this method is invoked from
- * Packet::RemoveHeader
- */
- virtual uint32_t DeserializeFrom (Buffer::Iterator start) = 0;
+ static uint32_t AllocateUid (std::string uuid);
};
} // namespace ns3
@@ -151,12 +105,11 @@
template <typename T>
uint32_t
-Header::Register (std::string uuid)
+Header::AllocateUid (std::string uuid)
{
return ChunkRegistry::RegisterHeader<T> (uuid);
}
-
} // namespace ns3
#endif /* HEADER_H */
--- a/src/common/packet-metadata-test.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/packet-metadata-test.cc Thu Aug 09 13:42:42 2007 +0200
@@ -38,12 +38,12 @@
static uint32_t GetUid (void);
HistoryHeader ();
bool IsOk (void) const;
+ std::string GetName (void) const;
+ void Print (std::ostream &os) const;
+ uint32_t GetSerializedSize (void) const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
private:
- virtual std::string DoGetName (void) const;
- virtual void PrintTo (std::ostream &os) const;
- virtual uint32_t GetSerializedSize (void) const;
- virtual void SerializeTo (Buffer::Iterator start) const;
- virtual uint32_t DeserializeFrom (Buffer::Iterator start);
bool m_ok;
};
@@ -53,7 +53,7 @@
{
std::ostringstream oss;
oss << N << "HistoryHeader.ns3";
- static uint32_t uid = Header::Register<HistoryHeader<N> > (oss.str());
+ static uint32_t uid = AllocateUid<HistoryHeader<N> > (oss.str());
return uid;
}
@@ -71,7 +71,7 @@
template <int N>
std::string
-HistoryHeader<N>::DoGetName (void) const
+HistoryHeader<N>::GetName (void) const
{
std::ostringstream oss;
oss << N;
@@ -80,7 +80,7 @@
template <int N>
void
-HistoryHeader<N>::PrintTo (std::ostream &os) const
+HistoryHeader<N>::Print (std::ostream &os) const
{
NS_ASSERT (false);
}
@@ -92,13 +92,13 @@
}
template <int N>
void
-HistoryHeader<N>::SerializeTo (Buffer::Iterator start) const
+HistoryHeader<N>::Serialize (Buffer::Iterator start) const
{
start.WriteU8 (N, N);
}
template <int N>
uint32_t
-HistoryHeader<N>::DeserializeFrom (Buffer::Iterator start)
+HistoryHeader<N>::Deserialize (Buffer::Iterator start)
{
m_ok = true;
for (int i = 0; i < N; i++)
@@ -118,12 +118,12 @@
static uint32_t GetUid (void);
HistoryTrailer ();
bool IsOk (void) const;
+ std::string GetName (void) const;
+ void Print (std::ostream &os) const;
+ uint32_t GetSerializedSize (void) const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
private:
- virtual std::string DoGetName (void) const;
- virtual void PrintTo (std::ostream &os) const;
- virtual uint32_t GetSerializedSize (void) const;
- virtual void SerializeTo (Buffer::Iterator start) const;
- virtual uint32_t DeserializeFrom (Buffer::Iterator start);
bool m_ok;
};
@@ -133,7 +133,7 @@
{
std::ostringstream oss;
oss << N << "HistoryTrailer.ns3";
- static uint32_t uid = Trailer::Register<HistoryTrailer<N> > (oss.str ());
+ static uint32_t uid = AllocateUid<HistoryTrailer<N> > (oss.str ());
return uid;
}
@@ -152,7 +152,7 @@
template <int N>
std::string
-HistoryTrailer<N>::DoGetName (void) const
+HistoryTrailer<N>::GetName (void) const
{
std::ostringstream oss;
oss << N;
@@ -160,7 +160,7 @@
}
template <int N>
void
-HistoryTrailer<N>::PrintTo (std::ostream &os) const
+HistoryTrailer<N>::Print (std::ostream &os) const
{
NS_ASSERT (false);
}
@@ -172,14 +172,14 @@
}
template <int N>
void
-HistoryTrailer<N>::SerializeTo (Buffer::Iterator start) const
+HistoryTrailer<N>::Serialize (Buffer::Iterator start) const
{
start.Prev (N);
start.WriteU8 (N, N);
}
template <int N>
uint32_t
-HistoryTrailer<N>::DeserializeFrom (Buffer::Iterator start)
+HistoryTrailer<N>::Deserialize (Buffer::Iterator start)
{
m_ok = true;
start.Prev (N);
--- a/src/common/packet-metadata.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/packet-metadata.cc Thu Aug 09 13:42:42 2007 +0200
@@ -23,8 +23,8 @@
#include "ns3/fatal-error.h"
#include "ns3/debug.h"
#include "packet-metadata.h"
-#include "chunk.h"
#include "buffer.h"
+#include "chunk-registry.h"
NS_DEBUG_COMPONENT_DEFINE ("PacketMetadata");
--- a/src/common/packet-printer.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/packet-printer.cc Thu Aug 09 13:42:42 2007 +0200
@@ -20,6 +20,7 @@
*/
#include "packet-printer.h"
+#include "chunk-registry.h"
namespace ns3 {
--- a/src/common/packet-printer.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/packet-printer.h Thu Aug 09 13:42:42 2007 +0200
@@ -24,7 +24,6 @@
#include "ns3/callback.h"
#include "ns3/ptr.h"
#include "buffer.h"
-#include "chunk.h"
#include <vector>
namespace ns3 {
--- a/src/common/packet.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/packet.cc Thu Aug 09 13:42:42 2007 +0200
@@ -126,6 +126,12 @@
}
void
+Packet::PrintTags (std::ostream &os) const
+{
+ m_tags.Print (os);
+}
+
+void
Packet::Print (std::ostream &os) const
{
m_metadata.Print (os, m_buffer, PacketPrinter ());
--- a/src/common/packet.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/packet.h Thu Aug 09 13:42:42 2007 +0200
@@ -27,6 +27,7 @@
#include "trailer.h"
#include "tags.h"
#include "packet-metadata.h"
+#include "tag.h"
#include "ns3/callback.h"
#include "ns3/assert.h"
@@ -62,15 +63,11 @@
*
* Implementing a new type of Header or Trailer for a new protocol is
* pretty easy and is a matter of creating a subclass of the ns3::Header
- * or of the ns3::Trailer base class, and implementing the 5 pure virtual
- * methods defined in either of the two base classes. Users _must_
- * also make sure that they class defines a public default constructor and
- * a public method named GetUid, as documented in the ns3::Header and ns::Trailer
- * API documentations.
+ * or of the ns3::Trailer base class, and implementing the methods
+ * described in their respective API documentation.
*
* Implementing a new type of Tag requires roughly the same amount of
- * work: users must implement a total of 6 methods which are described in
- * \ref tags
+ * work and this work is described in the ns3::Tag API documentation.
*
* The performance aspects of the Packet API are discussed in
* \ref packetperf
@@ -118,7 +115,7 @@
uint32_t GetSize (void) const;
/**
* Add header to this packet. This method invokes the
- * ns3::Chunk::GetSerializedSize and ns3::Chunk::SerializeTo
+ * GetSerializedSize and Serialize
* methods to reserve space in the buffer and request the
* header to serialize itself in the packet buffer.
*
@@ -128,7 +125,7 @@
void AddHeader (T const &header);
/**
* Deserialize and remove the header from the internal buffer.
- * This method invokes ns3::Chunk::DeserializeFrom.
+ * This method invokes Deserialize.
*
* \param header a reference to the header to remove from the internal buffer.
* \returns the number of bytes removed from the packet.
@@ -137,7 +134,7 @@
uint32_t RemoveHeader (T &header);
/**
* Add trailer to this packet. This method invokes the
- * ns3::Chunk::GetSerializedSize and ns3::Trailer::serializeTo
+ * GetSerializedSize and Serialize
* methods to reserve space in the buffer and request the trailer
* to serialize itself in the packet buffer.
*
@@ -147,7 +144,7 @@
void AddTrailer (T const &trailer);
/**
* Remove a deserialized trailer from the internal buffer.
- * This method invokes the ns3::Chunk::DeserializeFrom method.
+ * This method invokes the Deserialize method.
*
* \param trailer a reference to the trailer to remove from the internal buffer.
* \returns the number of bytes removed from the end of the packet.
@@ -157,7 +154,8 @@
/**
* Attach a tag to this packet. The tag is fully copied
* in a packet-specific internal buffer. This operation
- * is expected to be really fast.
+ * is expected to be really fast. The copy constructor of the
+ * tag is invoked to copy it into the tag buffer.
*
* \param tag a pointer to the tag to attach to this packet.
*/
@@ -184,6 +182,8 @@
/**
* Copy a tag stored internally to the input tag. If no instance
* of this tag is present internally, the input tag is not modified.
+ * The copy constructor of the tag is invoked to copy it into the
+ * input tag variable.
*
* \param tag a pointer to the tag to read from this packet
* \returns true if an instance of this tag type is stored
@@ -197,6 +197,14 @@
*/
void RemoveAllTags (void);
/**
+ * \param os output stream in which the data should be printed.
+ *
+ * Iterate over the tags present in this packet, and
+ * invoke the Print method of each tag stored in the packet.
+ */
+ void PrintTags (std::ostream &os) const;
+
+ /**
* Concatenate the input packet at the end of the current
* packet. This does not alter the uid of either packet.
*
@@ -289,18 +297,24 @@
* serialized representation contains a copy of the packet byte buffer,
* the tag list, and the packet metadata (if there is one).
*
+ * This method will trigger calls to the Serialize and GetSerializedSize
+ * methods of each tag stored in this packet.
+ *
* This method will typically be used by parallel simulations where
* the simulated system is partitioned and each partition runs on
* a different CPU.
*/
Buffer Serialize (void) const;
/**
- * \param a byte buffer
+ * \param buffer a byte buffer
*
* This method reads a byte buffer as created by Packet::Serialize
- * and restores the state of the Packet to what it was prio to
+ * and restores the state of the Packet to what it was prior to
* calling Serialize.
*
+ * This method will trigger calls to the Deserialize method
+ * of each tag stored in this packet.
+ *
* This method will typically be used by parallel simulations where
* the simulated system is partitioned and each partition runs on
* a different CPU.
@@ -315,59 +329,6 @@
};
/**
- * \defgroup tags Packet Tags
- *
- * A tag is a class which must define:
- * - a public default constructor
- * - a public static method named GetUid
- * - a public method named Print
- * - a public method named GetSerializedSize
- * - a public method named Serialize
- * - a public method named Deserialize
- *
- * So, a tag class should look like this:
- * \code
- * // in header file
- * // note how a tag class does not derive from any other class.
- * class MyTag
- * {
- * public:
- * // we need a public default constructor
- * MyTag ();
- * // we need a public static GetUid
- * // GetUid must return a 32 bit integer which uniquely
- * // identifies this tag type
- * static uint32_t GetUid (void);
- * // Print should record in the output stream
- * // the content of the tag instance.
- * void Print (std::ostream &os) const;
- * // GetSerializedSize should return the number of bytes needed
- * // to store the state of a tag instance
- * uint32_t GetSerializedSize (void) const;
- * // Serialize should store its state in the input
- * // buffer with the help of the iterator. It should
- * // write exactly size bytes.
- * void Serialize (Buffer::Iterator i, uint32_t size) const;
- * // Deserialize should restore the state of a Tag instance
- * // from a byte buffer with the help of the iterator
- * uint32_t Deserialize (Buffer::Iterator i);
- * };
- *
- * // in source file
- *
- * NS_TAG_ENSURE_REGISTERED (MyTag);
- *
- * std::string MyTag::GetUid (void)
- * {
- * // we really want to make sure that this
- * // string is unique in the universe.
- * static uint32_t uid = TagRegistry::Register<MyTag> ("MyTag.unique.prefix");
- * return uid;
- * }
- * \endcode
- */
-
-/**
* \defgroup packetperf Packet Performance
* The current implementation of the byte buffers and tag list is based
* on COW (Copy On Write. An introduction to COW can be found in Scott
@@ -416,9 +377,11 @@
void
Packet::AddHeader (T const &header)
{
- NS_ASSERT_MSG (dynamic_cast<Header const *> (&header) != 0,
- "Must pass Header subclass to Packet::AddHeader");
- uint32_t size = header.GetSize ();
+ const Header *testHeader;
+ // if the following assignment fails, it is because the
+ // input to this function is not a subclass of the Header class
+ testHeader = &header;
+ uint32_t size = header.GetSerializedSize ();
m_buffer.AddAtStart (size);
header.Serialize (m_buffer.Begin ());
m_metadata.AddHeader (header, size);
@@ -427,8 +390,10 @@
uint32_t
Packet::RemoveHeader (T &header)
{
- NS_ASSERT_MSG (dynamic_cast<Header const *> (&header) != 0,
- "Must pass Header subclass to Packet::RemoveHeader");
+ Header *testHeader;
+ // if the following assignment fails, it is because the
+ // input to this function is not a subclass of the Header class
+ testHeader = &header;
uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
m_buffer.RemoveAtStart (deserialized);
m_metadata.RemoveHeader (header, deserialized);
@@ -438,9 +403,11 @@
void
Packet::AddTrailer (T const &trailer)
{
- NS_ASSERT_MSG (dynamic_cast<Trailer const *> (&trailer) != 0,
- "Must pass Trailer subclass to Packet::AddTrailer");
- uint32_t size = trailer.GetSize ();
+ const Trailer *testTrailer;
+ // if the following assignment fails, it is because the
+ // input to this function is not a subclass of the Trailer class
+ testTrailer = &trailer;
+ uint32_t size = trailer.GetSerializedSize ();
m_buffer.AddAtEnd (size);
Buffer::Iterator end = m_buffer.End ();
trailer.Serialize (end);
@@ -450,8 +417,10 @@
uint32_t
Packet::RemoveTrailer (T &trailer)
{
- NS_ASSERT_MSG (dynamic_cast<Trailer const *> (&trailer) != 0,
- "Must pass Trailer subclass to Packet::RemoveTrailer");
+ Trailer *testTrailer;
+ // if the following assignment fails, it is because the
+ // input to this function is not a subclass of the Trailer class
+ testTrailer = &trailer;
uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
m_buffer.RemoveAtEnd (deserialized);
m_metadata.RemoveTrailer (trailer, deserialized);
@@ -462,18 +431,31 @@
template <typename T>
void Packet::AddTag (T const& tag)
{
+ const Tag *parent;
+ // if the following assignment fails, it is because the
+ // input to this function is not a subclass of the Tag class.
+ parent = &tag;
m_tags.Add (tag);
}
template <typename T>
bool Packet::RemoveTag (T & tag)
{
+ Tag *parent;
+ // if the following assignment fails, it is because the
+ // input to this function is not a subclass of the Tag class.
+ parent = &tag;
return m_tags.Remove (tag);
}
template <typename T>
bool Packet::PeekTag (T & tag) const
{
+ Tag *parent;
+ // if the following assignment fails, it is because the
+ // input to this function is not a subclass of the Tag class.
+ parent = &tag;
return m_tags.Peek (tag);
}
-}; // namespace ns3
+
+} // namespace ns3
#endif /* PACKET_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/tag-registry.cc Thu Aug 09 13:42:42 2007 +0200
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "tag-registry.h"
+#include "ns3/fatal-error.h"
+
+namespace ns3 {
+
+TagRegistry::TagInfoVector *
+TagRegistry::GetInfo (void)
+{
+ static TagRegistry::TagInfoVector vector;
+ return &vector;
+}
+
+std::string
+TagRegistry::GetUidString (uint32_t uid)
+{
+ TagInfo info = (*GetInfo ())[uid - 1];
+ return info.uidString;
+}
+uint32_t
+TagRegistry::GetUidFromUidString (std::string uidString)
+{
+ TagInfoVector *vec = GetInfo ();
+ uint32_t uid = 1;
+ for (TagInfoVector::iterator i = vec->begin (); i != vec->end (); i++)
+ {
+ if (i->uidString == uidString)
+ {
+ return uid;
+ }
+ uid++;
+ }
+ NS_FATAL_ERROR ("We are trying to deserialize an un-registered type. This can't work.");
+ return 0;
+}
+
+void
+TagRegistry::Destruct (uint32_t uid, uint8_t *data)
+{
+ TagInfo info = (*GetInfo ())[uid - 1];
+ info.destruct (data);
+}
+void
+TagRegistry::Print (uint32_t uid, uint8_t *data, std::ostream &os)
+{
+ TagInfo info = (*GetInfo ())[uid - 1];
+ info.print (data, os);
+}
+uint32_t
+TagRegistry::GetSerializedSize (uint32_t uid, uint8_t *data)
+{
+ TagInfo info = (*GetInfo ())[uid - 1];
+ return info.getSerializedSize (data);
+}
+void
+TagRegistry::Serialize (uint32_t uid, uint8_t *data, Buffer::Iterator start)
+{
+ TagInfo info = (*GetInfo ())[uid - 1];
+ info.serialize (data, start);
+}
+uint32_t
+TagRegistry::Deserialize (uint32_t uid, uint8_t *data, Buffer::Iterator start)
+{
+ TagInfo info = (*GetInfo ())[uid - 1];
+ return info.deserialize (data, start);
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/tag-registry.h Thu Aug 09 13:42:42 2007 +0200
@@ -0,0 +1,149 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef TAG_REGISTRY_H
+#define TAG_REGISTRY_H
+
+#include <string>
+#include <stdint.h>
+#include "buffer.h"
+
+namespace ns3 {
+
+/**
+ * \brief a registry of all existing tag types.
+ * \internal
+ *
+ * This class is used to give polymorphic access to the methods
+ * exported by a tag. It also is used to associate a single
+ * reliable uid to each unique type.
+ */
+class TagRegistry
+{
+public:
+ template <typename T>
+ static uint32_t Register (std::string uidString);
+ static std::string GetUidString (uint32_t uid);
+ static uint32_t GetUidFromUidString (std::string uidString);
+ static void Destruct (uint32_t uid, uint8_t *data);
+ static void Print (uint32_t uid, uint8_t *data, std::ostream &os);
+ static uint32_t GetSerializedSize (uint32_t uid, uint8_t *data);
+ static void Serialize (uint32_t uid, uint8_t *data, Buffer::Iterator start);
+ static uint32_t Deserialize (uint32_t uid, uint8_t *data, Buffer::Iterator start);
+private:
+ typedef void (*DestructCb) (uint8_t *);
+ typedef void (*PrintCb) (uint8_t *, std::ostream &);
+ typedef uint32_t (*GetSerializedSizeCb) (uint8_t *);
+ typedef void (*SerializeCb) (uint8_t *, Buffer::Iterator);
+ typedef uint32_t (*DeserializeCb) (uint8_t *, Buffer::Iterator);
+ struct TagInfo
+ {
+ std::string uidString;
+ DestructCb destruct;
+ PrintCb print;
+ GetSerializedSizeCb getSerializedSize;
+ SerializeCb serialize;
+ DeserializeCb deserialize;
+ };
+ typedef std::vector<struct TagInfo> TagInfoVector;
+
+ template <typename T>
+ static void DoDestruct (uint8_t *data);
+ template <typename T>
+ static void DoPrint (uint8_t *data, std::ostream &os);
+ template <typename T>
+ static uint32_t DoGetSerializedSize (uint8_t *data);
+ template <typename T>
+ static void DoSerialize (uint8_t *data, Buffer::Iterator start);
+ template <typename T>
+ static uint32_t DoDeserialize (uint8_t *data, Buffer::Iterator start);
+
+ static TagInfoVector *GetInfo (void);
+};
+
+} // namespace ns3
+
+namespace ns3 {
+
+template <typename T>
+void
+TagRegistry::DoDestruct (uint8_t *data)
+{
+ T *tag = reinterpret_cast<T *> (data);
+ tag->~T ();
+}
+template <typename T>
+void
+TagRegistry::DoPrint (uint8_t *data, std::ostream &os)
+{
+ T *tag = reinterpret_cast<T *> (data);
+ tag->Print (os);
+}
+template <typename T>
+uint32_t
+TagRegistry::DoGetSerializedSize (uint8_t *data)
+{
+ T *tag = reinterpret_cast<T *> (data);
+ return tag->GetSerializedSize ();
+}
+template <typename T>
+void
+TagRegistry::DoSerialize (uint8_t *data, Buffer::Iterator start)
+{
+ T *tag = reinterpret_cast<T *> (data);
+ tag->Serialize (start);
+}
+template <typename T>
+uint32_t
+TagRegistry::DoDeserialize (uint8_t *data, Buffer::Iterator start)
+{
+ T *tag = reinterpret_cast<T *> (data);
+ return tag->Deserialize (start);
+}
+
+template <typename T>
+uint32_t
+TagRegistry::Register (std::string uidString)
+{
+ TagInfoVector *vec = GetInfo ();
+ uint32_t j = 0;
+ for (TagInfoVector::iterator i = vec->begin (); i != vec->end (); i++)
+ {
+ if (i->uidString == uidString)
+ {
+ return j;
+ }
+ j++;
+ }
+ TagInfo info;
+ info.uidString = uidString;
+ info.destruct = &TagRegistry::DoDestruct<T>;
+ info.print = &TagRegistry::DoPrint<T>;
+ info.getSerializedSize = &TagRegistry::DoGetSerializedSize<T>;
+ info.serialize = &TagRegistry::DoSerialize<T>;
+ info.deserialize = &TagRegistry::DoDeserialize<T>;
+ vec->push_back (info);
+ uint32_t uid = vec->size ();
+ return uid;
+}
+
+} // namespace ns3
+
+#endif /* TAG_REGISTRY_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/tag.h Thu Aug 09 13:42:42 2007 +0200
@@ -0,0 +1,126 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef TAG_H
+#define TAG_H
+
+#include <stdint.h>
+#include <string>
+
+/**
+ * \relates ns3::Tag
+ * \brief this macro should be instantiated exactly once for each
+ * new type of Tag
+ *
+ * This macro will ensure that your new Tag type is registered
+ * within the tag registry. In most cases, this macro
+ * is not really needed but, for safety, please, use it all the
+ * time.
+ *
+ * Note: This macro is _absolutely_ needed if you try to run a
+ * distributed simulation.
+ */
+#define NS_TAG_ENSURE_REGISTERED(x) \
+static class thisisaveryverylongclassname ##x \
+{ \
+ public: \
+ thisisaveryverylongclassname ##x () \
+ { uint32_t uid; uid = x::GetUid ();} \
+} g_thisisanotherveryveryverylongname ## x;
+
+namespace ns3 {
+
+/**
+ * \brief a tag can be stored in a packet.
+ *
+ * A tag is a blob of 16 bytes of data which can be stored in
+ * a packet: a packet can contain an arbitrary number of tags
+ * and these tags are considered as "on-the-side" per-packet
+ * data structures which are not taken into account when calculating
+ * the size of the payload of a packet. They exist solely as
+ * simulation-specific objects.
+ *
+ * Tags are typically used to:
+ * - implement per-packet cross-layer communication
+ * - implement packet coloring: you could store a "color" tag
+ * in a packet to mark various types of packet for
+ * simulation analysis
+ *
+ * To create a new type of tag, you must create a subclass
+ * of the Tag base class which defines:
+ * - a public default constructor: needed for implementation
+ * purposes of the Packet code.
+ * - a public copy constructor: needed to copy a tag into
+ * a packet tag buffer when the user invokes Packet::AddTag
+ * - a public destructor: needed to destroy the copy of a tag
+ * stored in a packet buffer when the user invokes Packet::RemoveTag
+ * or when the packet is destroyed and the last reference to
+ * a tag instance disapears.
+ * - a public static method named GetUid: needed to uniquely
+ * the type of each tag instance.
+ * - a public method named Print: needed to print the content
+ * of a tag when the user calls Packet::PrintTags
+ * - a public method named GetSerializedSize: needed to serialize
+ * the content of a tag to a byte buffer when a packet must
+ * be sent from one computing node to another in a parallel
+ * simulation. If this method returns 0, it means that the
+ * tag does not need to be transfered from computing node to
+ * computing node
+ * - a public method named Serialize: perform the serialization
+ * to a byte buffer upon transfer to a new computing node in a
+ * parallel simulation.
+ * - a public method named Deserialize: invert the serialization
+ * from a byte buffer after being transfered to a new computing
+ * node in a parallel simulation.
+ *
+ * A detailed example of what these methods should look like
+ * and how they should be implemented is described in samples/main-packet-tag.cc
+ */
+class Tag
+{
+protected:
+ /**
+ * \param name the unique name of the new type of tag
+ * \returns a newly-allocated uid
+ *
+ * This method should be used by subclasses to implement
+ * their static public GetUid method.
+ */
+ template <typename T>
+ static uint32_t AllocateUid (std::string name);
+};
+
+} // namespace ns3
+
+// implementation below.
+#include "tag-registry.h"
+
+namespace ns3 {
+
+template <typename T>
+uint32_t
+Tag::AllocateUid (std::string name)
+{
+ return TagRegistry::Register<T> (name);
+}
+
+} // namespace ns3
+
+#endif /* TAG_H */
--- a/src/common/tags.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/tags.cc Thu Aug 09 13:42:42 2007 +0200
@@ -24,67 +24,6 @@
namespace ns3 {
-TagRegistry::TagInfoVector *
-TagRegistry::GetInfo (void)
-{
- static TagRegistry::TagInfoVector vector;
- return &vector;
-}
-
-std::string
-TagRegistry::GetUidString (uint32_t uid)
-{
- TagInfo info = (*GetInfo ())[uid - 1];
- return info.uidString;
-}
-uint32_t
-TagRegistry::GetUidFromUidString (std::string uidString)
-{
- TagInfoVector *vec = GetInfo ();
- uint32_t uid = 1;
- for (TagInfoVector::iterator i = vec->begin (); i != vec->end (); i++)
- {
- if (i->uidString == uidString)
- {
- return uid;
- }
- uid++;
- }
- NS_FATAL_ERROR ("We are trying to deserialize an un-registered type. This can't work.");
- return 0;
-}
-
-void
-TagRegistry::Destruct (uint32_t uid, uint8_t data[Tags::SIZE])
-{
- TagInfo info = (*GetInfo ())[uid - 1];
- info.destruct (data);
-}
-void
-TagRegistry::Print (uint32_t uid, uint8_t data[Tags::SIZE], std::ostream &os)
-{
- TagInfo info = (*GetInfo ())[uid - 1];
- info.print (data, os);
-}
-uint32_t
-TagRegistry::GetSerializedSize (uint32_t uid, uint8_t data[Tags::SIZE])
-{
- TagInfo info = (*GetInfo ())[uid - 1];
- return info.getSerializedSize (data);
-}
-void
-TagRegistry::Serialize (uint32_t uid, uint8_t data[Tags::SIZE], Buffer::Iterator start)
-{
- TagInfo info = (*GetInfo ())[uid - 1];
- info.serialize (data, start);
-}
-uint32_t
-TagRegistry::Deserialize (uint32_t uid, uint8_t data[Tags::SIZE], Buffer::Iterator start)
-{
- TagInfo info = (*GetInfo ())[uid - 1];
- return info.deserialize (data, start);
-}
-
#ifdef USE_FREE_LIST
struct Tags::TagData *Tags::gFree = 0;
@@ -185,6 +124,10 @@
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next)
{
TagRegistry::Print (cur->m_id, cur->m_data, os);
+ if (cur->m_next != 0)
+ {
+ os << " ";
+ }
}
}
@@ -296,10 +239,10 @@
virtual bool RunTests (void);
};
-class myTagA
+class myTagA : public Tag
{
public:
- static uint32_t GetUid (void) {static uint32_t uid = TagRegistry::Register<myTagA> ("myTagA.test.nsnam.org"); return uid;}
+ static uint32_t GetUid (void) {static uint32_t uid = AllocateUid<myTagA> ("myTagA.test.nsnam.org"); return uid;}
void Print (std::ostream &os) const {g_a = true;}
uint32_t GetSerializedSize (void) const {return 1;}
void Serialize (Buffer::Iterator i) const {i.WriteU8 (a);}
@@ -307,10 +250,10 @@
uint8_t a;
};
-class myTagB
+class myTagB : public Tag
{
public:
- static uint32_t GetUid (void) {static uint32_t uid = TagRegistry::Register<myTagB> ("myTagB.test.nsnam.org"); return uid;}
+ static uint32_t GetUid (void) {static uint32_t uid = AllocateUid<myTagB> ("myTagB.test.nsnam.org"); return uid;}
void Print (std::ostream &os) const {g_b = true;}
uint32_t GetSerializedSize (void) const {return 4;}
void Serialize (Buffer::Iterator i) const {i.WriteU32 (b);}
@@ -318,21 +261,21 @@
uint32_t b;
};
-class myTagC
+class myTagC : public Tag
{
public:
- static uint32_t GetUid (void) {static uint32_t uid = TagRegistry::Register<myTagC> ("myTagC.test.nsnam.org"); return uid;}
+ static uint32_t GetUid (void) {static uint32_t uid = AllocateUid<myTagC> ("myTagC.test.nsnam.org"); return uid;}
void Print (std::ostream &os) const {g_c = true;}
uint32_t GetSerializedSize (void) const {return Tags::SIZE;}
void Serialize (Buffer::Iterator i) const {i.Write (c, Tags::SIZE);}
uint32_t Deserialize (Buffer::Iterator i) {i.Read (c, Tags::SIZE); return Tags::SIZE;}
uint8_t c [Tags::SIZE];
};
-class myInvalidTag
+class myInvalidTag : public Tag
{
public:
static uint32_t GetUid (void)
- {static uint32_t uid = TagRegistry::Register<myInvalidTag> ("myinvalidTag.test.nsnam.org"); return uid;}
+ {static uint32_t uid = AllocateUid<myInvalidTag> ("myinvalidTag.test.nsnam.org"); return uid;}
void Print (std::ostream &os) const {}
uint32_t GetSerializedSize (void) const {return 0;}
void Serialize (Buffer::Iterator i) const {}
@@ -340,10 +283,10 @@
uint8_t invalid [Tags::SIZE+1];
};
-class myTagZ
+class myTagZ : public Tag
{
public:
- static uint32_t GetUid (void) {static uint32_t uid = TagRegistry::Register<myTagZ> ("myTagZ.test.nsnam.org"); return uid;}
+ static uint32_t GetUid (void) {static uint32_t uid = AllocateUid<myTagZ> ("myTagZ.test.nsnam.org"); return uid;}
void Print (std::ostream &os) const {g_z = true;}
uint32_t GetSerializedSize (void) const {return 0;}
void Serialize (Buffer::Iterator i) const {}
@@ -352,11 +295,11 @@
uint8_t z;
};
-class MySmartTag
+class MySmartTag : public Tag
{
public:
static uint32_t GetUid (void)
- {static uint32_t uid = TagRegistry::Register<MySmartTag> ("MySmartTag.test.nsnam.org"); return uid;}
+ {static uint32_t uid = AllocateUid<MySmartTag> ("MySmartTag.test.nsnam.org"); return uid;}
MySmartTag ()
{
//std::cout << "construct" << std::endl;
--- a/src/common/tags.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/tags.h Thu Aug 09 13:42:42 2007 +0200
@@ -26,35 +26,8 @@
#include <vector>
#include "buffer.h"
-/**
- * \ingroup tag
- * \brief this macro should be instantiated exactly once for each
- * new type of Tag
- *
- * This macro will ensure that your new Tag type is registered
- * within the tag registry. In most cases, this macro
- * is not really needed but, for safety, please, use it all the
- * time.
- *
- * Note: This macro is _absolutely_ needed if you try to run a
- * distributed simulation.
- */
-#define NS_TAG_ENSURE_REGISTERED(x) \
-namespace { \
-static class thisisaveryverylongclassname \
-{ \
-public: \
- thisisaveryverylongclassname () \
- { uint32_t uid; uid = x::GetUid ();} \
-} g_thisisanotherveryveryverylongname; \
-}
-
-
namespace ns3 {
-template <typename T>
-class TagPrettyPrinter;
-
/**
* \ingroup constants
* \brief Tag maximum size
@@ -114,128 +87,22 @@
/**************************************************************
An implementation of the templates defined above
*************************************************************/
+#include "tag-registry.h"
+#include "tag.h"
#include "ns3/assert.h"
#include <string>
namespace ns3 {
-/**
- * \brief a registry of all existing tag types.
- * \internal
- *
- * This class is used to give polymorphic access to the methods
- * exported by a tag. It also is used to associate a single
- * reliable uid to each unique type.
- */
-class TagRegistry
-{
-public:
- template <typename T>
- static uint32_t Register (std::string uidString);
- static std::string GetUidString (uint32_t uid);
- static uint32_t GetUidFromUidString (std::string uidString);
- static void Destruct (uint32_t uid, uint8_t data[Tags::SIZE]);
- static void Print (uint32_t uid, uint8_t data[Tags::SIZE], std::ostream &os);
- static uint32_t GetSerializedSize (uint32_t uid, uint8_t data[Tags::SIZE]);
- static void Serialize (uint32_t uid, uint8_t data[Tags::SIZE], Buffer::Iterator start);
- static uint32_t Deserialize (uint32_t uid, uint8_t data[Tags::SIZE], Buffer::Iterator start);
-private:
- typedef void (*DestructCb) (uint8_t [Tags::SIZE]);
- typedef void (*PrintCb) (uint8_t [Tags::SIZE], std::ostream &);
- typedef uint32_t (*GetSerializedSizeCb) (uint8_t [Tags::SIZE]);
- typedef void (*SerializeCb) (uint8_t [Tags::SIZE], Buffer::Iterator);
- typedef uint32_t (*DeserializeCb) (uint8_t [Tags::SIZE], Buffer::Iterator);
- struct TagInfo
- {
- std::string uidString;
- DestructCb destruct;
- PrintCb print;
- GetSerializedSizeCb getSerializedSize;
- SerializeCb serialize;
- DeserializeCb deserialize;
- };
- typedef std::vector<struct TagInfo> TagInfoVector;
-
- template <typename T>
- static void DoDestruct (uint8_t data[Tags::SIZE]);
- template <typename T>
- static void DoPrint (uint8_t data[Tags::SIZE], std::ostream &os);
- template <typename T>
- static uint32_t DoGetSerializedSize (uint8_t data[Tags::SIZE]);
- template <typename T>
- static void DoSerialize (uint8_t data[Tags::SIZE], Buffer::Iterator start);
- template <typename T>
- static uint32_t DoDeserialize (uint8_t data[Tags::SIZE], Buffer::Iterator start);
-
- static TagInfoVector *GetInfo (void);
-};
-
-template <typename T>
-void
-TagRegistry::DoDestruct (uint8_t data[Tags::SIZE])
-{
- T *tag = reinterpret_cast<T *> (data);
- tag->~T ();
-}
-template <typename T>
-void
-TagRegistry::DoPrint (uint8_t data[Tags::SIZE], std::ostream &os)
-{
- T *tag = reinterpret_cast<T *> (data);
- tag->Print (os);
-}
-template <typename T>
-uint32_t
-TagRegistry::DoGetSerializedSize (uint8_t data[Tags::SIZE])
-{
- T *tag = reinterpret_cast<T *> (data);
- return tag->GetSerializedSize ();
-}
-template <typename T>
-void
-TagRegistry::DoSerialize (uint8_t data[Tags::SIZE], Buffer::Iterator start)
-{
- T *tag = reinterpret_cast<T *> (data);
- tag->Serialize (start);
-}
-template <typename T>
-uint32_t
-TagRegistry::DoDeserialize (uint8_t data[Tags::SIZE], Buffer::Iterator start)
-{
- T *tag = reinterpret_cast<T *> (data);
- return tag->Deserialize (start);
-}
-
-template <typename T>
-uint32_t
-TagRegistry::Register (std::string uidString)
-{
- TagInfoVector *vec = GetInfo ();
- uint32_t j = 0;
- for (TagInfoVector::iterator i = vec->begin (); i != vec->end (); i++)
- {
- if (i->uidString == uidString)
- {
- return j;
- }
- j++;
- }
- TagInfo info;
- info.uidString = uidString;
- info.destruct = &TagRegistry::DoDestruct<T>;
- info.print = &TagRegistry::DoPrint<T>;
- info.getSerializedSize = &TagRegistry::DoGetSerializedSize<T>;
- info.serialize = &TagRegistry::DoSerialize<T>;
- info.deserialize = &TagRegistry::DoDeserialize<T>;
- vec->push_back (info);
- uint32_t uid = vec->size ();
- return uid;
-}
-
template <typename T>
void
Tags::Add (T const&tag)
{
+ const Tag *parent;
+ // if the following assignment fails, it is because the
+ // input to this function is not a subclass of the Tag class.
+ parent = &tag;
+
NS_ASSERT (sizeof (T) <= Tags::SIZE);
// ensure this id was not yet added
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next)
@@ -256,6 +123,10 @@
bool
Tags::Remove (T &tag)
{
+ Tag *parent;
+ // if the following assignment fails, it is because the
+ // input to this function is not a subclass of the Tag class.
+ parent = &tag;
NS_ASSERT (sizeof (T) <= Tags::SIZE);
return Remove (T::GetUid ());
}
@@ -264,6 +135,10 @@
bool
Tags::Peek (T &tag) const
{
+ Tag *parent;
+ // if the following assignment fails, it is because the
+ // input to this function is not a subclass of the Tag class.
+ parent = &tag;
NS_ASSERT (sizeof (T) <= Tags::SIZE);
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next)
{
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/trace-context-element.cc Thu Aug 09 13:42:42 2007 +0200
@@ -0,0 +1,34 @@
+#include "trace-context-element.h"
+
+namespace ns3 {
+
+uint32_t
+ElementRegistry::GetSize (uint16_t uid)
+{
+ InfoVector *vec = GetInfoVector ();
+ struct Info info = (*vec)[uid - 1];
+ return info.size;
+}
+void
+ElementRegistry::Print (uint16_t uid, uint8_t *instance, std::ostream &os)
+{
+ InfoVector *vec = GetInfoVector ();
+ struct Info info = (*vec)[uid - 1];
+ info.print (instance, os);
+}
+void
+ElementRegistry::Destroy (uint16_t uid, uint8_t *instance)
+{
+ InfoVector *vec = GetInfoVector ();
+ struct Info info = (*vec)[uid - 1];
+ info.destroy (instance);
+}
+ElementRegistry::InfoVector *
+ElementRegistry::GetInfoVector (void)
+{
+ static InfoVector vector;
+ return &vector;
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/trace-context-element.h Thu Aug 09 13:42:42 2007 +0200
@@ -0,0 +1,189 @@
+#ifndef TRACE_CONTEXT_ELEMENT_H
+#define TRACE_CONTEXT_ELEMENT_H
+
+#include <string>
+#include <vector>
+
+#define NS_TRACE_CONTEXT_ELEMENT_ENSURE_REGISTERED(x) \
+namespace { \
+static class thisisaveryverylongclassname ##x \
+ { \
+ public: \
+ thisisaveryverylongclassname ##x () \
+ { uint32_t uid; uid = x::GetUid ();} \
+ } g_thisisanotherveryveryverylongname ##x ; \
+}
+
+namespace ns3 {
+
+/**
+ * \brief an item stored in a TraceContext
+ *
+ * To store trace context information in a TraceContext instance,
+ * users must subclass this base class and store subclass instances
+ * in a TraceContext with TraceContext::Add.
+ *
+ * Each subclass should define and implement:
+ * - a public default constructor: it is used by the internals
+ * of the implementation of TraceContext.
+ * - a public destructor: it is also used by the internals of
+ * the implementation of TraceContext.
+ * - a public static method named GetUid which returns a 16 bit
+ * integer. The integer returned from this method should be
+ * allocated with the protected AllocatedUid method.
+ * - a public Print method: this method is used by the
+ * TraceContext::Print method to print the content of each
+ * of the trace context element stored in the trace context.
+ * This method takes a c++ output stream and argument and is
+ * expected to write an ascii string describing its content
+ * in this output stream.
+ *
+ * A typical subclass should look like this:
+ * \code
+ * class MyContext : public TraceContextElement
+ * {
+ * public:
+ * // the _required_ public API
+ * static uint16_t GetUid (void);
+ * MyContext ();
+ * ~MyContext ();
+ * void Print (std::ostream &os) const;
+ *
+ * // the user-specific API to manipulate the context.
+ * void SetData (uint8_t data);
+ * uint8_t GetData (void) const;
+ * private:
+ * uint8_t m_myContextData;
+ * };
+ *
+ * uint16_t
+ * MyContext::GetUid (void)
+ * {
+ * static uint16_t uid = AllocateUid<MyContext> ("MyContext");
+ * return uid;
+ * }
+ * MyContext::MyContext ()
+ * {}
+ * MyContext::~MyContext ()
+ * {}
+ * void
+ * MyContext::Print (std::ostream &os) const
+ * {
+ * os << "mycontext=" << (uint32_t) m_myContextData;
+ * }
+ * void
+ * MyContext::SetData (uint8_t data)
+ * {
+ * m_myContextData = data;
+ * }
+ * uint8_t
+ * MyContext::GetData (void) const
+ * {
+ * return m_myContextData;
+ * }
+ * \endcode
+ */
+class TraceContextElement
+{
+protected:
+ /**
+ * \param name a string which uniquely identifies the type
+ * of the subclass which is calling this method.
+ * \returns a unique 32 bit integer associated to the
+ * input string.
+ *
+ * Subclasses are expected to call this method from their
+ * public static GetUid method.
+ */
+ template <typename T>
+ static uint16_t AllocateUid (std::string name);
+};
+
+} // namespace ns3
+
+namespace ns3 {
+
+/**
+ * \brief a registry of TraceContextElement subclasses
+ * \internal
+ */
+class ElementRegistry
+{
+public:
+ template <typename T>
+ static uint16_t AllocateUid (std::string name);
+
+ static uint32_t GetSize (uint16_t uid);
+ static void Print (uint16_t uid, uint8_t *instance, std::ostream &os);
+ static void Destroy (uint16_t uid, uint8_t *instance);
+private:
+ typedef void (*PrintCb) (uint8_t *instance, std::ostream &os);
+ typedef void (*DestroyCb) (uint8_t *instance);
+ struct Info {
+ uint32_t size;
+ std::string uidString;
+ PrintCb print;
+ DestroyCb destroy;
+ };
+ typedef std::vector<struct Info> InfoVector;
+ static InfoVector *GetInfoVector (void);
+ template <typename T>
+ static void DoPrint (uint8_t *instance, std::ostream &os);
+ template <typename T>
+ static void DoDestroy (uint8_t *instance);
+};
+
+template <typename T>
+void
+ElementRegistry::DoPrint (uint8_t *instance, std::ostream &os)
+{
+ static T obj;
+ // make sure we are aligned.
+ memcpy ((void*)&obj, instance, sizeof (T));
+ obj.Print (os);
+}
+template <typename T>
+void
+ElementRegistry::DoDestroy (uint8_t *instance)
+{
+ static T obj;
+ // make sure we are aligned.
+ memcpy ((void*)&obj, instance, sizeof (T));
+ obj.~T ();
+}
+
+template <typename T>
+uint16_t
+ElementRegistry::AllocateUid (std::string name)
+{
+ InfoVector *vec = GetInfoVector ();
+ uint16_t uid = 1;
+ for (InfoVector::iterator i = vec->begin (); i != vec->end (); i++)
+ {
+ if (i->uidString == name)
+ {
+ return uid;
+ }
+ uid++;
+ }
+ struct Info info;
+ info.size = sizeof (T);
+ info.uidString = name;
+ info.print = &ElementRegistry::DoPrint<T>;
+ info.destroy = &ElementRegistry::DoDestroy<T>;
+ vec->push_back (info);
+ return vec->size ();
+}
+
+
+
+template <typename T>
+uint16_t
+TraceContextElement::AllocateUid (std::string name)
+{
+ return ElementRegistry::AllocateUid<T> (name);
+}
+
+} // namespace ns3
+
+#endif /* TRACE_CONTEXT_ELEMENT_H */
--- a/src/common/trace-context.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/trace-context.cc Thu Aug 09 13:42:42 2007 +0200
@@ -19,11 +19,11 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "trace-context.h"
+#include "trace-context-element.h"
#include "ns3/assert.h"
namespace ns3 {
-
TraceContext::TraceContext ()
: m_data (0)
{}
@@ -67,19 +67,6 @@
}
}
-TraceContext::Sizes *
-TraceContext::GetSizes (void)
-{
- static Sizes sizes;
- return &sizes;
-}
-
-uint8_t
-TraceContext::GetSize (uint8_t uid)
-{
- return (*GetSizes ())[uid];
-}
-
void
TraceContext::Add (TraceContext const &o)
{
@@ -87,12 +74,12 @@
{
return;
}
- uint8_t currentUid;
+ uint16_t currentUid;
uint16_t i = 0;
while (i < o.m_data->size)
{
currentUid = o.m_data->data[i];
- uint8_t size = TraceContext::GetSize (currentUid);
+ uint8_t size = ElementRegistry::GetSize (currentUid);
uint8_t *selfBuffer = CheckPresent (currentUid);
uint8_t *otherBuffer = &(o.m_data->data[i+1]);
if (selfBuffer != 0)
@@ -122,7 +109,7 @@
uint16_t i = 0;
do {
currentUid = m_data->data[i];
- uint8_t size = TraceContext::GetSize (currentUid);
+ uint8_t size = ElementRegistry::GetSize (currentUid);
if (currentUid == uid)
{
return &m_data->data[i+1];
@@ -137,7 +124,7 @@
TraceContext::DoAdd (uint8_t uid, uint8_t const *buffer)
{
NS_ASSERT (uid != 0);
- uint8_t size = TraceContext::GetSize (uid);
+ uint8_t size = ElementRegistry::GetSize (uid);
uint8_t *present = CheckPresent (uid);
if (present != 0) {
if (memcmp (present, buffer, size) == 0)
@@ -207,7 +194,7 @@
uint16_t i = 0;
do {
currentUid = m_data->data[i];
- uint8_t size = TraceContext::GetSize (currentUid);
+ uint8_t size = ElementRegistry::GetSize (currentUid);
if (currentUid == uid)
{
memcpy (buffer, &m_data->data[i+1], size);
@@ -218,31 +205,48 @@
return false;
}
-uint8_t
-TraceContext::DoGetNextUid (void)
+void
+TraceContext::Print (std::ostream &os) const
{
- static uint8_t uid = 0;
- if (uid == 0)
+ if (m_data == 0)
{
- GetSizes ()->push_back (0);
+ return;
}
- uid++;
- return uid;
+ uint8_t currentUid;
+ uint16_t i = 0;
+ do {
+ currentUid = m_data->data[i];
+ uint8_t size = ElementRegistry::GetSize (currentUid);
+ uint8_t *instance = &m_data->data[i+1];
+ ElementRegistry::Print (currentUid, instance, os);
+ i += 1 + size;
+ if (i < m_data->size && currentUid != 0)
+ {
+ os << " ";
+ }
+ else
+ {
+ break;
+ }
+ } while (true);
}
-
}//namespace ns3
#include "ns3/test.h"
+#include <sstream>
namespace ns3 {
template <int N>
-class Ctx
+class Ctx : public TraceContextElement
{
public:
+ static uint16_t GetUid (void) {static uint16_t uid = AllocateUid<Ctx<N> > (GetName ()); return uid;}
+ static std::string GetName (void) {std::ostringstream oss; oss << "Ctx" << N; return oss.str ();}
Ctx () : m_v (0) {}
Ctx (int v) : m_v (v) {}
+ void Print (std::ostream &os) {os << N;}
int Get (void) const { return N;}
private:
int m_v;
--- a/src/common/trace-context.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/trace-context.h Thu Aug 09 13:42:42 2007 +0200
@@ -24,6 +24,7 @@
#include <stdint.h>
#include <vector>
#include "ns3/fatal-error.h"
+#include "trace-context-element.h"
namespace ns3 {
@@ -77,26 +78,20 @@
*/
template <typename T>
void Get (T &context) const;
+
+ void Print (std::ostream &os) const;
private:
friend class TraceContextTest;
// used exclusively for testing code.
template <typename T>
bool SafeGet (T &context) const;
template <typename T>
- bool SafeAdd (T &context);
+ bool SafeAdd (const T &context);
- template <typename T>
- static uint8_t GetUid (void);
- template <typename T>
- static uint8_t GetNextUid (void);
- static uint8_t DoGetNextUid (void);
- static uint8_t GetSize (uint8_t uid);
uint8_t *CheckPresent (uint8_t uid) const;
bool DoAdd (uint8_t uid, uint8_t const *buffer);
bool DoGet (uint8_t uid, uint8_t *buffer) const;
- typedef std::vector<uint8_t> Sizes;
- static Sizes *GetSizes (void);
struct Data {
uint16_t count;
uint16_t size;
@@ -112,8 +107,12 @@
void
TraceContext::Add (T const &context)
{
+ const TraceContextElement *parent;
+ // if the following assignment fails, it is because the input
+ // to this function is not a subclass of the TraceContextElement class.
+ parent = &context;
uint8_t *data = (uint8_t *) &context;
- bool ok = DoAdd (TraceContext::GetUid<T> (), data);
+ bool ok = DoAdd (T::GetUid (), data);
if (!ok)
{
NS_FATAL_ERROR ("Trying to add twice the same type with different values is invalid.");
@@ -123,8 +122,12 @@
void
TraceContext::Get (T &context) const
{
+ TraceContextElement *parent;
+ // if the following assignment fails, it is because the input
+ // to this function is not a subclass of the TraceContextElement class.
+ parent = &context;
uint8_t *data = (uint8_t *) &context;
- bool found = DoGet (TraceContext::GetUid<T> (), data);
+ bool found = DoGet (T::GetUid (), data);
if (!found)
{
NS_FATAL_ERROR ("Type not stored in TraceContext");
@@ -134,35 +137,26 @@
bool
TraceContext::SafeGet (T &context) const
{
+ TraceContextElement *parent;
+ // if the following assignment fails, it is because the input
+ // to this function is not a subclass of the TraceContextElement class.
+ parent = &context;
uint8_t *data = (uint8_t *) &context;
- bool found = DoGet (TraceContext::GetUid<T> (), data);
+ bool found = DoGet (T::GetUid (), data);
return found;
}
template <typename T>
bool
-TraceContext::SafeAdd (T &context)
+TraceContext::SafeAdd (const T &context)
{
+ const TraceContextElement *parent;
+ // if the following assignment fails, it is because the input
+ // to this function is not a subclass of the TraceContextElement class.
+ parent = &context;
uint8_t *data = (uint8_t *) &context;
- bool ok = DoAdd (TraceContext::GetUid<T> (), data);
+ bool ok = DoAdd (T::GetUid (), data);
return ok;
}
-template <typename T>
-uint8_t
-TraceContext::GetUid (void)
-{
- static uint8_t uid = GetNextUid<T> ();
- return uid;
-}
-
-template <typename T>
-uint8_t
-TraceContext::GetNextUid (void)
-{
- uint8_t uid = DoGetNextUid ();
- GetSizes ()->push_back (sizeof (T));
- return uid;
-}
-
}//namespace ns3
#endif /* TRACE_CONTEXT_H */
--- a/src/common/trace-root.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/trace-root.cc Thu Aug 09 13:42:42 2007 +0200
@@ -41,7 +41,7 @@
Callback<TraceResolver *,TraceContext const &> createResolver)
{
CompositeTraceResolver *resolver = GetComposite ();
- resolver->Add (name, createResolver, TraceRoot::NOTHING);
+ resolver->Add (name, createResolver);
}
CompositeTraceResolver *
--- a/src/common/trace-root.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/trace-root.h Thu Aug 09 13:42:42 2007 +0200
@@ -328,9 +328,6 @@
Callback<TraceResolver *,TraceContext const &> createResolver);
private:
static CompositeTraceResolver *GetComposite (void);
- enum TraceType {
- NOTHING,
- };
};
}// namespace ns3
--- a/src/common/trailer.cc Thu Aug 09 13:38:04 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "trailer.h"
-
-namespace ns3 {
-
-Trailer::~Trailer ()
-{}
-
-}; // namespace ns3
--- a/src/common/trailer.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/trailer.h Thu Aug 09 13:42:42 2007 +0200
@@ -22,10 +22,10 @@
#ifndef TRAILER_H
#define TRAILER_H
-#include "chunk.h"
+#include "chunk-registry.h"
/**
- * \relates Trailer
+ * \relates ns3::Trailer
* \brief this macro should be instantiated exactly once for each
* new type of Trailer
*
@@ -37,15 +37,13 @@
* Note: This macro is _absolutely_ needed if you try to run a
* distributed simulation.
*/
-#define NS_TRAILER_ENSURE_REGISTERED(x) \
-namespace { \
-static class thisisaveryverylongclassname \
-{ \
-public: \
- thisisaveryverylongclassname () \
- { uint32_t uid; uid = x::GetUid ();} \
-} g_thisisanotherveryveryverylongname; \
-}
+#define NS_TRAILER_ENSURE_REGISTERED(x) \
+static class thisisaveryverylongclassname ##x \
+{ \
+ public: \
+ thisisaveryverylongclassname ##x () \
+ { uint32_t uid; uid = x::GetUid ();} \
+} g_thisisanotherveryveryverylongname ##x;
namespace ns3 {
@@ -53,123 +51,52 @@
* \brief Protocol trailer serialization and deserialization.
*
* Every Protocol trailer which needs to be inserted or removed
- * from a Packet instance must derive from this abstract base class
- * and implement the private pure virtual methods listed below:
- * - ns3::Trailer::SerializeTo
- * - ns3::Trailer::DeserializeFrom
- * - ns3::Trailer::GetSerializedSize
- * - ns3::Trailer::PrintTo
- * - ns3::Trailer::DoGetName
- *
- * Each trailer must also make sure that:
- * - it defines a public default constructor
- * - it defines a public static method named GetUid which returns a 32 bit integer.
- *
- * The latter should look like the following:
- * \code
- * // in the header
- * class MyTrailer : public Header
- * {
- * public:
- * static uint32_t GetUid (void);
- * };
- *
- * // in the source file
- * NS_TRAILER_ENSURE_REGISTERED (MyTrailer);
+ * from a Packet instance must derive from this base class and
+ * implement the following public methods:
+ * - a default constructor: is used by the internal implementation
+ * if the Packet class.
+ * - a static method named GetUid: is used to uniquely identify
+ * the type of each trailer. This method shall return a unique
+ * integer allocated with Trailer::AllocateUid.
+ * - a method named Serialize: is used by Packet::AddTrailer to
+ * store a trailer into the byte buffer of a packet.
+ * The input iterator points to the end of the byte buffer in
+ * which the trailer should write its data: the user is thus
+ * required to call Buffer::Iterator::Prev prior to writing
+ * any data in the buffer. The data written is expected to
+ * match bit-for-bit the representation of this trailer in a
+ * real network.
+ * - a method named GetSerializedSize: is used by Packet::AddTrailer
+ * to store a trailer into the byte buffer of a packet. This method
+ * should return the number of bytes which are needed to store
+ * the full trailer data by Serialize.
+ * - a method named Deserialize: is used by Packet::RemoveTrailer to
+ * re-create a trailer from the byte buffer of a packet. The input
+ * iterator points to the end of the byte buffer from which
+ * the trailer should read its data: the user is thus required to
+ * call Buffer::Iterator::Prev prior to reading any data from the
+ * buffer. The data read is expected to match bit-for-bit the
+ * representation of this trailer in real networks. This method
+ * shall return an integer which identifies the number of bytes read.
+ * - a method named Print: is used by Packet::Print to print the
+ * content of a trailer as ascii data to a c++ output stream.
+ * Although the trailer is free to format its output as it
+ * wishes, it is recommended to follow a few rules to integrate
+ * with the packet pretty printer: start with flags, small field
+ * values located between a pair of parens. Values should be separated
+ * by whitespace. Follow the parens with the important fields,
+ * separated by whitespace.
+ * i.e.: (field1 val1 field2 val2 field3 val3) field4 val4 field5 val5
+ * - a method named GetName: is used by Packet::Print to print
+ * trailer fragments. This method should return a user-readable
+ * single word as all capitalized letters.
*
- * uint32_t MyTrailer::GetUid (void)
- * {
- * static uint32_t uid = Trailer::Register<MyTrailer> ("MyTrailer.unique.prefix");
- * return uid;
- * }
- * \endcode
- *
- * Note that the SerializeTo and DeserializeFrom methods behave
- * in a way which might seem surprising to users: the input iterator
- * really points to the end of the buffer to which and from which
- * the user is expected to write and read respectively. This means that
- * if the trailer has a fixed size and if the user wishes to read or
- * write that trailer from front to back, the user must rewind the
- * iterator by hand to go to the start of the trailer. Typical code
- * looks like this:
- * \code
- * void CrcTrailer::SerializeTo (Buffer::Iterator end)
- * {
- * end.Prev (4);
- * end.WriteHtonU32 (m_crc);
- * }
- * \endcode
- *
- * Some users would have expected that the iterator would be rewinded
- * to the "start" of the trailer before calling SerializeTo and DeserializeFrom.
- * However, this behavior was not implemented because it cannot be made to
- * work reliably for trailers which have a variable size. i.e., if the trailer
- * contains options, the code which calls DeserializeFrom cannot rewind
- * to the start of the trailer because it does not know the real size of the
- * trailer. Hence, to make this legitimate use-case work (variable-sized
- * trailers), the input iterator to DeserializeFrom and SerializeTo points
- * to the end of the trailer, and not its start.
*/
-class Trailer : public Chunk {
-public:
- virtual ~Trailer ();
+class Trailer
+{
protected:
template <typename T>
- static uint32_t Register (std::string uidString);
-private:
- /**
- * \returns a user-readable name to identify this type of header.
- *
- * The string returned is expected to be a single word with
- * all capital letters
- */
- virtual std::string DoGetName (void) const = 0;
- /**
- * \param os the std output stream in which this
- * protocol trailer must print itself.
- *
- * Although the header is free to format its output as it
- * wishes, it is recommended to follow a few rules to integrate
- * with the packet pretty printer:
- * - start with flags, small field values located between a
- * pair of parens. Values should be separated by whitespace.
- * - follow the parens with the important fields, separated by
- * whitespace.
- * i.e.:
- * (field1 val1 field2 val2 field3 val3) field4 val4 field5 val5
- */
- virtual void PrintTo (std::ostream &os) const = 0;
-
- /**
- * \returns the size of the serialized Trailer.
- *
- * This method is used by Packet::AddTrailer to reserve
- * enough room in the packet byte buffer prior to calling
- * Trailer::Serialize.
- */
- virtual uint32_t GetSerializedSize (void) const = 0;
-
- /**
- * \param end the buffer iterator in which the protocol trailer
- * must serialize itself. This iterator identifies
- * the end of the buffer.
- *
- * This iterator must be typically moved with the Buffer::Iterator::Prev
- * method before writing any byte in the buffer.
- */
- virtual void SerializeTo (Buffer::Iterator end) const = 0;
- /**
- * \param end the buffer iterator from which the protocol trailer must
- * deserialize itself. This iterator identifies
- * the end of the buffer.
- * \returns the number of bytes read from the buffer
- *
- * This iterator must be typically moved with the Buffer::Iterator::Prev
- * method before reading any byte in the buffer. The value returned
- * is used to trim the packet byte buffer of the corresponding
- * amount when this method is invoked from Packet::RemoveTrailer
- */
- virtual uint32_t DeserializeFrom (Buffer::Iterator end) = 0;
+ static uint32_t AllocateUid (std::string uidString);
};
} // namespace ns3
@@ -178,7 +105,7 @@
template <typename T>
uint32_t
-Trailer::Register (std::string uidString)
+Trailer::AllocateUid (std::string uidString)
{
return ChunkRegistry::RegisterTrailer<T> (uidString);
}
--- a/src/common/wscript Thu Aug 09 13:38:04 2007 +0200
+++ b/src/common/wscript Thu Aug 09 13:42:42 2007 +0200
@@ -4,17 +4,17 @@
common = bld.create_ns3_module('common', ['core', 'simulator'])
common.source = [
'buffer.cc',
- 'chunk.cc',
- 'header.cc',
- 'trailer.cc',
+ 'chunk-registry.cc',
'packet-printer.cc',
'packet-metadata.cc',
'packet-metadata-test.cc',
'packet.cc',
'tags.cc',
+ 'tag-registry.cc',
'pcap-writer.cc',
'variable-tracer-test.cc',
'trace-context.cc',
+ 'trace-context-element.cc',
'trace-resolver.cc',
'callback-trace-source.cc',
'empty-trace-resolver.cc',
@@ -26,10 +26,12 @@
headers = bld.create_obj('ns3header')
headers.source = [
'buffer.h',
- 'chunk.h',
+ 'chunk-registry.h',
'header.h',
'trailer.h',
'tags.h',
+ 'tag-registry.h',
+ 'tag.h',
'packet.h',
'packet-printer.h',
'packet-metadata.h',
@@ -39,6 +41,7 @@
'pcap-writer.h',
'callback-trace-source.h',
'trace-context.h',
+ 'trace-context-element.h',
'trace-resolver.h',
'empty-trace-resolver.h',
'composite-trace-resolver.h',
--- a/src/core/assert.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/core/assert.h Thu Aug 09 13:42:42 2007 +0200
@@ -28,6 +28,17 @@
#include "breakpoint.h"
/**
+ * \defgroup assert Assert
+ * \brief assert functions and macros
+ *
+ * The assert macros are used to verify
+ * at runtime that a certain condition is true. If it is
+ * not true, the program halts. These checks are built
+ * into the program only in debugging builds. They are
+ * removed in optimized builds.
+ */
+
+/**
* \ingroup assert
* \param condition condition to verifiy.
*
--- a/src/core/callback.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/core/callback.h Thu Aug 09 13:42:42 2007 +0200
@@ -358,7 +358,7 @@
/**
* \ingroup MakeCallback
- * \param mem_ptr class method member pointer
+ * \param memPtr class method member pointer
* \param objPtr class instance
* \return a wrapper Callback
* Build Callbacks for class method members which takes no arguments
--- a/src/core/component-manager.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/core/component-manager.h Thu Aug 09 13:42:42 2007 +0200
@@ -348,7 +348,7 @@
* result.
*/
template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
- static Ptr<T> Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2, T3 a3, T4 a4, T5);
+ static Ptr<T> Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
private:
friend void RegisterCallback (ClassId classId, CallbackBase *callback,
--- a/src/core/random-variable.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/core/random-variable.h Thu Aug 09 13:42:42 2007 +0200
@@ -772,6 +772,7 @@
/**
* \param s Low end of the range
* \param l High end of the range
+ * \param mean mean of the distribution
* \return A triangularly distributed random number between s and l
*/
static double GetSingleValue(double s, double l, double mean);
--- a/src/devices/csma-cd/csma-cd-net-device.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/devices/csma-cd/csma-cd-net-device.cc Thu Aug 09 13:42:42 2007 +0200
@@ -35,6 +35,32 @@
namespace ns3 {
+CsmaCdTraceType::CsmaCdTraceType (enum Type type)
+ : m_type (type)
+{}
+CsmaCdTraceType::CsmaCdTraceType ()
+ : m_type (RX)
+{}
+void
+CsmaCdTraceType::Print (std::ostream &os) const
+{
+ switch (m_type) {
+ case RX:
+ os << "dev-rx";
+ break;
+ case DROP:
+ os << "dev-drop";
+ break;
+ }
+}
+uint16_t
+CsmaCdTraceType::GetUid (void)
+{
+ static uint16_t uid = AllocateUid<CsmaCdTraceType> ("CsmaCdTraceType");
+ return uid;
+}
+
+
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node)
: NetDevice (node, Eui48Address::Allocate ()),
m_bps (DataRate (0xffffffff))
@@ -177,7 +203,7 @@
switch (m_encapMode)
{
case ETHERNET_V1:
- lengthType = p.GetSize() + header.GetSize() + trailer.GetSize();
+ lengthType = p.GetSize() + header.GetSerializedSize() + trailer.GetSerializedSize();
break;
case IP_ARP:
lengthType = protocolNumber;
@@ -429,12 +455,14 @@
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
resolver->Add ("queue",
MakeCallback (&Queue::CreateTraceResolver,
- PeekPointer (m_queue)),
- CsmaCdNetDevice::QUEUE);
+ PeekPointer (m_queue)));
resolver->Add ("rx",
m_rxTrace,
- CsmaCdNetDevice::RX);
- return resolver;
+ CsmaCdTraceType (CsmaCdTraceType::RX));
+ resolver->Add ("drop",
+ m_dropTrace,
+ CsmaCdTraceType (CsmaCdTraceType::DROP));
+ return resolver;
}
bool
--- a/src/devices/csma-cd/csma-cd-net-device.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/devices/csma-cd/csma-cd-net-device.h Thu Aug 09 13:42:42 2007 +0200
@@ -41,6 +41,21 @@
class Queue;
class CsmaCdChannel;
+class CsmaCdTraceType : public TraceContextElement
+{
+public:
+ enum Type {
+ RX,
+ DROP
+ };
+ CsmaCdTraceType (enum Type type);
+ CsmaCdTraceType ();
+ void Print (std::ostream &os) const;
+ static uint16_t GetUid (void);
+private:
+ enum Type m_type;
+};
+
/**
* \class CsmaCdNetDevice
* \brief A Device for a CsmaCd Network Link.
@@ -62,15 +77,6 @@
*/
class CsmaCdNetDevice : public NetDevice {
public:
- /**
- * Enumeration of the types of traces supported in the class.
- *
- */
- enum TraceType {
- QUEUE, /**< Trace queue events on the attached queue */
- RX, /**< Trace packet reception events (from the channel) */
- DROP /**< Trace packet drop events (from the channel) */
- };
/**
* Enumeration of the types of packets supported in the class.
--- a/src/devices/point-to-point/point-to-point-net-device.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/devices/point-to-point/point-to-point-net-device.cc Thu Aug 09 13:42:42 2007 +0200
@@ -40,6 +40,21 @@
"The default data rate for point to point links",
DataRate ("10Mb/s"));
+PointToPointTraceType::PointToPointTraceType ()
+{}
+void
+PointToPointTraceType::Print (std::ostream &os) const
+{
+ os << "dev-rx";
+}
+uint16_t
+PointToPointTraceType::GetUid (void)
+{
+ static uint16_t uid = AllocateUid<PointToPointTraceType> ("PointToPointTraceType");
+ return uid;
+}
+
+
PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node,
const DataRate& rate)
:
@@ -178,11 +193,10 @@
{
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
resolver->Add ("queue",
- MakeCallback (&Queue::CreateTraceResolver, PeekPointer (m_queue)),
- PointToPointNetDevice::QUEUE);
+ MakeCallback (&Queue::CreateTraceResolver, PeekPointer (m_queue)));
resolver->Add ("rx",
m_rxTrace,
- PointToPointNetDevice::RX);
+ PointToPointTraceType ());
return resolver;
}
--- a/src/devices/point-to-point/point-to-point-net-device.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/devices/point-to-point/point-to-point-net-device.h Thu Aug 09 13:42:42 2007 +0200
@@ -38,6 +38,14 @@
class Queue;
class PointToPointChannel;
+class PointToPointTraceType : public TraceContextElement
+{
+public:
+ PointToPointTraceType ();
+ void Print (std::ostream &os) const;
+ static uint16_t GetUid (void);
+};
+
/**
* \class PointToPointNetDevice
* \brief A Device for a Point to Point Network Link.
@@ -64,14 +72,6 @@
class PointToPointNetDevice : public NetDevice {
public:
/**
- * Enumeration of the types of traces supported in the class.
- *
- */
- enum TraceType {
- QUEUE, /**< Trace queue events on the attached queue */
- RX, /**< Trace packet reception events (from the channel) */
- };
- /**
* Construct a PointToPointNetDevice
*
* This is the constructor for the PointToPointNetDevice. It takes as a
--- a/src/internet-node/arp-header.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/arp-header.cc Thu Aug 09 13:42:42 2007 +0200
@@ -23,20 +23,17 @@
#include "ns3/address-utils.h"
#include "arp-header.h"
-NS_HEADER_ENSURE_REGISTERED (ns3::ArpHeader);
+namespace ns3 {
-namespace ns3 {
+NS_HEADER_ENSURE_REGISTERED (ArpHeader);
uint32_t
ArpHeader::GetUid (void)
{
- static uint32_t uid = Header::Register<ArpHeader> ("ArpHeader.ns3");
+ static uint32_t uid = AllocateUid<ArpHeader> ("ArpHeader.ns3");
return uid;
}
-ArpHeader::~ArpHeader ()
-{}
-
void
ArpHeader::SetRequest (Address sourceHardwareAddress,
Ipv4Address sourceProtocolAddress,
@@ -93,13 +90,13 @@
}
std::string
-ArpHeader::DoGetName (void) const
+ArpHeader::GetName (void) const
{
return "ARP";
}
void
-ArpHeader::PrintTo (std::ostream &os) const
+ArpHeader::Print (std::ostream &os) const
{
if (IsRequest ())
{
@@ -132,7 +129,7 @@
}
void
-ArpHeader::SerializeTo (Buffer::Iterator start) const
+ArpHeader::Serialize (Buffer::Iterator start) const
{
Buffer::Iterator i = start;
NS_ASSERT (m_macSource.GetLength () == m_macDest.GetLength ());
@@ -150,7 +147,7 @@
WriteTo (i, m_ipv4Dest);
}
uint32_t
-ArpHeader::DeserializeFrom (Buffer::Iterator start)
+ArpHeader::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
i.Next (2+2);
--- a/src/internet-node/arp-header.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/arp-header.h Thu Aug 09 13:42:42 2007 +0200
@@ -36,8 +36,6 @@
public:
static uint32_t GetUid (void);
- virtual ~ArpHeader ();
-
void SetRequest (Address sourceHardwareAddress,
Ipv4Address sourceProtocolAddress,
Address destinationHardwareAddress,
@@ -53,25 +51,11 @@
Ipv4Address GetSourceIpv4Address (void);
Ipv4Address GetDestinationIpv4Address (void);
-private:
- virtual std::string DoGetName (void) const;
- /**
- * \param os
- */
- virtual void PrintTo (std::ostream &os) const;
- /**
- * \return
- */
- virtual uint32_t GetSerializedSize (void) const;
- /**
- * \param start
- */
- virtual void SerializeTo (Buffer::Iterator start) const;
- /**
- * \param start
- * \return
- */
- virtual uint32_t DeserializeFrom (Buffer::Iterator start);
+ std::string GetName (void) const;
+ void Print (std::ostream &os) const;
+ uint32_t GetSerializedSize (void) const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
enum ArpType_e {
ARP_TYPE_REQUEST = 1,
--- a/src/internet-node/arp-ipv4-interface.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/arp-ipv4-interface.cc Thu Aug 09 13:42:42 2007 +0200
@@ -47,8 +47,7 @@
if (GetDevice () != 0)
{
resolver->Add ("netdevice",
- MakeCallback (&NetDevice::CreateTraceResolver, PeekPointer (GetDevice ())),
- ArpIpv4Interface::NETDEVICE);
+ MakeCallback (&NetDevice::CreateTraceResolver, PeekPointer (GetDevice ())));
}
return resolver;
--- a/src/internet-node/arp-ipv4-interface.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/arp-ipv4-interface.h Thu Aug 09 13:42:42 2007 +0200
@@ -39,10 +39,6 @@
class ArpIpv4Interface : public Ipv4Interface
{
public:
- enum TraceType {
- NETDEVICE,
- ARP,
- };
ArpIpv4Interface (Ptr<Node> node, Ptr<NetDevice> device);
virtual ~ArpIpv4Interface ();
--- a/src/internet-node/ascii-trace.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/ascii-trace.cc Thu Aug 09 13:42:42 2007 +0200
@@ -24,8 +24,7 @@
#include "ns3/trace-root.h"
#include "ns3/simulator.h"
#include "ns3/node.h"
-#include "ns3/queue.h"
-#include "ns3/node-list.h"
+#include "ns3/packet.h"
namespace ns3 {
@@ -55,42 +54,18 @@
void
AsciiTrace::LogDevQueue (TraceContext const &context, Packet const &packet)
{
- enum Queue::TraceType type;
- context.Get (type);
- switch (type)
- {
- case Queue::ENQUEUE:
- m_os << "+ ";
- break;
- case Queue::DEQUEUE:
- m_os << "- ";
- break;
- case Queue::DROP:
- m_os << "d ";
- break;
- }
m_os << Simulator::Now ().GetSeconds () << " ";
- NodeList::NodeIndex nodeIndex;
- context.Get (nodeIndex);
- m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
- Node::NetDeviceIndex deviceIndex;
- context.Get (deviceIndex);
- m_os << "device=" << deviceIndex << " ";
- m_os << "pkt-uid=" << packet.GetUid () << " ";
+ context.Print (m_os);
+ m_os << " pkt-uid=" << packet.GetUid () << " ";
packet.Print (m_os);
m_os << std::endl;
}
void
AsciiTrace::LogDevRx (TraceContext const &context, Packet &p)
{
- m_os << "r " << Simulator::Now ().GetSeconds () << " ";
- NodeList::NodeIndex nodeIndex;
- context.Get (nodeIndex);
- m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
- Node::NetDeviceIndex deviceIndex;
- context.Get (deviceIndex);
- m_os << "device=" << deviceIndex << " ";
- m_os << "pkt-uid=" << p.GetUid () << " ";
+ m_os << Simulator::Now ().GetSeconds () << " ";
+ context.Print (m_os);
+ m_os << " pkt-uid=" << p.GetUid () << " ";
p.Print (m_os);
m_os << std::endl;
}
--- a/src/internet-node/internet-node.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/internet-node.cc Thu Aug 09 13:42:42 2007 +0200
@@ -80,8 +80,7 @@
Node::DoFillTraceResolver (resolver);
Ptr<Ipv4L3Protocol> ipv4 = QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
resolver.Add ("ipv4",
- MakeCallback (&Ipv4L3Protocol::CreateTraceResolver, PeekPointer (ipv4)),
- InternetNode::IPV4);
+ MakeCallback (&Ipv4L3Protocol::CreateTraceResolver, PeekPointer (ipv4)));
}
void
--- a/src/internet-node/internet-node.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/internet-node.h Thu Aug 09 13:42:42 2007 +0200
@@ -36,9 +36,6 @@
class InternetNode : public Node
{
public:
- enum TraceType {
- IPV4,
- };
InternetNode();
InternetNode(uint32_t systemId);
virtual ~InternetNode ();
--- a/src/internet-node/ipv4-header.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/ipv4-header.cc Thu Aug 09 13:42:42 2007 +0200
@@ -26,16 +26,16 @@
NS_DEBUG_COMPONENT_DEFINE ("Ipv4Header");
-NS_HEADER_ENSURE_REGISTERED (ns3::Ipv4Header);
+namespace ns3 {
-namespace ns3 {
+NS_HEADER_ENSURE_REGISTERED (Ipv4Header);
bool Ipv4Header::m_calcChecksum = false;
uint32_t
Ipv4Header::GetUid (void)
{
- static uint32_t uid = Header::Register<Ipv4Header> ("Ipv4Header.ns3");
+ static uint32_t uid = AllocateUid<Ipv4Header> ("Ipv4Header.ns3");
return uid;
}
@@ -49,8 +49,6 @@
m_fragmentOffset (0),
m_goodChecksum (true)
{}
-Ipv4Header::~Ipv4Header ()
-{}
void
Ipv4Header::EnableChecksums (void)
@@ -189,13 +187,13 @@
}
std::string
-Ipv4Header::DoGetName (void) const
+Ipv4Header::GetName (void) const
{
return "IPV4";
}
void
-Ipv4Header::PrintTo (std::ostream &os) const
+Ipv4Header::Print (std::ostream &os) const
{
// ipv4, right ?
std::string flags;
@@ -238,7 +236,7 @@
}
void
-Ipv4Header::SerializeTo (Buffer::Iterator start) const
+Ipv4Header::Serialize (Buffer::Iterator start) const
{
Buffer::Iterator i = start;
@@ -281,7 +279,7 @@
}
}
uint32_t
-Ipv4Header::DeserializeFrom (Buffer::Iterator start)
+Ipv4Header::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
uint8_t verIhl = i.ReadU8 ();
--- a/src/internet-node/ipv4-header.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/ipv4-header.h Thu Aug 09 13:42:42 2007 +0200
@@ -37,7 +37,6 @@
* \brief Construct a null IPv4 header
*/
Ipv4Header ();
- virtual ~Ipv4Header ();
/**
* \brief Enable checksum calculation for IP (XXX currently has no effect)
*/
@@ -141,12 +140,12 @@
*/
bool IsChecksumOk (void) const;
+ std::string GetName (void) const;
+ void Print (std::ostream &os) const;
+ uint32_t GetSerializedSize (void) const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
private:
- virtual std::string DoGetName (void) const;
- virtual void PrintTo (std::ostream &os) const;
- virtual uint32_t GetSerializedSize (void) const;
- virtual void SerializeTo (Buffer::Iterator start) const;
- virtual uint32_t DeserializeFrom (Buffer::Iterator start);
enum FlagsE {
DONT_FRAGMENT = (1<<0),
@@ -167,7 +166,7 @@
bool m_goodChecksum;
};
-}; // namespace ns3
+} // namespace ns3
#endif /* IPV4_HEADER_H */
--- a/src/internet-node/ipv4-l3-protocol.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/ipv4-l3-protocol.cc Thu Aug 09 13:42:42 2007 +0200
@@ -44,6 +44,76 @@
const InterfaceId Ipv4L3Protocol::iid = MakeInterfaceId ("Ipv4L3Protocol", Object::iid);
const uint16_t Ipv4L3Protocol::PROT_NUMBER = 0x0800;
+Ipv4L3ProtocolTraceContextElement::Ipv4L3ProtocolTraceContextElement ()
+ : m_type (TX)
+{}
+Ipv4L3ProtocolTraceContextElement::Ipv4L3ProtocolTraceContextElement (enum Type type)
+ : m_type (type)
+{}
+bool
+Ipv4L3ProtocolTraceContextElement::IsTx (void) const
+{
+ return m_type == TX;
+}
+bool
+Ipv4L3ProtocolTraceContextElement::IsRx (void) const
+{
+ return m_type == RX;
+}
+bool
+Ipv4L3ProtocolTraceContextElement::IsDrop (void) const
+{
+ return m_type == DROP;
+}
+void
+Ipv4L3ProtocolTraceContextElement::Print (std::ostream &os) const
+{
+ os << "ipv4=";
+ switch (m_type)
+ {
+ case TX:
+ os << "tx";
+ break;
+ case RX:
+ os << "rx";
+ break;
+ case DROP:
+ os << "drop";
+ break;
+ }
+}
+uint16_t
+Ipv4L3ProtocolTraceContextElement::GetUid (void)
+{
+ static uint16_t uid = AllocateUid<Ipv4L3ProtocolTraceContextElement> ("Ipv4L3ProtocolTraceContextElement");
+ return uid;
+}
+
+
+Ipv4l3ProtocolInterfaceIndex::Ipv4l3ProtocolInterfaceIndex ()
+ : m_index (0)
+{}
+Ipv4l3ProtocolInterfaceIndex::Ipv4l3ProtocolInterfaceIndex (uint32_t index)
+ : m_index (index)
+{}
+uint32_t
+Ipv4l3ProtocolInterfaceIndex::Get (void) const
+{
+ return m_index;
+}
+void
+Ipv4l3ProtocolInterfaceIndex::Print (std::ostream &os) const
+{
+ os << "ipv4-interface=" << m_index;
+}
+uint16_t
+Ipv4l3ProtocolInterfaceIndex::GetUid (void)
+{
+ static uint16_t uid = AllocateUid<Ipv4l3ProtocolInterfaceIndex> ("Ipv4l3ProtocolInterfaceIndex");
+ return uid;
+}
+
+
Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node)
: m_nInterfaces (0),
m_defaultTtl (64),
@@ -87,20 +157,19 @@
Ipv4L3Protocol::CreateTraceResolver (TraceContext const &context)
{
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
- resolver->Add ("tx", m_txTrace, Ipv4L3Protocol::TX);
- resolver->Add ("rx", m_rxTrace, Ipv4L3Protocol::RX);
- resolver->Add ("drop", m_dropTrace, Ipv4L3Protocol::DROP);
+ resolver->Add ("tx", m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX));
+ resolver->Add ("rx", m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX));
+ resolver->Add ("drop", m_dropTrace, Ipv4L3ProtocolTraceContextElement (Ipv4L3ProtocolTraceContextElement::DROP));
resolver->Add ("interfaces",
- MakeCallback (&Ipv4L3Protocol::InterfacesCreateTraceResolver, this),
- Ipv4L3Protocol::INTERFACES);
+ MakeCallback (&Ipv4L3Protocol::InterfacesCreateTraceResolver, this));
return resolver;
}
TraceResolver *
Ipv4L3Protocol::InterfacesCreateTraceResolver (TraceContext const &context) const
{
- ArrayTraceResolver<Ipv4Interface *> *resolver =
- new ArrayTraceResolver<Ipv4Interface *>
+ ArrayTraceResolver<Ipv4Interface *, Ipv4l3ProtocolInterfaceIndex> *resolver =
+ new ArrayTraceResolver<Ipv4Interface *,Ipv4l3ProtocolInterfaceIndex>
(context,
MakeCallback (&Ipv4L3Protocol::GetNInterfaces, this),
MakeCallback (&Ipv4L3Protocol::GetInterface, this));
--- a/src/internet-node/ipv4-l3-protocol.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/ipv4-l3-protocol.h Thu Aug 09 13:42:42 2007 +0200
@@ -25,11 +25,11 @@
#include <list>
#include <stdint.h>
#include "ns3/callback-trace-source.h"
-#include "ns3/array-trace-resolver.h"
+#include "ns3/trace-context-element.h"
#include "ns3/ipv4-address.h"
-#include "ipv4-header.h"
#include "ns3/ptr.h"
#include "ns3/ipv4.h"
+#include "ipv4-header.h"
#include "ipv4-static-routing.h"
namespace ns3 {
@@ -44,6 +44,37 @@
class TraceResolver;
class TraceContext;
+class Ipv4L3ProtocolTraceContextElement : public TraceContextElement
+{
+public:
+ enum Type {
+ TX,
+ RX,
+ DROP,
+ };
+ Ipv4L3ProtocolTraceContextElement ();
+ Ipv4L3ProtocolTraceContextElement (enum Type type);
+ bool IsTx (void) const;
+ bool IsRx (void) const;
+ bool IsDrop (void) const;
+ void Print (std::ostream &os) const;
+ static uint16_t GetUid (void);
+private:
+ enum Type m_type;
+};
+
+class Ipv4l3ProtocolInterfaceIndex : public TraceContextElement
+{
+public:
+ Ipv4l3ProtocolInterfaceIndex ();
+ Ipv4l3ProtocolInterfaceIndex (uint32_t index);
+ uint32_t Get (void) const;
+ void Print (std::ostream &os) const;
+ static uint16_t GetUid (void);
+private:
+ uint32_t m_index;
+};
+
class Ipv4L3Protocol : public Object
{
@@ -51,14 +82,6 @@
static const InterfaceId iid;
static const uint16_t PROT_NUMBER;
- enum TraceType {
- TX,
- RX,
- DROP,
- INTERFACES,
- };
- typedef ArrayTraceResolver<Ipv4Interface *>::Index InterfaceIndex;
-
Ipv4L3Protocol(Ptr<Node> node);
virtual ~Ipv4L3Protocol ();
--- a/src/internet-node/ipv4-l4-demux.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/ipv4-l4-demux.cc Thu Aug 09 13:42:42 2007 +0200
@@ -32,6 +32,30 @@
const InterfaceId Ipv4L4Demux::iid = MakeInterfaceId ("Ipv4L4Demux", Object::iid);
+Ipv4L4ProtocolTraceContextElement::Ipv4L4ProtocolTraceContextElement ()
+ : m_protocolNumber (0)
+{}
+Ipv4L4ProtocolTraceContextElement::Ipv4L4ProtocolTraceContextElement (int protocolNumber)
+ : m_protocolNumber (protocolNumber)
+{}
+int
+Ipv4L4ProtocolTraceContextElement::Get (void) const
+{
+ return m_protocolNumber;
+}
+void
+Ipv4L4ProtocolTraceContextElement::Print (std::ostream &os) const
+{
+ os << "ipv4-protocol=0x" << std::hex << m_protocolNumber << std::dec;
+}
+uint16_t
+Ipv4L4ProtocolTraceContextElement::GetUid (void)
+{
+ static uint16_t uid = AllocateUid<Ipv4L4ProtocolTraceContextElement> ("Ipv4L4ProtocolTraceContextElement");
+ return uid;
+}
+
+
Ipv4L4Demux::Ipv4L4Demux (Ptr<Node> node)
: m_node (node)
{
@@ -64,7 +88,7 @@
std::string protValue;
std::ostringstream oss (protValue);
oss << (*i)->GetProtocolNumber ();
- Ipv4L4ProtocolTraceType protocolNumber = (*i)->GetProtocolNumber ();
+ Ipv4L4ProtocolTraceContextElement protocolNumber = (*i)->GetProtocolNumber ();
resolver->Add (protValue,
MakeCallback (&Ipv4L4Protocol::CreateTraceResolver, PeekPointer (protocol)),
protocolNumber);
--- a/src/internet-node/ipv4-l4-demux.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/ipv4-l4-demux.h Thu Aug 09 13:42:42 2007 +0200
@@ -28,6 +28,7 @@
#include <list>
#include "ns3/object.h"
#include "ns3/ptr.h"
+#include "ns3/trace-context-element.h"
namespace ns3 {
@@ -36,6 +37,18 @@
class TraceResolver;
class TraceContext;
+class Ipv4L4ProtocolTraceContextElement : public TraceContextElement
+{
+public:
+ Ipv4L4ProtocolTraceContextElement ();
+ Ipv4L4ProtocolTraceContextElement (int protocolNumber);
+ int Get (void) const;
+ void Print (std::ostream &os) const;
+ static uint16_t GetUid (void);
+private:
+ int m_protocolNumber;
+};
+
/**
* \brief L4 Ipv4 Demux
*/
@@ -43,7 +56,6 @@
{
public:
static const InterfaceId iid;
- typedef int Ipv4L4ProtocolTraceType;
Ipv4L4Demux (Ptr<Node> node);
virtual ~Ipv4L4Demux();
--- a/src/internet-node/pcap-trace.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/pcap-trace.cc Thu Aug 09 13:42:42 2007 +0200
@@ -82,10 +82,9 @@
void
PcapTrace::LogIp (TraceContext const &context, Packet const &p, uint32_t interfaceIndex)
{
- NodeList::NodeIndex nodeIndex;
+ NodeListIndex nodeIndex;
context.Get (nodeIndex);
- uint32_t nodeId = NodeList::GetNode (nodeIndex)->GetId ();
- PcapWriter *writer = GetStream (nodeId, interfaceIndex);
+ PcapWriter *writer = GetStream (nodeIndex.Get (), interfaceIndex);
writer->WritePacket (p);
}
--- a/src/internet-node/udp-header.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/udp-header.cc Thu Aug 09 13:42:42 2007 +0200
@@ -22,16 +22,16 @@
#include "udp-header.h"
#include "ipv4-checksum.h"
-NS_HEADER_ENSURE_REGISTERED (ns3::UdpHeader);
+namespace ns3 {
-namespace ns3 {
+NS_HEADER_ENSURE_REGISTERED (UdpHeader);
bool UdpHeader::m_calcChecksum = false;
uint32_t
UdpHeader::GetUid (void)
{
- static uint32_t uid = Header::Register<UdpHeader> ("UdpHeader.ns3");
+ static uint32_t uid = AllocateUid<UdpHeader> ("UdpHeader.ns3");
return uid;
}
@@ -93,7 +93,7 @@
destination.Serialize (buf+4);
buf[8] = 0;
buf[9] = protocol;
- uint16_t udpLength = m_payloadSize + GetSize ();
+ uint16_t udpLength = m_payloadSize + GetSerializedSize ();
buf[10] = udpLength >> 8;
buf[11] = udpLength & 0xff;
@@ -101,16 +101,16 @@
}
std::string
-UdpHeader::DoGetName (void) const
+UdpHeader::GetName (void) const
{
return "UDP";
}
void
-UdpHeader::PrintTo (std::ostream &os) const
+UdpHeader::Print (std::ostream &os) const
{
os << "("
- << "length: " << m_payloadSize + GetSize ()
+ << "length: " << m_payloadSize + GetSerializedSize ()
<< ") "
<< m_sourcePort << " > " << m_destinationPort
;
@@ -123,12 +123,12 @@
}
void
-UdpHeader::SerializeTo (Buffer::Iterator start) const
+UdpHeader::Serialize (Buffer::Iterator start) const
{
Buffer::Iterator i = start;
i.WriteHtonU16 (m_sourcePort);
i.WriteHtonU16 (m_destinationPort);
- i.WriteHtonU16 (m_payloadSize + GetSize ());
+ i.WriteHtonU16 (m_payloadSize + GetSerializedSize ());
i.WriteU16 (0);
if (m_calcChecksum)
@@ -137,7 +137,7 @@
//XXXX
uint16_t checksum = Ipv4ChecksumCalculate (m_initialChecksum,
buffer->PeekData (),
- GetSize () + m_payloadSize);
+ GetSerializedSize () + m_payloadSize);
checksum = Ipv4ChecksumComplete (checksum);
i = buffer->Begin ();
i.Next (6);
@@ -146,12 +146,12 @@
}
}
uint32_t
-UdpHeader::DeserializeFrom (Buffer::Iterator start)
+UdpHeader::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
m_sourcePort = i.ReadNtohU16 ();
m_destinationPort = i.ReadNtohU16 ();
- m_payloadSize = i.ReadNtohU16 () - GetSize ();
+ m_payloadSize = i.ReadNtohU16 () - GetSerializedSize ();
if (m_calcChecksum)
{
// XXX verify checksum.
--- a/src/internet-node/udp-header.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/udp-header.h Thu Aug 09 13:42:42 2007 +0200
@@ -42,7 +42,7 @@
* Creates a null header
*/
UdpHeader ();
- virtual ~UdpHeader ();
+ ~UdpHeader ();
/**
* \brief Enable checksum calculation for UDP (XXX currently has no effect)
@@ -84,13 +84,13 @@
Ipv4Address destination,
uint8_t protocol);
+ std::string GetName (void) const;
+ void Print (std::ostream &os) const;
+ uint32_t GetSerializedSize (void) const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
+
private:
- virtual std::string DoGetName (void) const;
- virtual void PrintTo (std::ostream &os) const;
- virtual uint32_t GetSerializedSize (void) const;
- virtual void SerializeTo (Buffer::Iterator start) const;
- virtual uint32_t DeserializeFrom (Buffer::Iterator start);
-
uint16_t m_sourcePort;
uint16_t m_destinationPort;
uint16_t m_payloadSize;
@@ -99,6 +99,6 @@
static bool m_calcChecksum;
};
-}; // namespace ns3
+} // namespace ns3
#endif /* UDP_HEADER */
--- a/src/internet-node/wscript Thu Aug 09 13:38:04 2007 +0200
+++ b/src/internet-node/wscript Thu Aug 09 13:42:42 2007 +0200
@@ -34,4 +34,5 @@
'ascii-trace.h',
'pcap-trace.h',
'ipv4-header.h',
+ 'udp-header.h',
]
--- a/src/node/ethernet-header.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/ethernet-header.cc Thu Aug 09 13:42:42 2007 +0200
@@ -27,14 +27,14 @@
NS_DEBUG_COMPONENT_DEFINE ("EthernetHeader");
-NS_HEADER_ENSURE_REGISTERED (ns3::EthernetHeader);
+namespace ns3 {
-namespace ns3 {
+NS_HEADER_ENSURE_REGISTERED (EthernetHeader);
uint32_t
EthernetHeader::GetUid (void)
{
- static uint32_t uid = Header::Register<EthernetHeader> ("EthernetHeader.ns3");
+ static uint32_t uid = AllocateUid<EthernetHeader> ("EthernetHeader.ns3");
return uid;
}
@@ -48,9 +48,6 @@
m_lengthType (0)
{}
-EthernetHeader::~EthernetHeader ()
-{}
-
void
EthernetHeader::SetLengthType (uint16_t lengthType)
{
@@ -108,13 +105,13 @@
}
std::string
-EthernetHeader::DoGetName (void) const
+EthernetHeader::GetName (void) const
{
return "ETHERNET";
}
void
-EthernetHeader::PrintTo (std::ostream &os) const
+EthernetHeader::Print (std::ostream &os) const
{
// ethernet, right ?
if (m_enPreambleSfd)
@@ -139,7 +136,7 @@
}
void
-EthernetHeader::SerializeTo (Buffer::Iterator start) const
+EthernetHeader::Serialize (Buffer::Iterator start) const
{
Buffer::Iterator i = start;
@@ -152,7 +149,7 @@
i.WriteU16 (m_lengthType);
}
uint32_t
-EthernetHeader::DeserializeFrom (Buffer::Iterator start)
+EthernetHeader::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
--- a/src/node/ethernet-header.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/ethernet-header.h Thu Aug 09 13:42:42 2007 +0200
@@ -62,7 +62,6 @@
* By default, does not add or remove an ethernet preamble
*/
EthernetHeader ();
- virtual ~EthernetHeader ();
/**
* \param size The size of the payload in bytes
*/
@@ -104,17 +103,16 @@
*/
uint32_t GetHeaderSize() const;
+ std::string GetName (void) const;
+ void Print (std::ostream &os) const;
+ uint32_t GetSerializedSize (void) const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
private:
static const int PREAMBLE_SIZE = 8; /// size of the preamble_sfd header field
static const int LENGTH_SIZE = 2; /// size of the length_type header field
static const int MAC_ADDR_SIZE = 6; /// size of src/dest addr header fields
- virtual std::string DoGetName (void) const;
- virtual void PrintTo (std::ostream &os) const;
- virtual uint32_t GetSerializedSize (void) const;
- virtual void SerializeTo (Buffer::Iterator start) const;
- virtual uint32_t DeserializeFrom (Buffer::Iterator start);
-
/**
* If false, the preamble/sfd are not serialised/deserialised.
*/
--- a/src/node/ethernet-trailer.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/ethernet-trailer.cc Thu Aug 09 13:42:42 2007 +0200
@@ -26,16 +26,16 @@
NS_DEBUG_COMPONENT_DEFINE ("EthernetTrailer");
-NS_TRAILER_ENSURE_REGISTERED (ns3::EthernetTrailer);
+namespace ns3 {
-namespace ns3 {
+NS_TRAILER_ENSURE_REGISTERED (EthernetTrailer);
bool EthernetTrailer::m_calcFcs = false;
uint32_t
EthernetTrailer::GetUid (void)
{
- static uint32_t uid = Trailer::Register<EthernetTrailer> ("EthernetTrailer.ns3");
+ static uint32_t uid = AllocateUid<EthernetTrailer> ("EthernetTrailer.ns3");
return uid;
}
@@ -44,9 +44,6 @@
Init();
}
-EthernetTrailer::~EthernetTrailer ()
-{}
-
void EthernetTrailer::Init()
{
m_fcs = 0;
@@ -94,13 +91,13 @@
return GetSerializedSize();
}
std::string
-EthernetTrailer::DoGetName (void) const
+EthernetTrailer::GetName (void) const
{
return "ETHERNET";
}
void
-EthernetTrailer::PrintTo (std::ostream &os) const
+EthernetTrailer::Print (std::ostream &os) const
{
os << " fcs=" << m_fcs;
}
@@ -111,7 +108,7 @@
}
void
-EthernetTrailer::SerializeTo (Buffer::Iterator end) const
+EthernetTrailer::Serialize (Buffer::Iterator end) const
{
Buffer::Iterator i = end;
i.Prev(GetSerializedSize());
@@ -119,7 +116,7 @@
i.WriteU32 (m_fcs);
}
uint32_t
-EthernetTrailer::DeserializeFrom (Buffer::Iterator end)
+EthernetTrailer::Deserialize (Buffer::Iterator end)
{
Buffer::Iterator i = end;
uint32_t size = GetSerializedSize();
--- a/src/node/ethernet-trailer.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/ethernet-trailer.h Thu Aug 09 13:42:42 2007 +0200
@@ -43,7 +43,7 @@
* \brief Construct a null ethernet trailer
*/
EthernetTrailer ();
- virtual ~EthernetTrailer ();
+
/**
* \brief Enable or disabled FCS checking and calculations
* \param enable If true, enables FCS calculations.
@@ -81,12 +81,12 @@
*/
uint32_t GetTrailerSize() const;
+ std::string GetName (void) const;
+ void Print (std::ostream &os) const;
+ uint32_t GetSerializedSize (void) const;
+ void Serialize (Buffer::Iterator end) const;
+ uint32_t Deserialize (Buffer::Iterator end);
private:
- virtual std::string DoGetName (void) const;
- virtual void PrintTo (std::ostream &os) const;
- virtual uint32_t GetSerializedSize (void) const;
- virtual void SerializeTo (Buffer::Iterator end) const;
- virtual uint32_t DeserializeFrom (Buffer::Iterator end);
/**
* Initializes the trailer parameters during construction.
@@ -102,7 +102,7 @@
};
-}; // namespace ns3
+} // namespace ns3
#endif /* ETHERNET_TRAILER_H */
--- a/src/node/ipv4-address.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/ipv4-address.h Thu Aug 09 13:42:42 2007 +0200
@@ -116,7 +116,7 @@
* (bitwise and) with a network mask, yielding an IPv4 network
* address.
*
- * \param a network mask
+ * \param mask a network mask
*/
Ipv4Address CombineMask (Ipv4Mask const &mask) const;
--- a/src/node/llc-snap-header.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/llc-snap-header.cc Thu Aug 09 13:42:42 2007 +0200
@@ -23,23 +23,20 @@
#include "ns3/assert.h"
#include <string>
-NS_HEADER_ENSURE_REGISTERED (ns3::LlcSnapHeader);
+namespace ns3 {
-
-namespace ns3 {
+NS_HEADER_ENSURE_REGISTERED (LlcSnapHeader);
uint32_t
LlcSnapHeader::GetUid (void)
{
- static uint32_t uid = Header::Register<LlcSnapHeader> ("LlcSnapHeader.ns3");
+ static uint32_t uid = AllocateUid<LlcSnapHeader> ("LlcSnapHeader.ns3");
return uid;
}
LlcSnapHeader::LlcSnapHeader ()
{}
-LlcSnapHeader::~LlcSnapHeader ()
-{}
void
LlcSnapHeader::SetType (uint16_t type)
{
@@ -58,13 +55,13 @@
}
std::string
-LlcSnapHeader::DoGetName (void) const
+LlcSnapHeader::GetName (void) const
{
return "LLCSNAP";
}
void
-LlcSnapHeader::PrintTo (std::ostream &os) const
+LlcSnapHeader::Print (std::ostream &os) const
{
os << "(type 0x";
os.setf (std::ios::hex, std::ios::basefield);
@@ -74,7 +71,7 @@
}
void
-LlcSnapHeader::SerializeTo (Buffer::Iterator start) const
+LlcSnapHeader::Serialize (Buffer::Iterator start) const
{
Buffer::Iterator i = start;
uint8_t buf[] = {0xaa, 0xaa, 0x03, 0, 0, 0};
@@ -82,7 +79,7 @@
i.WriteHtonU16 (m_etherType);
}
uint32_t
-LlcSnapHeader::DeserializeFrom (Buffer::Iterator start)
+LlcSnapHeader::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
i.Next (5+1);
@@ -91,4 +88,4 @@
}
-}; // namespace ns3
+} // namespace ns3
--- a/src/node/llc-snap-header.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/llc-snap-header.h Thu Aug 09 13:42:42 2007 +0200
@@ -34,21 +34,19 @@
static uint32_t GetUid (void);
LlcSnapHeader ();
- virtual ~LlcSnapHeader ();
-
void SetType (uint16_t type);
uint16_t GetType (void);
+ std::string GetName (void) const;
+ void Print (std::ostream &os) const;
+ uint32_t GetSerializedSize (void) const;
+ void Serialize (Buffer::Iterator start) const;
+ uint32_t Deserialize (Buffer::Iterator start);
private:
- virtual std::string DoGetName (void) const;
- virtual void PrintTo (std::ostream &os) const;
- virtual uint32_t GetSerializedSize (void) const;
- virtual void SerializeTo (Buffer::Iterator start) const;
- virtual uint32_t DeserializeFrom (Buffer::Iterator start);
uint16_t m_etherType;
};
-}; // namespace ns3
+} // namespace ns3
#endif /* LLC_SNAP_HEADER_H */
--- a/src/node/node-list.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/node-list.cc Thu Aug 09 13:42:42 2007 +0200
@@ -40,6 +40,30 @@
namespace ns3 {
+NodeListIndex::NodeListIndex ()
+ : m_index (0)
+{}
+NodeListIndex::NodeListIndex (uint32_t index)
+ : m_index (index)
+{}
+void
+NodeListIndex::Print (std::ostream &os)
+{
+ os << "nodeid=" << m_index;
+}
+uint16_t
+NodeListIndex::GetUid (void)
+{
+ static uint16_t uid = AllocateUid<NodeListIndex> ("NodeListIndex");
+ return uid;
+}
+uint32_t
+NodeListIndex::Get (void) const
+{
+ return m_index;
+}
+
+
/**
* The private node list used by the static-based API
*/
@@ -109,8 +133,8 @@
TraceResolver *
NodeListPriv::CreateTraceResolver (TraceContext const &context)
{
- ArrayTraceResolver<Ptr<Node> > *resolver =
- new ArrayTraceResolver<Ptr<Node> >
+ ArrayTraceResolver<Ptr<Node>, NodeListIndex> *resolver =
+ new ArrayTraceResolver<Ptr<Node>, NodeListIndex>
(context,
MakeCallback (&NodeListPriv::GetNNodes, this),
MakeCallback (&NodeListPriv::GetNode, this));
--- a/src/node/node-list.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/node-list.h Thu Aug 09 13:42:42 2007 +0200
@@ -23,7 +23,7 @@
#define NODE_LIST_H
#include <vector>
-#include "ns3/array-trace-resolver.h"
+#include "ns3/trace-context-element.h"
#include "ns3/ptr.h"
namespace ns3 {
@@ -32,6 +32,19 @@
class TraceResolver;
class TraceContext;
+class NodeListIndex : public TraceContextElement
+{
+public:
+ NodeListIndex ();
+ NodeListIndex (uint32_t index);
+ void Print (std::ostream &os);
+ static uint16_t GetUid (void);
+ uint32_t Get (void) const;
+private:
+ uint32_t m_index;
+};
+
+
/**
* \brief the list of simulation nodes.
*
@@ -40,7 +53,6 @@
class NodeList
{
public:
- typedef ArrayTraceResolver<Ptr<Node> >::Index NodeIndex;
typedef std::vector< Ptr<Node> >::iterator Iterator;
/**
--- a/src/node/node.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/node.cc Thu Aug 09 13:42:42 2007 +0200
@@ -25,11 +25,37 @@
#include "packet-socket-factory.h"
#include "ns3/simulator.h"
#include "ns3/composite-trace-resolver.h"
+#include "ns3/array-trace-resolver.h"
namespace ns3{
const InterfaceId Node::iid = MakeInterfaceId ("Node", Object::iid);
+NodeNetDeviceIndex::NodeNetDeviceIndex ()
+ : m_index (0)
+{}
+NodeNetDeviceIndex::NodeNetDeviceIndex (uint32_t index)
+ : m_index (index)
+{}
+uint32_t
+NodeNetDeviceIndex::Get (void) const
+{
+ return m_index;
+}
+void
+NodeNetDeviceIndex::Print (std::ostream &os) const
+{
+ os << "device=" << m_index;
+}
+uint16_t
+NodeNetDeviceIndex::GetUid (void)
+{
+ static uint16_t uid = AllocateUid<NodeNetDeviceIndex> ("NodeNetDeviceIndex");
+ return uid;
+}
+
+
+
Node::Node()
: m_id(0),
m_sid(0)
@@ -118,10 +144,11 @@
TraceResolver *
Node::CreateDevicesTraceResolver (const TraceContext &context)
{
- ArrayTraceResolver<Ptr<NetDevice> > *resolver =
- new ArrayTraceResolver<Ptr<NetDevice> > (context,
- MakeCallback (&Node::GetNDevices, this),
- MakeCallback (&Node::GetDevice, this));
+ ArrayTraceResolver<Ptr<NetDevice>,NodeNetDeviceIndex> *resolver =
+ new ArrayTraceResolver<Ptr<NetDevice>,NodeNetDeviceIndex>
+ (context,
+ MakeCallback (&Node::GetNDevices, this),
+ MakeCallback (&Node::GetDevice, this));
return resolver;
}
@@ -130,8 +157,7 @@
Node::DoFillTraceResolver (CompositeTraceResolver &resolver)
{
resolver.Add ("devices",
- MakeCallback (&Node::CreateDevicesTraceResolver, this),
- Node::DEVICES);
+ MakeCallback (&Node::CreateDevicesTraceResolver, this));
}
void
--- a/src/node/node.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/node.h Thu Aug 09 13:42:42 2007 +0200
@@ -25,7 +25,7 @@
#include "ns3/object.h"
#include "ns3/callback.h"
-#include "ns3/array-trace-resolver.h"
+#include "ns3/trace-context-element.h"
namespace ns3 {
@@ -37,6 +37,18 @@
class Address;
class CompositeTraceResolver;
+class NodeNetDeviceIndex : public TraceContextElement
+{
+public:
+ NodeNetDeviceIndex ();
+ NodeNetDeviceIndex (uint32_t index);
+ uint32_t Get (void) const;
+ void Print (std::ostream &os) const;
+ static uint16_t GetUid (void);
+private:
+ uint32_t m_index;
+};
+
/**
* \brief A network Node.
*
@@ -58,7 +70,6 @@
{
public:
static const InterfaceId iid;
- typedef ArrayTraceResolver<Ptr<NetDevice> >::Index NetDeviceIndex;
/**
* Must be invoked by subclasses only.
@@ -204,9 +215,6 @@
void Construct (void);
TraceResolver *CreateDevicesTraceResolver (const TraceContext &context);
- enum TraceSource {
- DEVICES
- };
struct ProtocolHandlerEntry {
ProtocolHandler handler;
uint16_t protocol;
--- a/src/node/queue.cc Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/queue.cc Thu Aug 09 13:42:42 2007 +0200
@@ -31,6 +31,52 @@
static ClassIdDefaultValue g_classIdDefaultValue ("Queue", "Packet Queue",
Queue::iid, "DropTailQueue");
+
+uint16_t
+QueueTraceType::GetUid (void)
+{
+ static uint16_t uid = AllocateUid<QueueTraceType> ("QueueTraceType");
+ return uid;
+}
+QueueTraceType::QueueTraceType ()
+ : m_type (QueueTraceType::ENQUEUE)
+{}
+QueueTraceType::QueueTraceType (enum Type type)
+ : m_type (type)
+{}
+bool
+QueueTraceType::IsEnqueue (void) const
+{
+ return m_type == ENQUEUE;
+}
+bool
+QueueTraceType::IsDequeue (void) const
+{
+ return m_type == DEQUEUE;
+}
+bool
+QueueTraceType::IsDrop (void) const
+{
+ return m_type == DROP;
+}
+
+void
+QueueTraceType::Print (std::ostream &os) const
+{
+ os << "queue-";
+ switch (m_type) {
+ case QueueTraceType::ENQUEUE:
+ os << "enqueue";
+ break;
+ case QueueTraceType::DEQUEUE:
+ os << "dequeue";
+ break;
+ case QueueTraceType::DROP:
+ os << "drop";
+ break;
+ }
+}
+
Queue::Queue() :
m_nBytes(0),
m_nTotalReceivedBytes(0),
@@ -52,9 +98,9 @@
Queue::CreateTraceResolver (TraceContext const &context)
{
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
- resolver->Add ("enqueue", m_traceEnqueue, Queue::ENQUEUE);
- resolver->Add ("dequeue", m_traceDequeue, Queue::DEQUEUE);
- resolver->Add ("drop", m_traceDrop, Queue::DROP);
+ resolver->Add ("enqueue", m_traceEnqueue, QueueTraceType (QueueTraceType::ENQUEUE));
+ resolver->Add ("dequeue", m_traceDequeue, QueueTraceType (QueueTraceType::DEQUEUE));
+ resolver->Add ("drop", m_traceDrop, QueueTraceType (QueueTraceType::DROP));
return resolver;
}
--- a/src/node/queue.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/node/queue.h Thu Aug 09 13:42:42 2007 +0200
@@ -31,11 +31,32 @@
#include "ns3/object.h"
#include "ns3/callback-trace-source.h"
#include "ns3/trace-resolver.h"
+#include "ns3/trace-context-element.h"
namespace ns3 {
class StringEnumDefaultValue;
+class QueueTraceType : public TraceContextElement
+{
+public:
+ enum Type {
+ ENQUEUE,
+ DEQUEUE,
+ DROP
+ };
+ static uint16_t GetUid (void);
+ QueueTraceType ();
+ QueueTraceType (enum Type type);
+ bool IsEnqueue (void) const;
+ bool IsDequeue (void) const;
+ bool IsDrop (void) const;
+ void Print (std::ostream &os) const;
+private:
+ enum Type m_type;
+};
+
+
/**
* \brief Abstract base class for packet Queues
*
@@ -46,11 +67,6 @@
public:
static const InterfaceId iid;
- enum TraceType {
- ENQUEUE,
- DEQUEUE,
- DROP,
- };
Queue ();
virtual ~Queue ();
--- a/src/simulator/scheduler.h Thu Aug 09 13:38:04 2007 +0200
+++ b/src/simulator/scheduler.h Thu Aug 09 13:42:42 2007 +0200
@@ -58,9 +58,7 @@
virtual ~Scheduler () = 0;
/**
- * \param event event to store in the event list
- * \param key timecode associated to this new event
- * \returns an event id which identifies the event inserted
+ * \param id event to store in the event list
*
* This method takes ownership of the event pointer.
*/
@@ -83,9 +81,8 @@
virtual EventId RemoveNext (void) = 0;
/**
* \param id the id of the event to remove
- * \param key the timecode of the event removed
- * \returns a pointer to the event removed. The caller
- * takes ownership of the returned pointer.
+ * \returns true if the id was found and removed
+ * successfully, false otherwise.
*
* This methods cannot be invoked if the list is empty.
*/