replace PacketPrinter with an iterator

This commit is contained in:
Mathieu Lacage
2008-03-17 11:45:36 -07:00
parent 218c66592a
commit c7be59d0c1
7 changed files with 146 additions and 268 deletions

View File

@@ -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'

View File

@@ -202,135 +202,40 @@ public:
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)
bool
PacketMetadataTest::CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...)
{
static bool registered = false;
if (!registered)
std::list<int> expected;
va_list ap;
va_start (ap, n);
for (uint32_t j = 0; j < n; j++)
{
m_printer.SetHeaderPrinter (MakeCallback (&PacketMetadataTest::PrintHeader<N>, this),
MakeCallback (&PacketMetadataTest::PrintFragment, this));
registered = true;
int v = va_arg (ap, int);
expected.push_back (v);
}
}
va_end (ap);
template <int N>
void
PacketMetadataTest::RegisterTrailer (void)
{
static bool registered = false;
if (!registered)
PacketMetadata::ItemIterator k = p->BeginItem ();
std::list<int> got;
while (k.HasNext ())
{
m_printer.SetTrailerPrinter (MakeCallback (&PacketMetadataTest::PrintTrailer<N>, this),
MakeCallback (&PacketMetadataTest::PrintFragment, this));
registered = true;
struct PacketMetadata::Item item = k.Next ();
got.push_back (item.currentSize);
}
}
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 ())
{
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<int> 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<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 @@ PacketMetadataTest::Check (const char *file, int line, std::list<int> expected)
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 @@ PacketMetadataTest::Check (const char *file, int line, std::list<int> expected)
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, ...) \

View File

@@ -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

View File

@@ -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 @@ 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,

View File

@@ -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

View File

@@ -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

View File

@@ -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',