replace PacketPrinter with an iterator
This commit is contained in:
@@ -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'
|
||||
|
||||
|
||||
@@ -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, ...) \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user