re-implement PacketHistory to use the PacketPrinter and work on ItemList::Print
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Thu, 31 May 2007 14:30:34 +0200
changeset 806 0190f1b49dc8
parent 805 3368d1e0446d
child 807 1c3cc23a0cb8
re-implement PacketHistory to use the PacketPrinter and work on ItemList::Print
SConstruct
src/common/packet-history.cc
src/common/packet-history.h
src/common/packet.cc
src/common/packet.h
--- a/SConstruct	Thu May 31 14:30:07 2007 +0200
+++ b/SConstruct	Thu May 31 14:30:34 2007 +0200
@@ -188,6 +188,7 @@
     'chunk.cc',
     'header.cc',
     'trailer.cc',
+    'packet-printer.cc',
     'packet-history.cc',
     'packet.cc',
     'tags.cc',
@@ -210,6 +211,7 @@
     'trailer.h',
     'tags.h',
     'packet.h',
+    'packet-printer.h',
     'packet-history.h',
     'uv-trace-source.h',
     'sv-trace-source.h',
--- a/src/common/packet-history.cc	Thu May 31 14:30:07 2007 +0200
+++ b/src/common/packet-history.cc	Thu May 31 14:30:34 2007 +0200
@@ -31,7 +31,7 @@
 class ItemList
 {
 public:
-  void InitPayload (uint32_t uid, uint32_t size);
+  void InitPayload (uint32_t packetUid, uint32_t size);
   void AddHeader (uint32_t type, uint32_t size);
   void AddTrailer (uint32_t type, uint32_t size);
 
@@ -43,12 +43,13 @@
 
   void AddAtEnd (ItemList const *other);
 
-  void Print (std::ostream &os, ns3::Buffer buffer) const;
+  void Print (std::ostream &os, ns3::Buffer buffer, const ns3::PacketPrinter &printer) const;
 
 private:
   enum Type {
     PAYLOAD,
-    CHUNK,
+    HEADER,
+    TRAILER,
   };
   struct Item
   {
@@ -57,13 +58,13 @@
     uint32_t m_chunkType;
     uint32_t m_fragmentStart;
     uint32_t m_fragmentEnd;
-    uint32_t m_uid;
+    uint32_t m_packetUid;
   };
   std::list<Item> m_itemList;
 };
 
 void 
-ItemList::InitPayload (uint32_t uid, uint32_t size)
+ItemList::InitPayload (uint32_t packetUid, uint32_t size)
 {
   NS_ASSERT (m_itemList.empty ());
   struct Item item;
@@ -72,7 +73,7 @@
   item.m_size = size;
   item.m_fragmentStart = 0;
   item.m_fragmentEnd = item.m_size;
-  item.m_uid = uid;
+  item.m_packetUid = packetUid;
   m_itemList.push_back (item);
 }
 
@@ -80,12 +81,12 @@
 ItemList::AddHeader (uint32_t type, uint32_t size)
 {
   struct Item item;
-  item.m_type = ItemList::CHUNK;
+  item.m_type = ItemList::HEADER;
   item.m_chunkType = type;
   item.m_size = size;
   item.m_fragmentStart = 0;
   item.m_fragmentEnd = size;
-  item.m_uid = m_itemList.front ().m_uid;
+  item.m_packetUid = m_itemList.front ().m_packetUid;
   m_itemList.push_front (item);
 }
 
@@ -93,12 +94,12 @@
 ItemList::AddTrailer (uint32_t type, uint32_t size)
 {
   struct Item item;
-  item.m_type = ItemList::CHUNK;
+  item.m_type = ItemList::TRAILER;
   item.m_chunkType = type;
   item.m_size = size;
   item.m_fragmentStart = 0;
   item.m_fragmentEnd = size;
-  item.m_uid = m_itemList.back ().m_uid;
+  item.m_packetUid = m_itemList.back ().m_packetUid;
   m_itemList.push_back (item);
 }
 
@@ -106,7 +107,7 @@
 ItemList::RemHeader (uint32_t type, uint32_t size)
 {
   struct Item item = m_itemList.front ();
-  if (item.m_type != CHUNK ||
+  if (item.m_type != ItemList::HEADER ||
       item.m_size != size ||
       item.m_chunkType != type)
     {
@@ -123,7 +124,7 @@
 ItemList::RemTrailer (uint32_t type, uint32_t size)
 {
   struct Item item = m_itemList.back ();
-  if (item.m_type != CHUNK ||
+  if (item.m_type != ItemList::TRAILER ||
       item.m_size != size ||
       item.m_chunkType != type)
     {
@@ -193,7 +194,7 @@
     {
       const ItemList::Item &item = *i;
       ItemList::Item &last = m_itemList.back ();
-      if (item.m_uid == last.m_uid &&
+      if (item.m_packetUid == last.m_packetUid &&
           item.m_type == last.m_type &&
           item.m_chunkType == last.m_chunkType &&
           item.m_size == last.m_size &&
@@ -210,15 +211,43 @@
 }
 
 void 
-ItemList::Print (std::ostream &os, ns3::Buffer buffer) const
-{}
+ItemList::Print (std::ostream &os, ns3::Buffer buffer, const ns3::PacketPrinter &printer) const
+{
+  NS_ASSERT (!m_itemList.empty ());
+  for (std::list<ItemList::Item>::const_iterator i = m_itemList.begin (); 
+       i != m_itemList.end (); i++)
+    {
+      ItemList::Item item = *i;
+      if (item.m_type == ItemList::PAYLOAD)
+        {
+          printer.PrintPayload (os, item.m_packetUid, item.m_size, item.m_fragmentStart, item.m_fragmentEnd);
+        }
+      else if (item.m_fragmentStart != 0 || 
+               item.m_fragmentEnd != item.m_size)
+        {
+          printer.PrintChunkFragment (item.m_chunkType, os, item.m_packetUid, item.m_size, 
+                                      item.m_fragmentStart, item.m_fragmentEnd);
+        }
+      else if (item.m_type == ItemList::HEADER)
+        {
+          ns3::Buffer::Iterator j = buffer.Begin ();
+          j.Next (0); //XXX
+          printer.PrintChunk (item.m_chunkType, j, os, item.m_packetUid, item.m_size);
+        }
+      else if (item.m_type == ItemList::TRAILER)
+        {
+          ns3::Buffer::Iterator j = buffer.End ();
+          j.Prev (0); //XXX
+          printer.PrintChunk (item.m_chunkType, j, os, item.m_packetUid, item.m_size);
+        }
+    }
+}
 
 } // anonymous namespace
 
 namespace ns3 {
 
 bool PacketHistory::m_enable = false;
-PacketHistory::ChunkFactories PacketHistory::m_factories;
 uint32_t PacketHistory::m_maxSize = 0;
 PacketHistory::DataFreeList PacketHistory::m_freeList;
 
@@ -662,7 +691,7 @@
 }
 
 void 
-PacketHistory::PrintSimple (std::ostream &os, Buffer buffer) const
+PacketHistory::PrintSimple (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const
 {
   Buffer original = buffer;
   HeadersToPrint headersToPrint;
@@ -794,34 +823,30 @@
     {
       uint32_t uid = j->first;
       uint32_t offset = j->second;
-      Buffer tmp = original;
-      tmp.RemoveAtStart (offset);
-      Chunk *chunk = CreateStatic (uid);
-      chunk->Deserialize (tmp.Begin ());
-      chunk->Print (os);
+      Buffer::Iterator tmp = original.Begin ();
+      tmp.Next (offset);
+      printer.PrintChunk (uid, tmp, os, 0, 0);
     }
   for (TrailersToPrint::reverse_iterator j = trailersToPrint.rbegin (); 
        j != trailersToPrint.rend (); j++)
     {
       uint32_t uid = j->first;
       uint32_t offset = j->second;
-      Buffer tmp = original;
-      tmp.RemoveAtEnd (offset);
-      Chunk *chunk = CreateStatic (uid);
-      chunk->Deserialize (tmp.End ());
-      chunk->Print (os);
+      Buffer::Iterator tmp = original.End ();
+      tmp.Prev (offset);
+      printer.PrintChunk (uid, tmp, os, 0, 0);
     }
 }
 
 void 
-PacketHistory::PrintComplex (std::ostream &os, Buffer buffer) const
+PacketHistory::PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const
 {
   // we need to build a linked list of the different fragments 
   // which are stored in this packet.
   uint8_t *dataBuffer = &m_data->m_data[0];
   ItemList itemList;
   BuildItemList (&itemList, dataBuffer, m_end);
-  itemList.Print (os, buffer);
+  itemList.Print (os, buffer, printer);
 }
 
 void 
@@ -878,6 +903,12 @@
 void 
 PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const
 {
+  Print (os, buffer, PacketPrinter::GetDefault ());
+}
+
+void
+PacketHistory::Print (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const
+{
   if (!m_enable) 
     {
       return;
@@ -885,41 +916,15 @@
 
   if (m_aggregated)
     {
-      PrintComplex (os, buffer);
+      PrintComplex (os, buffer, printer);
     }
   else
     {
-      PrintSimple (os, buffer);
+      PrintSimple (os, buffer, printer);
     }
 }
 
 
-Chunk *
-PacketHistory::CreateStatic (uint32_t uid)
-{
-  for (ChunkFactoriesI i = m_factories.begin (); i != m_factories.end (); i++) 
-    {
-      if (i->first == uid) 
-        {
-          return (*i->second) ();
-        }
-    }
-  NS_ASSERT_MSG (false, "cannot be reached");
-  /* quiet compiler */
-  return 0;
-}
-uint32_t 
-PacketHistory::RegisterChunkFactory (Chunk *(*createStatic) (void))
-{
-  static uint32_t uid = 0;
-  uid++;
-  for (ChunkFactoriesI i = m_factories.begin (); i != m_factories.end (); i++) 
-    {
-      NS_ASSERT (i->first != uid);
-    }
-  m_factories.push_back (std::make_pair (uid, createStatic));
-  return uid;
-}
 
 }; // namespace ns3
 
@@ -933,46 +938,34 @@
 
 namespace ns3 {
 
-static std::list<int> g_prints;
-static bool g_headerError;
-static bool g_trailerError;
-
-static void 
-RecordPrint (int n)
-{
-  g_prints.push_back (n);
-}
-
-static void
-RecordTrailerError (int n)
-{
-  g_trailerError = true;
-}
-
-static void
-RecordHeaderError (int n)
-{
-  g_headerError = true;
-}
-
-static void
-CleanupPrints (void)
-{
-  g_prints.erase (g_prints.begin (), g_prints.end ());
-}
-
 template <int N>
 class HistoryHeader : public Header
 {
+public:
+  HistoryHeader ();
+  bool IsOk (void) const;
 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;
 };
 
 template <int N>
+HistoryHeader<N>::HistoryHeader ()
+  : m_ok (false)
+{}
+
+template <int N>
+bool 
+HistoryHeader<N>::IsOk (void) const
+{
+  return m_ok;
+}
+
+template <int N>
 std::string 
 HistoryHeader<N>::DoGetName (void) const
 {
@@ -985,7 +978,7 @@
 void 
 HistoryHeader<N>::PrintTo (std::ostream &os) const
 {
-  RecordPrint (N);
+  NS_ASSERT (false);
 }
 template <int N>
 uint32_t 
@@ -1003,11 +996,12 @@
 uint32_t
 HistoryHeader<N>::DeserializeFrom (Buffer::Iterator start)
 {
+  m_ok = true;
   for (int i = 0; i < N; i++)
     {
       if (start.ReadU8 () != N)
         {
-          RecordHeaderError (N);
+          m_ok = false;
         }
     }
   return N;
@@ -1016,15 +1010,31 @@
 template <int N>
 class HistoryTrailer : public Trailer
 {
+public:
+  HistoryTrailer ();
+  bool IsOk (void) const;
 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;
 };
 
 template <int N>
+HistoryTrailer<N>::HistoryTrailer ()
+  : m_ok (false)
+{}
+
+template <int N>
+bool
+HistoryTrailer<N>::IsOk (void) const
+{
+  return m_ok;
+}
+
+template <int N>
 std::string 
 HistoryTrailer<N>::DoGetName (void) const
 {
@@ -1036,7 +1046,7 @@
 void 
 HistoryTrailer<N>::PrintTo (std::ostream &os) const
 {
-  RecordPrint (N);
+  NS_ASSERT (false);
 }
 template <int N>
 uint32_t 
@@ -1054,12 +1064,13 @@
 uint32_t
 HistoryTrailer<N>::DeserializeFrom (Buffer::Iterator start)
 {
+  m_ok = true;
   start.Prev (N);
   for (int i = 0; i < N; i++)
     {
       if (start.ReadU8 () != N)
         {
-          RecordTrailerError (N);
+          m_ok = false;
         }
     }
   return N;
@@ -1073,41 +1084,148 @@
   virtual ~PacketHistoryTest ();
   bool CheckHistory (Packet p, char *file, int line, uint32_t n, ...);
   virtual bool RunTests (void);
+private:
+  template <int N>
+  void PrintHeader (std::ostream &os, uint32_t packetUid, uint32_t size, const HistoryHeader<N> *header);
+  template <int N>
+  void PrintTrailer (std::ostream &os, uint32_t packetUid, uint32_t size, const HistoryTrailer<N> *trailer);
+  void PrintFragment (std::ostream &os,uint32_t packetUid,
+                      uint32_t size,std::string & name, 
+                      struct PacketPrinter::FragmentInformation info);
+  void PrintDefault (std::ostream& os,uint32_t packetUid,
+                     uint32_t size,std::string& name,
+                     struct PacketPrinter::FragmentInformation info);
+  void PrintPayload (std::ostream &os,uint32_t packetUid,
+                     uint32_t size,
+                     struct PacketPrinter::FragmentInformation info);
+  template <int N>
+  void RegisterHeader (void);
+  template <int N>
+  void RegisterTrailer (void);
+  void CleanupPrints (void);
+
+
+  bool m_headerError;
+  bool m_trailerError;
+  std::list<int> m_prints;
+  PacketPrinter m_printer;
 };
 
 PacketHistoryTest::PacketHistoryTest ()
   : Test ("PacketHistory")
-{}
+{
+  m_printer.AddPayloadPrinter (MakeCallback (&PacketHistoryTest::PrintPayload, this));
+  m_printer.AddDefaultPrinter (MakeCallback (&PacketHistoryTest::PrintDefault, this));
+}
 
 PacketHistoryTest::~PacketHistoryTest ()
 {}
 
+template <int N>
+void 
+PacketHistoryTest::RegisterHeader (void)
+{
+  static bool registered = false;
+  if (!registered)
+    {
+      m_printer.AddPrinter (MakeCallback (&PacketHistoryTest::PrintHeader<N>, this),
+                            MakeCallback (&PacketHistoryTest::PrintFragment, this));
+      registered = true;
+    }
+}
+
+template <int N>
+void 
+PacketHistoryTest::RegisterTrailer (void)
+{
+  static bool registered = false;
+  if (!registered)
+    {
+      m_printer.AddPrinter (MakeCallback (&PacketHistoryTest::PrintTrailer<N>, this),
+                            MakeCallback (&PacketHistoryTest::PrintFragment, this));
+      registered = true;
+    }
+}
+
+
+template <int N>
+void 
+PacketHistoryTest::PrintHeader (std::ostream &os, uint32_t packetUid, uint32_t size, 
+                                const HistoryHeader<N> *header)
+{
+  if (!header->IsOk ())
+    {
+      m_headerError = true;
+    }
+  m_prints.push_back (N);
+}
+
+template <int N>
+void 
+PacketHistoryTest::PrintTrailer (std::ostream &os, uint32_t packetUid, uint32_t size, 
+                                 const HistoryTrailer<N> *trailer)
+{
+  if (!trailer->IsOk ())
+    {
+      m_trailerError = true;
+    }
+  m_prints.push_back (N);
+}
+void 
+PacketHistoryTest::PrintFragment (std::ostream &os,uint32_t packetUid,
+                                  uint32_t size,std::string & name, 
+                                  struct PacketPrinter::FragmentInformation info)
+{
+  NS_ASSERT (false);
+}
+void 
+PacketHistoryTest::PrintDefault (std::ostream& os,uint32_t packetUid,
+                     uint32_t size,std::string& name,
+                     struct PacketPrinter::FragmentInformation info)
+{
+  NS_ASSERT (false);
+}
+void 
+PacketHistoryTest::PrintPayload (std::ostream &os,uint32_t packetUid,
+                                 uint32_t size,
+                                 struct PacketPrinter::FragmentInformation info)
+{
+  NS_ASSERT (false);
+}
+
+
+void 
+PacketHistoryTest::CleanupPrints (void)
+{
+  m_prints.clear ();
+}
+
 bool 
 PacketHistoryTest::CheckHistory (Packet p, char *file, int line, uint32_t n, ...)
 {
-  g_headerError = false;
-  g_trailerError = false;
+  m_headerError = false;
+  m_trailerError = false;
   va_list ap;
-  p.Print (std::cerr);
+  p.Print (std::cerr, m_printer);
   va_start (ap, n);
-  if (g_headerError)
+  if (m_headerError)
     {
       std::cout << "PacketHistory header error. file=" << file 
                 << ", line=" << line << std::endl;
       return false;
     }
-  if (g_trailerError)
+  if (m_trailerError)
     {
       std::cout << "PacketHistory trailer error. file=" << file 
                 << ", line=" << line << std::endl;
       return false;
     }
-  if (n != g_prints.size ())
+  if (n != m_prints.size ())
     {
       goto error;
     }
-  for (std::list<int>::iterator i = g_prints.begin (); 
-       i != g_prints.end (); i++)
+  for (std::list<int>::iterator i = m_prints.begin (); 
+       i != m_prints.end (); i++)
     {
       int v = va_arg (ap, int);
       if (v != *i)
@@ -1121,8 +1239,8 @@
  error:
   std::cout << "PacketHistory error. file="<< file 
             << ", line=" << line << ", got:\"";
-  for (std::list<int>::iterator i = g_prints.begin (); 
-       i != g_prints.end (); i++)
+  for (std::list<int>::iterator i = m_prints.begin (); 
+       i != m_prints.end (); i++)
     {
       std::cout << *i << ", ";
     }
@@ -1141,21 +1259,25 @@
 #define ADD_HEADER(p, n)                        \
   {                                             \
     HistoryHeader<n> header;                    \
+    RegisterHeader<n> ();                       \
     p.AddHeader (header);                       \
   }
 #define ADD_TRAILER(p, n)                       \
   {                                             \
     HistoryTrailer<n> trailer;                  \
+    RegisterTrailer<n> ();                      \
     p.AddTrailer (trailer);                     \
   }
 #define REM_HEADER(p, n)                        \
   {                                             \
     HistoryHeader<n> header;                    \
+    RegisterHeader<n> ();                       \
     p.RemoveHeader (header);                    \
   }
 #define REM_TRAILER(p, n)                       \
   {                                             \
     HistoryTrailer<n> trailer;                  \
+    RegisterTrailer<n> ();                      \
     p.RemoveTrailer (trailer);                  \
   }
 #define CHECK_HISTORY(p, ...)                   \
--- a/src/common/packet-history.h	Thu May 31 14:30:07 2007 +0200
+++ b/src/common/packet-history.h	Thu May 31 14:30:34 2007 +0200
@@ -24,6 +24,7 @@
 #include <stdint.h>
 #include <vector>
 #include "ns3/callback.h"
+#include "packet-printer.h"
 
 namespace {
 class ItemList;
@@ -34,19 +35,6 @@
 class Chunk;
 class Buffer;
 
-class PacketPrinter 
-{
-public:
-  void PrintForward (void);
-  void PrintBackward (void);
-  template <typename T>
-  void Add (Callback<void,std::ostream &, T> cb);
-  
-private:
-  std::vector <std::pair<uint32_t,CallbackBase> > m_printers;
-  bool m_forward;
-};
-
 class PacketHistory {
 public:
   static void Enable (void);
@@ -73,7 +61,7 @@
   void RemoveAtEnd (uint32_t end);
 
   void PrintDefault (std::ostream &os, Buffer buffer) const;
-  void Print (std::ostream &os, Buffer buffer, PacketPrinter printer) const;
+  void Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const;
 
 private:
   enum CommandType {
@@ -97,14 +85,6 @@
   };
   typedef std::vector<std::pair<uint32_t,uint32_t> > HeadersToPrint;
   typedef std::vector<std::pair<uint32_t,uint32_t> > TrailersToPrint;
-  template <typename T>
-  class ChunkUid {
-  public:
-    static const uint32_t GetUid (void);
-    static Chunk *CreateStatic (void);
-  };
-  typedef std::vector<std::pair<uint32_t, Chunk *(*) (void)> > ChunkFactories;
-  typedef std::vector<std::pair<uint32_t, Chunk *(*) (void)> >::iterator ChunkFactoriesI;
   typedef std::vector<struct CommandData *> DataFreeList;
   
   PacketHistory ();
@@ -123,19 +103,16 @@
   void RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size);
   void AddTrailer (uint32_t uid, Chunk const & trailer, uint32_t size);
   void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size);
-  void PrintSimple (std::ostream &os, Buffer buffer) const;
-  void PrintComplex (std::ostream &os, Buffer buffer) const;
+  void PrintSimple (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const;
+  void PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const;
   void BuildItemList (ItemList *list, uint8_t *buffer, uint32_t size) const;
 
   static struct PacketHistory::CommandData *Create (uint32_t size);
   static void Recycle (struct CommandData *data);
   static struct PacketHistory::CommandData *Allocate (uint32_t n);
   static void Deallocate (struct CommandData *data);
-  static Chunk *CreateStatic (uint32_t uid);
-  static uint32_t RegisterChunkFactory (Chunk *(*createStatic) (void));  
   
   static DataFreeList m_freeList;
-  static ChunkFactories m_factories;
   static bool m_enable;
   static uint32_t m_maxSize;
   
@@ -150,46 +127,29 @@
 namespace ns3 {
 
 template <typename T>
-const uint32_t 
-PacketHistory::ChunkUid<T>::GetUid (void)
-{
-  static uint32_t uid = 
-    PacketHistory::RegisterChunkFactory (&PacketHistory::ChunkUid<T>::CreateStatic);
-  return uid;
-}
-template <typename T>
-Chunk *
-PacketHistory::ChunkUid<T>::CreateStatic (void)
-{
-  static T chunk = T ();
-  return &chunk;
-}
-
-
-template <typename T>
 void 
 PacketHistory::AddHeader (T const &header, uint32_t size)
 {
-  AddHeader (ChunkUid<T>::GetUid (), header, size);
+  AddHeader (PacketPrinter::GetUid<T> (), header, size);
 }
 
 template <typename T>
 void 
 PacketHistory::RemoveHeader (T const &header, uint32_t size)
 {
-  RemoveHeader (ChunkUid<T>::GetUid (), header, size);
+  RemoveHeader (PacketPrinter::GetUid<T> (), header, size);
 }
 template <typename T>
 void 
 PacketHistory::AddTrailer (T const &trailer, uint32_t size)
 {
-  AddTrailer (ChunkUid<T>::GetUid (), trailer, size);
+  AddTrailer (PacketPrinter::GetUid<T> (), trailer, size);
 }
 template <typename T>
 void 
 PacketHistory::RemoveTrailer (T const &trailer, uint32_t size)
 {
-  RemoveTrailer (ChunkUid<T>::GetUid (), trailer, size);
+  RemoveTrailer (PacketPrinter::GetUid<T> (), trailer, size);
 }
 
 }; // namespace ns3
--- a/src/common/packet.cc	Thu May 31 14:30:07 2007 +0200
+++ b/src/common/packet.cc	Thu May 31 14:30:34 2007 +0200
@@ -19,6 +19,7 @@
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 #include "packet.h"
+#include "packet-printer.h"
 #include "ns3/assert.h"
 
 namespace ns3 {
@@ -130,4 +131,10 @@
   m_history.PrintDefault (os, m_buffer);
 }
 
+void 
+Packet::Print (std::ostream &os, const PacketPrinter &printer) const
+{
+  m_history.Print (os, m_buffer, printer);
+}
+
 }; // namespace ns3
--- a/src/common/packet.h	Thu May 31 14:30:07 2007 +0200
+++ b/src/common/packet.h	Thu May 31 14:30:34 2007 +0200
@@ -32,6 +32,8 @@
 
 namespace ns3 {
 
+class PacketPrinter;
+
 /**
  * \brief network packets
  *
@@ -254,6 +256,7 @@
   uint32_t GetUid (void) const;
 
   void Print (std::ostream &os) const;
+  void Print (std::ostream &os, const PacketPrinter &printer) const;
 private:
   Packet (Buffer buffer, Tags tags, PacketHistory history, uint32_t uid);
   Buffer m_buffer;