--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/main-header.cc Fri Aug 03 17:00:40 2007 +0200
@@ -0,0 +1,123 @@
+/* -*- 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 const char *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 ()
+{}
+
+const char *
+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.
+ return "MyHeader.test.nsnam.org";
+}
+
+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;
+}
--- a/samples/main-packet.cc Fri Aug 03 14:09:04 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +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 const char *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;
-};
-
-const char *
-MyHeader::GetUid (void)
-{
- // make sure the string is really unique.
- return "MyHeader.test.nsnam.org";
-}
-
-MyHeader::MyHeader ()
-{}
-MyHeader::~MyHeader ()
-{}
-std::string
-MyHeader::DoGetName (void) const
-{
- return "MyHeader";
-}
-void
-MyHeader::PrintTo (std::ostream &os) const
-{
- os << "MyHeader data=" << m_data << std::endl;
-}
-uint32_t
-MyHeader::GetSerializedSize (void) const
-{
- return 2;
-}
-void
-MyHeader::SerializeTo (Buffer::Iterator start) const
-{
- // serialize in head of buffer
- start.WriteHtonU16 (m_data);
-}
-uint32_t
-MyHeader::DeserializeFrom (Buffer::Iterator start)
-{
- // deserialize from head of buffer
- m_data = start.ReadNtohU16 ();
- return GetSerializedSize ();
-}
-
-void
-MyHeader::SetData (uint16_t data)
-{
- m_data = data;
-}
-uint16_t
-MyHeader::GetData (void) const
-{
- return m_data;
-}
-
-/* A sample Tag implementation
- */
-class MyTag
-{
-public:
- static const char *GetUid (void) {return "MyTag.test.nsnam.org";}
- void Print (std::ostream &os) const {}
- uint32_t GetSerializedSize (void) const {return 0;}
- void Serialize (Buffer::Iterator i) const {}
- uint32_t Deserialize (Buffer::Iterator i) {return 0;}
-
- uint16_t m_streamId;
-};
-
-static void
-Receive (Packet p)
-{
- MyHeader my;
- p.RemoveHeader (my);
- std::cout << "received data=" << my.GetData () << std::endl;
- struct MyTag myTag;
- p.PeekTag (myTag);
-}
-
-
-int main (int argc, char *argv[])
-{
- Packet p;
- MyHeader my;
- my.SetData (2);
- std::cout << "send data=2" << std::endl;
- p.AddHeader (my);
- struct MyTag myTag;
- myTag.m_streamId = 5;
- p.AddTag (myTag);
- Receive (p);
- return 0;
-}
--- a/samples/wscript Fri Aug 03 14:09:04 2007 +0200
+++ b/samples/wscript Fri Aug 03 17:00:40 2007 +0200
@@ -14,7 +14,7 @@
obj = create_ns_prog('main-ptr', 'main-ptr.cc')
#obj = create_ns_prog('main-trace', 'main-trace.cc')
obj = create_ns_prog('main-simulator', 'main-simulator.cc')
- obj = create_ns_prog('main-packet', 'main-packet.cc')
+ obj = create_ns_prog('main-header', 'main-header.cc')
obj = create_ns_prog('main-test', 'main-test.cc')
obj = create_ns_prog('main-simple', 'main-simple.cc',
deps=['node', 'internet-node', 'applications'])
--- a/src/common/header.h Fri Aug 03 14:09:04 2007 +0200
+++ b/src/common/header.h Fri Aug 03 17:00:40 2007 +0200
@@ -36,6 +36,29 @@
* - 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 string.
+ *
+ * The latter should look like the following to ensure that
+ * every header returns a unique string.
+ * \code
+ * class MyHeader : public Header
+ * {
+ * public:
+ * static const char *GetUid (void);
+ * };
+ *
+ * const char *MyHeader::GetUid (void)
+ * {
+ * return "MyHeader.unique.prefix";
+ * }
+ * \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
*/
class Header : public Chunk {
public:
--- a/src/common/packet.h Fri Aug 03 14:09:04 2007 +0200
+++ b/src/common/packet.h Fri Aug 03 17:00:40 2007 +0200
@@ -58,21 +58,19 @@
* were serialized in the byte buffer. The maintenance of metadata is
* optional and disabled by default. To enable it, you must call
* Packet::EnableMetadata and this will allow you to get non-empty
- * output from Packet::Print and Packet::PrintDefault.
+ * output from Packet::Print and Packet::Print.
*
* 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 4 pure virtual
+ * 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 implement a static public method named GetUid which is
- * expected to return a unique string which uniquely identifies the
- * user's new header or trailer.
- *
- * 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
+ * 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.
*
* Implementing a new type of Tag requires roughly the same amount of
- * work:
+ * work: users must implement a total of 6 methods which are described in
+ * the ns3::Tags API documentation.
*
* 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
--- a/src/common/trailer.h Fri Aug 03 14:09:04 2007 +0200
+++ b/src/common/trailer.h Fri Aug 03 17:00:40 2007 +0200
@@ -36,6 +36,26 @@
* - 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 string.
+ *
+ * The latter should look like the following to ensure that
+ * every trailer returns a unique string.
+ * \code
+ * class MyTrailer : public Header
+ * {
+ * public:
+ * static const char *GetUid (void);
+ * };
+ *
+ * const char *MyTrailer::GetUid (void)
+ * {
+ * return "MyTrailer.unique.prefix";
+ * }
+ * \endcode
*
* Note that the SerializeTo and DeserializeFrom methods behave
* in a way which might seem surprising to users: the input iterator