From c7be59d0c132c46eeb1eedc645cf2164d43ca298 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 17 Mar 2008 11:45:36 -0700 Subject: [PATCH] replace PacketPrinter with an iterator --- samples/wscript | 3 - src/common/packet-metadata-test.cc | 169 ++++------------------------- src/common/packet-metadata.cc | 155 ++++++++++++-------------- src/common/packet-metadata.h | 59 ++++++++-- src/common/packet.cc | 8 +- src/common/packet.h | 18 +-- src/common/wscript | 2 - 7 files changed, 146 insertions(+), 268 deletions(-) diff --git a/samples/wscript b/samples/wscript index b6500b517..e7868460b 100644 --- a/samples/wscript +++ b/samples/wscript @@ -13,9 +13,6 @@ def build(bld): 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' diff --git a/src/common/packet-metadata-test.cc b/src/common/packet-metadata-test.cc index fb32b1934..45d7ab5a1 100644 --- a/src/common/packet-metadata-test.cc +++ b/src/common/packet-metadata-test.cc @@ -202,135 +202,40 @@ public: bool CheckHistory (Ptr p, const char *file, int line, uint32_t n, ...); virtual bool RunTests (void); private: - template - void PrintHeader (std::ostream &os, uint32_t packetUid, uint32_t size, const HistoryHeader *header); - template - void PrintTrailer (std::ostream &os, uint32_t packetUid, uint32_t size, const HistoryTrailer *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 - void RegisterHeader (void); - template - void RegisterTrailer (void); - void CleanupPrints (void); Ptr DoAddHeader (Ptr p); - bool Check (const char *file, int line, std::list expected); - - - bool m_headerError; - bool m_trailerError; - std::list m_prints; - PacketPrinter m_printer; }; PacketMetadataTest::PacketMetadataTest () : Test ("PacketMetadata") -{ - m_printer.SetPayloadPrinter (MakeCallback (&PacketMetadataTest::PrintPayload, this)); - m_printer.SetSeparator (""); -} +{} PacketMetadataTest::~PacketMetadataTest () {} -template -void -PacketMetadataTest::RegisterHeader (void) +bool +PacketMetadataTest::CheckHistory (Ptr p, const char *file, int line, uint32_t n, ...) { - static bool registered = false; - if (!registered) + std::list expected; + va_list ap; + va_start (ap, n); + for (uint32_t j = 0; j < n; j++) { - m_printer.SetHeaderPrinter (MakeCallback (&PacketMetadataTest::PrintHeader, this), - MakeCallback (&PacketMetadataTest::PrintFragment, this)); - registered = true; + int v = va_arg (ap, int); + expected.push_back (v); } -} + va_end (ap); -template -void -PacketMetadataTest::RegisterTrailer (void) -{ - static bool registered = false; - if (!registered) + PacketMetadata::ItemIterator k = p->BeginItem (); + std::list got; + while (k.HasNext ()) { - m_printer.SetTrailerPrinter (MakeCallback (&PacketMetadataTest::PrintTrailer, this), - MakeCallback (&PacketMetadataTest::PrintFragment, this)); - registered = true; + struct PacketMetadata::Item item = k.Next (); + got.push_back (item.currentSize); } -} - -template -void -PacketMetadataTest::PrintHeader (std::ostream &os, uint32_t packetUid, uint32_t size, - const HistoryHeader *header) -{ - if (!header->IsOk ()) - { - m_headerError = true; - } - m_prints.push_back (N); -} - -template -void -PacketMetadataTest::PrintTrailer (std::ostream &os, uint32_t packetUid, uint32_t size, - const HistoryTrailer *trailer) -{ - if (!trailer->IsOk ()) - { - m_trailerError = true; - } - 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)); -} - - -void -PacketMetadataTest::CleanupPrints (void) -{ - m_prints.clear (); -} - -bool -PacketMetadataTest::Check (const char *file, int line, std::list expected) -{ - if (m_headerError) - { - Failure () << "PacketMetadata header error. file=" << file - << ", line=" << line << std::endl; - return false; - } - 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::iterator i = m_prints.begin (), + for (std::list::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 @@ PacketMetadataTest::Check (const char *file, int line, std::list expected) error: Failure () << "PacketMetadata error. file="<< file << ", line=" << line << ", got:\""; - for (std::list::iterator i = m_prints.begin (); - i != m_prints.end (); i++) + for (std::list::iterator i = got.begin (); + i != got.end (); i++) { Failure () << *i << ", "; } @@ -357,60 +262,24 @@ PacketMetadataTest::Check (const char *file, int line, std::list expected) return false; } -bool -PacketMetadataTest::CheckHistory (Ptr p, const char *file, int line, uint32_t n, ...) -{ - m_headerError = false; - m_trailerError = false; - std::list 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 header; \ - RegisterHeader (); \ p->AddHeader (header); \ } #define ADD_TRAILER(p, n) \ { \ HistoryTrailer trailer; \ - RegisterTrailer (); \ p->AddTrailer (trailer); \ } #define REM_HEADER(p, n) \ { \ HistoryHeader header; \ - RegisterHeader (); \ p->RemoveHeader (header); \ } #define REM_TRAILER(p, n) \ { \ HistoryTrailer trailer; \ - RegisterTrailer (); \ p->RemoveTrailer (trailer); \ } #define CHECK_HISTORY(p, ...) \ diff --git a/src/common/packet-metadata.cc b/src/common/packet-metadata.cc index 0f6541f75..6b30b49d3 100644 --- a/src/common/packet-metadata.cc +++ b/src/common/packet-metadata.cc @@ -988,47 +988,6 @@ PacketMetadata::RemoveAtEnd (uint32_t end) } 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 @@ PacketMetadata::GetUid (void) const { 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 diff --git a/src/common/packet-metadata.h b/src/common/packet-metadata.h index 8b979ff35..2d71d712a 100644 --- a/src/common/packet-metadata.h +++ b/src/common/packet-metadata.h @@ -25,7 +25,7 @@ #include #include "ns3/callback.h" #include "ns3/assert.h" -#include "packet-printer.h" +#include "buffer.h" namespace ns3 { @@ -72,8 +72,54 @@ class Buffer; * 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 @@ public: 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 @@ private: }; friend DataFreeList::~DataFreeList (); + friend class ItemIterator; PacketMetadata (); void DoAddHeader (uint32_t uid, uint32_t size); @@ -219,10 +266,6 @@ private: 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, diff --git a/src/common/packet.cc b/src/common/packet.cc index 4636bdd9c..77539642b 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -187,13 +187,13 @@ Packet::PrintTags (std::ostream &os) const 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 diff --git a/src/common/packet.h b/src/common/packet.h index e13b946c1..0bc5d5483 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -34,8 +34,6 @@ namespace ns3 { -class PacketPrinter; - /** * \brief network packets * @@ -287,20 +285,8 @@ public: * 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 diff --git a/src/common/wscript b/src/common/wscript index b25aff575..16527fd99 100644 --- a/src/common/wscript +++ b/src/common/wscript @@ -5,7 +5,6 @@ def build(bld): common.source = [ 'buffer.cc', 'chunk-registry.cc', - 'packet-printer.cc', 'packet-metadata.cc', 'packet-metadata-test.cc', 'packet.cc', @@ -27,7 +26,6 @@ def build(bld): 'tag-registry.h', 'tag.h', 'packet.h', - 'packet-printer.h', 'packet-metadata.h', 'pcap-writer.h', 'data-rate.h',