add Packet::Ref/Unref methods
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Mon, 01 Oct 2007 14:14:31 +0200
changeset 1865 829dc1815014
parent 1864 f5f263266774
child 1866 e7dbcc4df546
add Packet::Ref/Unref methods
src/common/packet.cc
src/common/packet.h
--- a/src/common/packet.cc	Mon Oct 01 14:07:53 2007 +0200
+++ b/src/common/packet.cc	Mon Oct 01 14:14:31 2007 +0200
@@ -26,22 +26,72 @@
 
 uint32_t Packet::m_globalUid = 0;
 
+void 
+Packet::Ref (void) const
+{
+  m_refCount++;
+}
+void 
+Packet::Unref (void) const
+{
+  m_refCount--;
+  if (m_refCount == 0)
+    {
+      delete this;
+    }
+}
+
+Ptr<Packet> 
+Packet::Copy (void) const
+{
+  // we need to invoke the copy constructor directly
+  // rather than calling Create because the copy constructor
+  // is private.
+  return Ptr<Packet> (new Packet (*this), false);
+}
+
 Packet::Packet ()
   : m_buffer (),
-    m_metadata (m_globalUid, 0)
+    m_tags (),
+    m_metadata (m_globalUid, 0),
+    m_refCount (1)
 {
   m_globalUid++;
 }
 
+Packet::Packet (const Packet &o)
+  : m_buffer (o.m_buffer),
+    m_tags (o.m_tags),
+    m_metadata (o.m_metadata),
+    m_refCount (1)
+{}
+
+Packet &
+Packet::operator = (const Packet &o)
+{
+  if (this == &o)
+    {
+      return *this;
+    }
+  m_buffer = o.m_buffer;
+  m_tags = o.m_tags;
+  m_metadata = o.m_metadata;
+  return *this;
+}
+
 Packet::Packet (uint32_t size)
   : m_buffer (size),
-    m_metadata (m_globalUid, size)
+    m_tags (),
+    m_metadata (m_globalUid, size),
+    m_refCount (1)
 {
   m_globalUid++;
 }
 Packet::Packet (uint8_t const*buffer, uint32_t size)
   : m_buffer (),
-    m_metadata (m_globalUid, size)
+    m_tags (),
+    m_metadata (m_globalUid, size),
+    m_refCount (1)
 {
   m_globalUid++;
   m_buffer.AddAtStart (size);
@@ -52,17 +102,20 @@
 Packet::Packet (Buffer buffer, Tags tags, PacketMetadata metadata)
   : m_buffer (buffer),
     m_tags (tags),
-    m_metadata (metadata)
+    m_metadata (metadata),
+    m_refCount (1)
 {}
 
-Packet 
+Ptr<Packet>
 Packet::CreateFragment (uint32_t start, uint32_t length) const
 {
   Buffer buffer = m_buffer.CreateFragment (start, length);
   NS_ASSERT (m_buffer.GetSize () >= start + length);
   uint32_t end = m_buffer.GetSize () - (start + length);
   PacketMetadata metadata = m_metadata.CreateFragment (start, end);
-  return Packet (buffer, m_tags, metadata);
+  // again, call the constructor directly rather than
+  // through Create because it is private.
+  return Ptr<Packet> (new Packet (buffer, m_tags, metadata), false);
 }
 
 uint32_t 
@@ -72,9 +125,9 @@
 }
 
 void 
-Packet::AddAtEnd (Packet packet)
+Packet::AddAtEnd (Ptr<const Packet> packet)
 {
-  Buffer src = packet.m_buffer.CreateFullCopy ();
+  Buffer src = packet->m_buffer.CreateFullCopy ();
   Buffer dst = m_buffer.CreateFullCopy ();
 
   dst.AddAtEnd (src.GetSize ());
@@ -86,7 +139,7 @@
    * XXX: we might need to merge the tag list of the
    * other packet into the current packet.
    */
-  m_metadata.AddAtEnd (packet.m_metadata);
+  m_metadata.AddAtEnd (packet->m_metadata);
 }
 void
 Packet::AddPaddingAtEnd (uint32_t size)
@@ -233,20 +286,20 @@
 {
   bool ok = true;
 
-  Packet pkt1 (reinterpret_cast<const uint8_t*> ("hello"), 5);
-  Packet pkt2 (reinterpret_cast<const uint8_t*> (" world"), 6);
-  Packet packet;
-  packet.AddAtEnd (pkt1);
-  packet.AddAtEnd (pkt2);
+  Ptr<Packet> pkt1 = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello"), 5);
+  Ptr<Packet> pkt2 = Create<Packet> (reinterpret_cast<const uint8_t*> (" world"), 6);
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->AddAtEnd (pkt1);
+  packet->AddAtEnd (pkt2);
   
-  if (packet.GetSize () != 11)
+  if (packet->GetSize () != 11)
     {
-      Failure () << "expected size 11, got " << packet.GetSize () << std::endl;
+      Failure () << "expected size 11, got " << packet->GetSize () << std::endl;
       ok = false;
     }
 
-  std::string msg = std::string (reinterpret_cast<const char *>(packet.PeekData ()),
-                                 packet.GetSize ());
+  std::string msg = std::string (reinterpret_cast<const char *>(packet->PeekData ()),
+                                 packet->GetSize ());
   if (msg != "hello world")
     {
       Failure () << "expected 'hello world', got '" << msg << "'" << std::endl;
--- a/src/common/packet.h	Mon Oct 01 14:07:53 2007 +0200
+++ b/src/common/packet.h	Mon Oct 01 14:14:31 2007 +0200
@@ -30,6 +30,7 @@
 #include "tag.h"
 #include "ns3/callback.h"
 #include "ns3/assert.h"
+#include "ns3/ptr.h"
 
 namespace ns3 {
 
@@ -74,6 +75,11 @@
  */
 class Packet {
 public:
+  void Ref (void) const;
+  void Unref (void) const;
+
+  Ptr<Packet> Copy (void) const;
+
   /**
    * Create an empty packet with a new uid (as returned
    * by getUid).
@@ -107,7 +113,7 @@
    * \param length length of fragment to create
    * \returns a fragment of the original packet
    */
-  Packet CreateFragment (uint32_t start, uint32_t length) const;
+  Ptr<Packet> CreateFragment (uint32_t start, uint32_t length) const;
   /**
    * \returns the size in bytes of the packet (including the zero-filled
    *          initial payload)
@@ -210,7 +216,7 @@
    *
    * \param packet packet to concatenate
    */
-  void AddAtEnd (Packet packet);
+  void AddAtEnd (Ptr<const Packet> packet);
   /**
    * \param size number of padding bytes to add.
    */
@@ -322,9 +328,12 @@
   void Deserialize (Buffer buffer);
 private:
   Packet (Buffer buffer, Tags tags, PacketMetadata metadata);
+  Packet (const Packet &o);
+  Packet &operator = (const Packet &o);
   Buffer m_buffer;
   Tags m_tags;
   PacketMetadata m_metadata;
+  mutable uint32_t m_refCount;
   static uint32_t m_globalUid;
 };