replace PacketPrinter with an iterator
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Mon, 17 Mar 2008 11:45:36 -0700
changeset 2639 588221b7f892
parent 2638 00bd5081ee68
child 2640 f6262d180725
replace PacketPrinter with an iterator
samples/wscript
src/common/packet-metadata-test.cc
src/common/packet-metadata.cc
src/common/packet-metadata.h
src/common/packet.cc
src/common/packet.h
src/common/wscript
--- a/samples/wscript	Mon Mar 17 05:42:20 2008 +0100
+++ b/samples/wscript	Mon Mar 17 11:45:36 2008 -0700
@@ -13,9 +13,6 @@
     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/packet-metadata-test.cc	Mon Mar 17 05:42:20 2008 +0100
+++ b/src/common/packet-metadata-test.cc	Mon Mar 17 11:45:36 2008 -0700
@@ -202,135 +202,40 @@
   bool CheckHistory (Ptr<Packet> p, const 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 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);
   Ptr<Packet> DoAddHeader (Ptr<Packet> p);
-  bool Check (const char *file, int line, std::list<int> expected);
-
-
-  bool m_headerError;
-  bool m_trailerError;
-  std::list<int> m_prints;
-  PacketPrinter m_printer;
 };
 
 PacketMetadataTest::PacketMetadataTest ()
   : Test ("PacketMetadata")
-{
-  m_printer.SetPayloadPrinter (MakeCallback (&PacketMetadataTest::PrintPayload, this));
-  m_printer.SetSeparator ("");
-}
+{}
 
 PacketMetadataTest::~PacketMetadataTest ()
 {}
 
-template <int N>
-void 
-PacketMetadataTest::RegisterHeader (void)
-{
-  static bool registered = false;
-  if (!registered)
-    {
-      m_printer.SetHeaderPrinter (MakeCallback (&PacketMetadataTest::PrintHeader<N>, this),
-                                  MakeCallback (&PacketMetadataTest::PrintFragment, this));
-      registered = true;
-    }
-}
-
-template <int N>
-void 
-PacketMetadataTest::RegisterTrailer (void)
+bool 
+PacketMetadataTest::CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...)
 {
-  static bool registered = false;
-  if (!registered)
-    {
-      m_printer.SetTrailerPrinter (MakeCallback (&PacketMetadataTest::PrintTrailer<N>, this),
-                                   MakeCallback (&PacketMetadataTest::PrintFragment, this));
-      registered = true;
-    }
-}
-
-
-template <int N>
-void 
-PacketMetadataTest::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 
-PacketMetadataTest::PrintTrailer (std::ostream &os, uint32_t packetUid, uint32_t size, 
-                                 const HistoryTrailer<N> *trailer)
-{
-  if (!trailer->IsOk ())
+  std::list<int> expected;
+  va_list ap;
+  va_start (ap, n);
+  for (uint32_t j = 0; j < n; j++)
     {
-      m_trailerError = true;
+      int v = va_arg (ap, int);
+      expected.push_back (v);
     }
-  m_prints.push_back (N);
-}
-void 
-PacketMetadataTest::PrintFragment (std::ostream &os,uint32_t packetUid,
-                                  uint32_t size,std::string & name, 
-                                  struct PacketPrinter::FragmentInformation info)
-{
-  m_prints.push_back (size - (info.end + info.start));
-}
-void 
-PacketMetadataTest::PrintPayload (std::ostream &os,uint32_t packetUid,
-                                 uint32_t size,
-                                 struct PacketPrinter::FragmentInformation info)
-{
-  m_prints.push_back (size - (info.end + info.start));
-}
-
+  va_end (ap);
 
-void 
-PacketMetadataTest::CleanupPrints (void)
-{
-  m_prints.clear ();
-}
-
-bool
-PacketMetadataTest::Check (const char *file, int line, std::list<int> expected)
-{
-  if (m_headerError)
+  PacketMetadata::ItemIterator k = p->BeginItem ();
+  std::list<int> got;
+  while (k.HasNext ())
     {
-      Failure () << "PacketMetadata header error. file=" << file 
-                << ", line=" << line << std::endl;
-      return false;
+      struct PacketMetadata::Item item = k.Next ();
+      got.push_back (item.currentSize);
     }
-  if (m_trailerError)
-    {
-      Failure () << "PacketMetadata trailer error. file=" << file 
-                << ", line=" << line << std::endl;
-      return false;
-    }
-  if (expected.size () != m_prints.size ())
-    {
-      goto error;
-    }
-  for (std::list<int>::iterator i = m_prints.begin (),
+
+  for (std::list<int>::iterator i = got.begin (),
          j = expected.begin (); 
-       i != m_prints.end (); i++, j++)
+       i != got.end (); i++, j++)
     {
       NS_ASSERT (j != expected.end ());
       if (*j != *i)
@@ -342,8 +247,8 @@
  error:
   Failure () << "PacketMetadata error. file="<< file 
             << ", line=" << line << ", got:\"";
-  for (std::list<int>::iterator i = m_prints.begin (); 
-       i != m_prints.end (); i++)
+  for (std::list<int>::iterator i = got.begin (); 
+       i != got.end (); i++)
     {
       Failure () << *i << ", ";
     }
@@ -357,60 +262,24 @@
   return false;
 }
 
-bool 
-PacketMetadataTest::CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...)
-{
-  m_headerError = false;
-  m_trailerError = false;
-  std::list<int> expected;
-  va_list ap;
-  va_start (ap, n);
-  for (uint32_t j = 0; j < n; j++)
-    {
-      int v = va_arg (ap, int);
-      expected.push_back (v);
-    }
-  va_end (ap);
-
-  m_printer.PrintForward ();
-  p->Print (Failure (), m_printer);
-  bool ok = Check (file, line, expected);
-  CleanupPrints ();
-  if (!ok)
-    {
-      return false;
-    }
-
-  m_printer.PrintBackward ();
-  p->Print (Failure (), m_printer);
-  expected.reverse ();
-  ok = Check (file, line, expected);
-  CleanupPrints ();
-  return ok;
-}
-
 #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-metadata.cc	Mon Mar 17 05:42:20 2008 +0100
+++ b/src/common/packet-metadata.cc	Mon Mar 17 11:45:36 2008 -0700
@@ -988,47 +988,6 @@
     }
   NS_ASSERT (leftToRemove == 0);
 }
-
-uint32_t
-PacketMetadata::DoPrint (const struct PacketMetadata::SmallItem *item, 
-                         const struct PacketMetadata::ExtraItem *extraItem,
-                         Buffer data, uint32_t offset, const PacketPrinter &printer,
-                         std::ostream &os) const
-{
-  uint32_t uid = (item->typeUid & 0xfffffffe) >> 1;
-  if (uid == 0)
-    {
-      // payload.
-      printer.PrintPayload (os, extraItem->packetUid, item->size, 
-                            extraItem->fragmentStart, 
-                            item->size - extraItem->fragmentEnd);
-    }
-  else if (extraItem->fragmentStart != 0 ||
-           extraItem->fragmentEnd != item->size)
-    {
-      printer.PrintChunkFragment (uid, os, extraItem->packetUid, item->size, 
-                                  extraItem->fragmentStart, 
-                                  item->size - extraItem->fragmentEnd);
-    }
-  else if (ChunkRegistry::IsHeader (uid))
-    {
-      ns3::Buffer::Iterator j = data.Begin ();
-      j.Next (offset);
-      printer.PrintChunk (uid, j, os, extraItem->packetUid, item->size);
-    }
-  else if (ChunkRegistry::IsTrailer (uid))
-    {
-      ns3::Buffer::Iterator j = data.End ();
-      j.Prev (data.GetSize () - (offset + item->size));
-      printer.PrintChunk (uid, j, os, extraItem->packetUid, item->size);
-    }
-  else 
-    {
-      NS_ASSERT (false);
-    }
-  return extraItem->fragmentEnd - extraItem->fragmentStart;
-}
-
 uint32_t
 PacketMetadata::GetTotalSize (void) const
 {
@@ -1056,60 +1015,86 @@
 {
   return m_packetUid;
 }
-
-void
-PacketMetadata::Print (std::ostream &os, Buffer data, const PacketPrinter &printer) const
+PacketMetadata::ItemIterator 
+PacketMetadata::BeginItem (Buffer buffer) const
 {
-  if (!m_enable) 
+  return ItemIterator (this, buffer);
+}
+PacketMetadata::ItemIterator::ItemIterator (const PacketMetadata *metadata, Buffer buffer)
+  : m_metadata (metadata),
+    m_buffer (buffer),
+    m_current (metadata->m_head),
+    m_offset (0),
+    m_hasReadTail (false)
+{}
+bool 
+PacketMetadata::ItemIterator::HasNext (void) const
+{
+  if (m_current == 0xffff)
     {
-      return;
+      return false;
     }
-  NS_ASSERT (m_data != 0);
-  NS_ASSERT (GetTotalSize () == data.GetSize ());
-  struct PacketMetadata::SmallItem item;
-  struct PacketMetadata::ExtraItem extraItem;
-  if (printer.m_forward)
+  if (m_hasReadTail)
     {
-      uint32_t current = m_head;
-      uint32_t offset = 0;
-      while (current != 0xffff)
-        {
-          ReadItems (current, &item, &extraItem);
-          uint32_t realSize = DoPrint (&item, &extraItem, data, offset, printer, os);
-          offset += realSize;
-          if (current == m_tail)
-            {
-              break;
-            }
-          if (item.next != 0xffff)
-            {
-              os << printer.m_separator;
-            }
-          NS_ASSERT (current != item.next);
-          current = item.next;
-        }
+      return false;
+    }
+  return true;
+}
+PacketMetadata::Item
+PacketMetadata::ItemIterator::Next (void)
+{
+  struct PacketMetadata::Item item;
+  struct PacketMetadata::SmallItem smallItem;
+  struct PacketMetadata::ExtraItem extraItem;
+  m_metadata->ReadItems (m_current, &smallItem, &extraItem);
+  if (m_current == m_metadata->m_tail)
+    {
+      m_hasReadTail = true;
+    }
+  m_current = smallItem.next;
+  uint32_t uid = (smallItem.typeUid & 0xfffffffe) >> 1;
+  item.uid = uid;
+  item.currentTrimedFromStart = extraItem.fragmentStart;
+  item.currentTrimedFromEnd = extraItem.fragmentEnd - smallItem.size;
+  item.currentSize = extraItem.fragmentEnd - extraItem.fragmentStart;
+  if (extraItem.fragmentStart != 0 || extraItem.fragmentEnd != 0)
+    {
+      item.isFragment = true;
     }
   else
     {
-      uint32_t current = m_tail;
-      uint32_t offset = data.GetSize ();
-      while (current != 0xffff)
+      item.isFragment = false;
+    }
+  if (uid == 0)
+    {
+      item.type = PacketMetadata::Item::PAYLOAD;
+    }
+  else if (ChunkRegistry::IsHeader (uid))
+    {
+      item.type = PacketMetadata::Item::HEADER;
+      if (!item.isFragment)
         {
-          ReadItems (current, &item, &extraItem);
-          uint32_t realSize = DoPrint (&item, &extraItem, data, offset - item.size, printer, os);
-          offset -= realSize;
-          if (current == m_head)
-            {
-              break;
-            }
-          if (item.prev != 0xffff)
-            {
-              os << printer.m_separator;
-            }
-          NS_ASSERT (current != item.prev);
-          current = item.prev;
+          ns3::Buffer::Iterator j = m_buffer.Begin ();
+          j.Next (m_offset);
+          item.current = j;
         }
     }
+  else if (ChunkRegistry::IsTrailer (uid))
+    {
+      item.type = PacketMetadata::Item::TRAILER;
+      if (!item.isFragment)
+        {
+          ns3::Buffer::Iterator j = m_buffer.End ();
+          j.Prev (m_buffer.GetSize () - (m_offset + smallItem.size));
+          item.current = j;
+        }
+    }
+  else 
+    {
+      NS_ASSERT (false);
+    }
+  m_offset += extraItem.fragmentEnd - extraItem.fragmentStart;
+  return item;
 }
 
 uint32_t 
--- a/src/common/packet-metadata.h	Mon Mar 17 05:42:20 2008 +0100
+++ b/src/common/packet-metadata.h	Mon Mar 17 11:45:36 2008 -0700
@@ -25,7 +25,7 @@
 #include <vector>
 #include "ns3/callback.h"
 #include "ns3/assert.h"
-#include "packet-printer.h"
+#include "buffer.h"
 
 namespace ns3 {
 
@@ -72,8 +72,54 @@
  * The variable-size 32 bit integers are stored using the uleb128
  * encoding.
  */
-class PacketMetadata {
+class PacketMetadata 
+{
 public:
+  struct Item 
+  {
+    enum {
+      PAYLOAD,
+      HEADER,
+      TRAILER
+    } type;
+    /* true: this is a fragmented header, trailer, or, payload.
+     * false: this is a whole header, trailer, or, payload.
+     */
+    bool isFragment;
+    /* uid of header or trailer. valid only if isPayload is false.
+     */
+    uint32_t uid;
+    /* size of item. If fragment, size of fragment. Otherwise, 
+     * size of original item. 
+     */
+    uint32_t currentSize;
+    /* how many bytes were trimed from the start of a fragment.
+     * if isFragment is true, this field is zero.
+     */
+    uint32_t currentTrimedFromStart;
+    /* how many bytes were trimed from the end of a fragment.
+     * if isFragment is true, this field is zero.
+     */
+    uint32_t currentTrimedFromEnd;
+    /* an iterator which can be fed to Deserialize. Valid only
+     * if isFragment and isPayload are false.
+     */
+    Buffer::Iterator current;
+  };
+  class ItemIterator 
+  {
+  public:
+    ItemIterator (const PacketMetadata *metadata, Buffer buffer);
+    bool HasNext (void) const;
+    Item Next (void);
+  private:
+    const PacketMetadata *m_metadata;
+    Buffer m_buffer;
+    uint16_t m_current;
+    uint32_t m_offset;
+    bool m_hasReadTail;
+  };
+
   static void Enable (void);
   static void SetOptOne (bool optOne);
 
@@ -100,14 +146,14 @@
 
   uint32_t GetUid (void) const;
 
-  void Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const;
-
   uint32_t GetSerializedSize (void) const;
   void Serialize (Buffer::Iterator i, uint32_t size) const;
   uint32_t Deserialize (Buffer::Iterator i);
 
   static void PrintStats (void);
 
+  ItemIterator BeginItem (Buffer buffer) const;
+
 private:
   struct Data {
     /* number of references to this struct Data instance. */
@@ -192,6 +238,7 @@
   };
 
   friend DataFreeList::~DataFreeList ();
+  friend class ItemIterator;
 
   PacketMetadata ();
   void DoAddHeader (uint32_t uid, uint32_t size);
@@ -219,10 +266,6 @@
   void AppendValueExtra (uint32_t value, uint8_t *buffer);
   inline void Reserve (uint32_t n);
   void ReserveCopy (uint32_t n);
-  uint32_t DoPrint (const struct PacketMetadata::SmallItem *item,
-                    const struct PacketMetadata::ExtraItem *extraItem,
-                    Buffer data, uint32_t offset, const PacketPrinter &printer,
-                    std::ostream &os) const;
   uint32_t GetTotalSize (void) const;
   uint32_t ReadItems (uint16_t current, 
                       struct PacketMetadata::SmallItem *item,
--- a/src/common/packet.cc	Mon Mar 17 05:42:20 2008 +0100
+++ b/src/common/packet.cc	Mon Mar 17 11:45:36 2008 -0700
@@ -187,13 +187,13 @@
 void 
 Packet::Print (std::ostream &os) const
 {
-  m_metadata.Print (os, m_buffer, PacketPrinter ());
+  //XXX
 }
 
-void 
-Packet::Print (std::ostream &os, const PacketPrinter &printer) const
+PacketMetadata::ItemIterator 
+Packet::BeginItem (void) const
 {
-  m_metadata.Print (os, m_buffer, printer);
+  return m_metadata.BeginItem (m_buffer);
 }
 
 void
--- a/src/common/packet.h	Mon Mar 17 05:42:20 2008 +0100
+++ b/src/common/packet.h	Mon Mar 17 11:45:36 2008 -0700
@@ -34,8 +34,6 @@
 
 namespace ns3 {
 
-class PacketPrinter;
-
 /**
  * \brief network packets
  *
@@ -287,20 +285,8 @@
    * Trailer::DoPrint methods.
    */
   void Print (std::ostream &os) const;
-  /**
-   * \param os output stream in which the data should be printed.
-   * \param printer the output formatter to use to print
-   *        the content of this packet.
-   *
-   * Iterate over the headers and trailers present in this packet,
-   * either in the "forward" (first header to last trailer) or in
-   * the "backward" (last trailer to first header) direction, as
-   * specified by the PacketPrinter::PrintForward or the
-   * PacketPrinter::PrintBackward methods. For each header, trailer,
-   * or fragment of a header or a trailer, invoke the user-specified
-   * print callback stored in the specified PacketPrinter.
-   */
-  void Print (std::ostream &os, const PacketPrinter &printer) const;
+
+  PacketMetadata::ItemIterator BeginItem (void) const;
 
   /**
    * By default, packets do not keep around enough metadata to
--- a/src/common/wscript	Mon Mar 17 05:42:20 2008 +0100
+++ b/src/common/wscript	Mon Mar 17 11:45:36 2008 -0700
@@ -5,7 +5,6 @@
     common.source = [
         'buffer.cc',
         'chunk-registry.cc',
-        'packet-printer.cc',
         'packet-metadata.cc',
         'packet-metadata-test.cc',
         'packet.cc',
@@ -27,7 +26,6 @@
         'tag-registry.h',
         'tag.h',
         'packet.h',
-        'packet-printer.h',
         'packet-metadata.h',
         'pcap-writer.h',
         'data-rate.h',