add packet tag iterator

This commit is contained in:
Mathieu Lacage
2009-03-20 14:22:23 +01:00
parent 2cb895a0a6
commit c439c4be63
4 changed files with 108 additions and 42 deletions

View File

@@ -89,7 +89,7 @@ PacketTagList::Remove (Tag &tag)
if (cur->tid == tid)
{
found = true;
tag.Deserialize (TagBuffer (cur->data, cur->data+PacketTagList::SIZE));
tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE));
}
}
if (!found)
@@ -114,7 +114,7 @@ PacketTagList::Remove (Tag &tag)
copy->tid = cur->tid;
copy->count = 1;
copy->next = 0;
memcpy (copy->data, cur->data, PacketTagList::SIZE);
memcpy (copy->data, cur->data, PACKET_TAG_MAX_SIZE);
*prevNext = copy;
prevNext = &copy->next;
}
@@ -124,27 +124,6 @@ PacketTagList::Remove (Tag &tag)
return true;
}
void
PacketTagList::Print (std::ostream &os, std::string separator) const
{
for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
{
NS_ASSERT (cur->tid.HasConstructor ());
Callback<ObjectBase *> constructor = cur->tid.GetConstructor ();
NS_ASSERT (!constructor.IsNull ());
ObjectBase *instance = constructor ();
Tag *tag = dynamic_cast<Tag *> (instance);
NS_ASSERT (tag != 0);
tag->Deserialize (TagBuffer (cur->data, cur->data+PacketTagList::SIZE));
tag->Print (os);
delete tag;
if (cur->next != 0)
{
os << separator;
}
}
}
void
PacketTagList::Add (const Tag &tag) const
{
@@ -158,7 +137,7 @@ PacketTagList::Add (const Tag &tag) const
head->next = 0;
head->tid = tag.GetInstanceTypeId ();
head->next = m_next;
NS_ASSERT (tag.GetSerializedSize () < PacketTagList::SIZE);
NS_ASSERT (tag.GetSerializedSize () < PACKET_TAG_MAX_SIZE);
tag.Serialize (TagBuffer (head->data, head->data+tag.GetSerializedSize ()));
const_cast<PacketTagList *> (this)->m_next = head;
@@ -173,7 +152,7 @@ PacketTagList::Peek (Tag &tag) const
if (cur->tid == tid)
{
/* found tag */
tag.Deserialize (TagBuffer (cur->data, cur->data+PacketTagList::SIZE));
tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE));
return true;
}
}
@@ -181,5 +160,11 @@ PacketTagList::Peek (Tag &tag) const
return false;
}
const struct PacketTagList::TagData *
PacketTagList::Head (void) const
{
return m_next;
}
} // namespace ns3

View File

@@ -17,8 +17,8 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef TAGS_H
#define TAGS_H
#ifndef PACKET_TAG_LIST_H
#define PACKET_TAG_LIST_H
#include <stdint.h>
#include <ostream>
@@ -34,10 +34,18 @@ class Tag;
* The maximum size (in bytes) of a Tag is stored
* in this constant.
*/
#define TAGS_MAX_SIZE 16
#define PACKET_TAG_MAX_SIZE 16
class PacketTagList {
class PacketTagList
{
public:
struct TagData {
uint8_t data[PACKET_TAG_MAX_SIZE];
struct TagData *next;
TypeId tid;
uint32_t count;
};
inline PacketTagList ();
inline PacketTagList (PacketTagList const &o);
inline PacketTagList &operator = (PacketTagList const &o);
@@ -48,19 +56,11 @@ public:
bool Peek (Tag &tag) const;
inline void RemoveAll (void);
const struct PacketTagList::TagData *Head (void) const;
void Print (std::ostream &os, std::string separator) const;
enum {
SIZE = TAGS_MAX_SIZE
};
private:
struct TagData {
uint8_t data[PacketTagList::SIZE];
struct TagData *next;
TypeId tid;
uint32_t count;
};
bool Remove (TypeId tid);
struct PacketTagList::TagData *AllocData (void) const;
@@ -74,7 +74,9 @@ private:
} // namespace ns3
/****************************************************
* Implementation of inline methods for performance
****************************************************/
namespace ns3 {
@@ -139,4 +141,4 @@ PacketTagList::RemoveAll (void)
} // namespace ns3
#endif /* TAGS_H */
#endif /* PACKET_TAG_LIST_H */

View File

@@ -76,6 +76,39 @@ TagIterator::TagIterator (TagList::Iterator i)
{}
PacketTagIterator::PacketTagIterator (const struct PacketTagList::TagData *head)
: m_current (head)
{}
bool
PacketTagIterator::HasNext (void) const
{
return m_current != 0;
}
PacketTagIterator::Item
PacketTagIterator::Next (void)
{
NS_ASSERT (HasNext ());
const struct PacketTagList::TagData *prev = m_current;
m_current = m_current->next;
return PacketTagIterator::Item (prev);
}
PacketTagIterator::Item::Item (const struct PacketTagList::TagData *data)
: m_data (data)
{}
TypeId
PacketTagIterator::Item::GetTypeId (void) const
{
return m_data->tid;
}
void
PacketTagIterator::Item::GetTag (Tag &tag) const
{
NS_ASSERT (tag.GetInstanceTypeId () == m_data->tid);
tag.Deserialize (TagBuffer ((uint8_t*)m_data->data, (uint8_t*)m_data->data+PACKET_TAG_MAX_SIZE));
}
void
Packet::Ref (void) const
{
@@ -609,7 +642,30 @@ Packet::RemoveAllPacketTags (void)
void
Packet::PrintPacketTags (std::ostream &os) const
{
m_packetTagList.Print (os, " ");
PacketTagIterator i = GetPacketTagIterator ();
while (i.HasNext ())
{
PacketTagIterator::Item item = i.Next ();
NS_ASSERT (item.GetTypeId ().HasConstructor ());
Callback<ObjectBase *> constructor = item.GetTypeId ().GetConstructor ();
NS_ASSERT (!constructor.IsNull ());
ObjectBase *instance = constructor ();
Tag *tag = dynamic_cast<Tag *> (instance);
NS_ASSERT (tag != 0);
item.GetTag (*tag);
tag->Print (os);
delete tag;
if (i.HasNext ())
{
os << " ";
}
}
}
PacketTagIterator
Packet::GetPacketTagIterator (void) const
{
return PacketTagIterator (m_packetTagList.Head ());
}

View File

@@ -103,6 +103,27 @@ private:
TagList::Iterator m_current;
};
class PacketTagIterator
{
public:
class Item
{
public:
TypeId GetTypeId (void) const;
void GetTag (Tag &tag) const;
private:
friend class PacketTagIterator;
Item (const struct PacketTagList::TagData *data);
const struct PacketTagList::TagData *m_data;
};
bool HasNext (void) const;
Item Next (void);
private:
friend class Packet;
PacketTagIterator (const struct PacketTagList::TagData *head);
const struct PacketTagList::TagData *m_current;
};
/**
* \ingroup packet
* \brief network packets
@@ -447,6 +468,8 @@ public:
void PrintPacketTags (std::ostream &os) const;
PacketTagIterator GetPacketTagIterator (void) const;
private:
Packet (const Buffer &buffer, const TagList &tagList,
const PacketTagList &packetTagList, const PacketMetadata &metadata);