From e1dfadc502f67808ee2a490c2747a989cb8f5131 Mon Sep 17 00:00:00 2001 From: Alexander Afanasyev Date: Tue, 17 Apr 2012 21:05:02 -0700 Subject: network: !!! Change PacketTag API !!! diff --git a/src/network/model/packet-tag-list.cc b/src/network/model/packet-tag-list.cc index c311a0f..a758b29 100644 --- a/src/network/model/packet-tag-list.cc +++ b/src/network/model/packet-tag-list.cc @@ -28,150 +28,146 @@ NS_LOG_COMPONENT_DEFINE ("PacketTagList"); namespace ns3 { -#ifdef USE_FREE_LIST - -struct PacketTagList::TagData *PacketTagList::g_free = 0; -uint32_t PacketTagList::g_nfree = 0; - -struct PacketTagList::TagData * -PacketTagList::AllocData (void) const -{ - NS_LOG_FUNCTION (g_nfree); - struct PacketTagList::TagData *retval; - if (g_free != 0) - { - retval = g_free; - g_free = g_free->m_next; - g_nfree--; - } - else - { - retval = new struct PacketTagList::TagData (); - } - return retval; -} - void -PacketTagList::FreeData (struct TagData *data) const -{ - NS_LOG_FUNCTION (g_nfree << data); - if (g_nfree > 1000) - { - delete data; - return; - } - g_nfree++; - data->next = g_free; - data->tid = TypeId (); - g_free = data; -} -#else -struct PacketTagList::TagData * -PacketTagList::AllocData (void) const +PacketTagList::Add (Ptr tag) { - NS_LOG_FUNCTION_NOARGS (); - struct PacketTagList::TagData *retval; - retval = new struct PacketTagList::TagData (); - return retval; -} + NS_LOG_FUNCTION (this << tag->GetInstanceTypeId ()); -void -PacketTagList::FreeData (struct TagData *data) const -{ - NS_LOG_FUNCTION (data); - delete data; + NS_ASSERT_MSG (Peek (tag->GetInstanceTypeId ()) == 0, + "Only one tag type per packet is allowed"); + + push_back (tag); } -#endif -bool -PacketTagList::Remove (Tag &tag) +Ptr +PacketTagList::Remove (TypeId tagType) { - NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ()); - TypeId tid = tag.GetInstanceTypeId (); - bool found = false; - for (struct TagData *cur = m_next; cur != 0; cur = cur->next) - { - if (cur->tid == tid) - { - found = true; - tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE)); - } - } - if (!found) + NS_LOG_FUNCTION (this << tagType); + + for (iterator tag = begin (); tag != end (); tag++) { - return false; - } - struct TagData *start = 0; - struct TagData **prevNext = &start; - for (struct TagData *cur = m_next; cur != 0; cur = cur->next) - { - if (cur->tid == tid) + if ((*tag)->GetInstanceTypeId () == tagType) { - /** - * XXX - * Note: I believe that we could optimize this to - * avoid copying each TagData located after the target id - * and just link the already-copied list to the next tag. - */ - continue; + Ptr retval = *tag; + erase (tag); + return retval; } - struct TagData *copy = AllocData (); - copy->tid = cur->tid; - copy->count = 1; - copy->next = 0; - memcpy (copy->data, cur->data, PACKET_TAG_MAX_SIZE); - *prevNext = copy; - prevNext = ©->next; } - *prevNext = 0; - RemoveAll (); - m_next = start; - return true; -} -void -PacketTagList::Add (const Tag &tag) const -{ - NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ()); - // ensure this id was not yet added - for (struct TagData *cur = m_next; cur != 0; cur = cur->next) - { - NS_ASSERT (cur->tid != tag.GetInstanceTypeId ()); - } - struct TagData *head = AllocData (); - head->count = 1; - head->next = 0; - head->tid = tag.GetInstanceTypeId (); - head->next = m_next; - NS_ASSERT (tag.GetSerializedSize () <= PACKET_TAG_MAX_SIZE); - tag.Serialize (TagBuffer (head->data, head->data+tag.GetSerializedSize ())); - - const_cast (this)->m_next = head; + return 0; } -bool -PacketTagList::Peek (Tag &tag) const +Ptr +PacketTagList::Peek (TypeId tagType) const { - NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ()); - TypeId tid = tag.GetInstanceTypeId (); - for (struct TagData *cur = m_next; cur != 0; cur = cur->next) + NS_LOG_FUNCTION (this << tagType); + for (const_iterator tag = begin (); tag != end (); tag++) { - if (cur->tid == tid) - { - /* found tag */ - tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE)); - return true; - } + if ((*tag)->GetInstanceTypeId () == tagType) + return *tag; } - /* no tag found */ - return false; -} -const struct PacketTagList::TagData * -PacketTagList::Head (void) const -{ - return m_next; + return 0; } + +// bool +// PacketTagList::Remove (Tag &tag) +// { +// NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ()); + +// return false; + +// // TypeId tid = tag.GetInstanceTypeId (); +// // bool found = false; +// // for (struct TagData *cur = m_next; cur != 0; cur = cur->next) +// // { +// // if (cur->tid == tid) +// // { +// // found = true; +// // tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE)); +// // } +// // } +// // if (!found) +// // { +// // return false; +// // } +// // struct TagData *start = 0; +// // struct TagData **prevNext = &start; +// // for (struct TagData *cur = m_next; cur != 0; cur = cur->next) +// // { +// // if (cur->tid == tid) +// // { +// // /** +// // * XXX +// // * Note: I believe that we could optimize this to +// // * avoid copying each TagData located after the target id +// // * and just link the already-copied list to the next tag. +// // */ +// // continue; +// // } +// // struct TagData *copy = AllocData (); +// // copy->tid = cur->tid; +// // copy->count = 1; +// // copy->next = 0; +// // memcpy (copy->data, cur->data, PACKET_TAG_MAX_SIZE); +// // *prevNext = copy; +// // prevNext = ©->next; +// // } +// // *prevNext = 0; +// // RemoveAll (); +// // m_next = start; +// // return true; +// } + +// void +// PacketTagList::Add (const Tag &tag) const +// { +// NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ()); +// // ensure this id was not yet added + +// // for (struct TagData *cur = m_next; cur != 0; cur = cur->next) +// // { +// // NS_ASSERT (cur->tid != tag.GetInstanceTypeId ()); +// // } + +// // struct TagData *head = AllocData (); +// // head->count = 1; +// // head->next = 0; +// // head->tid = tag.GetInstanceTypeId (); +// // head->next = m_next; +// // NS_ASSERT (tag.GetSerializedSize () <= PACKET_TAG_MAX_SIZE); +// // tag.Serialize (TagBuffer (head->data, head->data+tag.GetSerializedSize ())); + +// // const_cast (this)->m_next = head; + +// // m_tags. +// } + +// bool +// PacketTagList::Peek (Tag &tag) const +// { +// NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ()); +// // TypeId tid = tag.GetInstanceTypeId (); +// // for (struct TagData *cur = m_next; cur != 0; cur = cur->next) +// // { +// // if (cur->tid == tid) +// // { +// // /* found tag */ +// // tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE)); +// // return true; +// // } +// // } + +// /* no tag found */ +// return false; +// } + +// // const struct PacketTagList::TagData * +// // PacketTagList::Head (void) const +// // { +// // return m_next; +// // } + } // namespace ns3 diff --git a/src/network/model/packet-tag-list.h b/src/network/model/packet-tag-list.h index 838e847..270ddff 100644 --- a/src/network/model/packet-tag-list.h +++ b/src/network/model/packet-tag-list.h @@ -21,7 +21,7 @@ #define PACKET_TAG_LIST_H #include -#include +#include #include "ns3/type-id.h" namespace ns3 { @@ -34,40 +34,30 @@ class Tag; * The maximum size (in bytes) of a Tag is stored * in this constant. */ -#define PACKET_TAG_MAX_SIZE 20 +// #define PACKET_TAG_MAX_SIZE 20 -class PacketTagList +class PacketTagList : public std::list > { public: - struct TagData { - uint8_t data[PACKET_TAG_MAX_SIZE]; - struct TagData *next; - TypeId tid; - uint32_t count; - }; + // struct TagData { + // std::vector data; + // TypeId tid; + // uint32_t count; + // }; - inline PacketTagList (); - inline PacketTagList (PacketTagList const &o); - inline PacketTagList &operator = (PacketTagList const &o); - inline ~PacketTagList (); + // inline PacketTagList (); + // inline PacketTagList (PacketTagList const &o); + // inline PacketTagList &operator = (PacketTagList const &o); + // inline ~PacketTagList (); - void Add (Tag const&tag) const; - bool Remove (Tag &tag); - bool Peek (Tag &tag) const; - inline void RemoveAll (void); + void + Add (Ptr tag); - const struct PacketTagList::TagData *Head (void) const; + Ptr + Remove (TypeId tagType); -private: - - bool Remove (TypeId tid); - struct PacketTagList::TagData *AllocData (void) const; - void FreeData (struct TagData *data) const; - - static struct PacketTagList::TagData *g_free; - static uint32_t g_nfree; - - struct TagData *m_next; + Ptr + Peek (TypeId tagType) const; }; } // namespace ns3 @@ -78,65 +68,38 @@ private: namespace ns3 { -PacketTagList::PacketTagList () - : m_next () -{ -} - -PacketTagList::PacketTagList (PacketTagList const &o) - : m_next (o.m_next) -{ - if (m_next != 0) - { - m_next->count++; - } -} - -PacketTagList & -PacketTagList::operator = (PacketTagList const &o) -{ - // self assignment - if (m_next == o.m_next) - { - return *this; - } - RemoveAll (); - m_next = o.m_next; - if (m_next != 0) - { - m_next->count++; - } - return *this; -} - -PacketTagList::~PacketTagList () -{ - RemoveAll (); -} - -void -PacketTagList::RemoveAll (void) -{ - struct TagData *prev = 0; - for (struct TagData *cur = m_next; cur != 0; cur = cur->next) - { - cur->count--; - if (cur->count > 0) - { - break; - } - if (prev != 0) - { - FreeData (prev); - } - prev = cur; - } - if (prev != 0) - { - FreeData (prev); - } - m_next = 0; -} +// PacketTagList::PacketTagList () +// { +// } + +// PacketTagList::PacketTagList (PacketTagList const &o) +// : m_tags (o.m_tags) +// { +// } + +// PacketTagList & +// PacketTagList::operator = (PacketTagList const &o) +// { +// // self assignment +// if (&o == this) +// { +// return *this; +// } +// // RemoveAll (); // ??? +// m_tags = o.m_tags; +// return *this; +// } + +// PacketTagList::~PacketTagList () +// { +// RemoveAll (); +// } + +// void +// PacketTagList::RemoveAll (void) +// { +// m_tags.clear (); +// } } // namespace ns3 diff --git a/src/network/model/packet.cc b/src/network/model/packet.cc index 72ccc94..62aba0f 100644 --- a/src/network/model/packet.cc +++ b/src/network/model/packet.cc @@ -81,39 +81,39 @@ ByteTagIterator::ByteTagIterator (ByteTagList::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)); -} +// 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)); +// } Ptr @@ -835,60 +835,90 @@ Packet::FindFirstMatchingByteTag (Tag &tag) const return false; } -void -Packet::AddPacketTag (const Tag &tag) const +// void +// Packet::AddPacketTag (const Tag &tag) const +// { +// NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ()); +// m_packetTagList.Add (tag); +// } +// bool +// Packet::RemovePacketTag (Tag &tag) +// { +// NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ()); +// bool found = m_packetTagList.Remove (tag); +// return found; +// } +// bool +// Packet::PeekPacketTag (Tag &tag) const +// { +// bool found = m_packetTagList.Peek (tag); +// return found; +// } + +void +Packet::AddPacketTag (Ptr tag) { - NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ()); m_packetTagList.Add (tag); } -bool -Packet::RemovePacketTag (Tag &tag) + +Ptr +Packet::RemovePacketTag (TypeId tagType) { - NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ()); - bool found = m_packetTagList.Remove (tag); - return found; + return m_packetTagList.Remove (tagType); } -bool -Packet::PeekPacketTag (Tag &tag) const + +Ptr +Packet::PeekPacketTag (TypeId tagType) const { - bool found = m_packetTagList.Peek (tag); - return found; + return m_packetTagList.Peek (tagType); } + void Packet::RemoveAllPacketTags (void) { NS_LOG_FUNCTION (this); - m_packetTagList.RemoveAll (); + m_packetTagList.clear (); } void Packet::PrintPacketTags (std::ostream &os) const { - PacketTagIterator i = GetPacketTagIterator (); - while (i.HasNext ()) + for (PacketTagList::const_iterator tag = m_packetTagList.begin (); + tag != m_packetTagList.end (); + tag++) { - PacketTagIterator::Item item = i.Next (); - NS_ASSERT (item.GetTypeId ().HasConstructor ()); - Callback constructor = item.GetTypeId ().GetConstructor (); - NS_ASSERT (!constructor.IsNull ()); - ObjectBase *instance = constructor (); - Tag *tag = dynamic_cast (instance); - NS_ASSERT (tag != 0); - item.GetTag (*tag); - tag->Print (os); - delete tag; - if (i.HasNext ()) + if (tag != m_packetTagList.begin ()) { os << " "; } - } -} -PacketTagIterator -Packet::GetPacketTagIterator (void) const -{ - return PacketTagIterator (m_packetTagList.Head ()); -} + (*tag)->Print (os); + } + // PacketTagIterator i = GetPacketTagIterator (); + // while (i.HasNext ()) + // { + // PacketTagIterator::Item item = i.Next (); + // NS_ASSERT (item.GetTypeId ().HasConstructor ()); + // Callback constructor = item.GetTypeId ().GetConstructor (); + // NS_ASSERT (!constructor.IsNull ()); + // ObjectBase *instance = constructor (); + // Tag *tag = dynamic_cast (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 ()); +// } std::ostream& operator<< (std::ostream& os, const Packet &packet) { diff --git a/src/network/model/packet.h b/src/network/model/packet.h index 539dac5..59c2743 100644 --- a/src/network/model/packet.h +++ b/src/network/model/packet.h @@ -106,53 +106,6 @@ private: /** * \ingroup packet - * \brief Iterator over the set of 'packet' tags in a packet - * - * This is a java-style iterator. - */ -class PacketTagIterator -{ -public: - /** - * Identifies a tag within a packet. - */ - class Item - { -public: - /** - * \returns the ns3::TypeId associated to this tag. - */ - TypeId GetTypeId (void) const; - /** - * \param tag the user tag to which the data should be copied. - * - * Read the requested tag and store it in the user-provided - * tag instance. This method will crash if the type of the - * tag provided by the user does not match the type of - * the underlying tag. - */ - void GetTag (Tag &tag) const; -private: - friend class PacketTagIterator; - Item (const struct PacketTagList::TagData *data); - const struct PacketTagList::TagData *m_data; - }; - /** - * \returns true if calling Next is safe, false otherwise. - */ - bool HasNext (void) const; - /** - * \returns the next item found and prepare for the next one. - */ - Item Next (void); -private: - friend class Packet; - PacketTagIterator (const struct PacketTagList::TagData *head); - const struct PacketTagList::TagData *m_current; -}; - -/** - * \ingroup packet * \brief network packets * * Each network packet contains a byte buffer, a set of byte tags, a set of @@ -498,31 +451,63 @@ public: /** * \param tag the tag to store in this packet * - * Add a tag to this packet. This method calls the - * Tag::GetSerializedSize and, then, Tag::Serialize. + * Add a tag to this packet. + */ + void + AddPacketTag (Ptr tag); + + /** + * \param tag the tag to remove from this packet + * \returns smart pointer to a constant Tag object if the requested tag is found, + * 0 otherwise. * - * Note that this method is const, that is, it does not - * modify the state of this packet, which is fairly - * un-intuitive. + * Remove a tag from this packet. */ - void AddPacketTag (const Tag &tag) const; + Ptr + RemovePacketTag (TypeId tagType); + /** * \param tag the tag to remove from this packet + * \returns smart pointer to a constant Tag object if the requested tag is found, + * 0 otherwise. + * + * Templated version to remove a tag from this packet. + * In addition to non-templated version, there is a DynamicCast to + * the requested tag type + */ + template + Ptr + RemovePacketTag () + { + return DynamicCast (RemovePacketTag (T::GetTypeId ())); + } + + /** + * \param tag the tag to search in this packet * \returns true if the requested tag is found, false * otherwise. * - * Remove a tag from this packet. This method calls - * Tag::Deserialize if the tag is found. + * Search a matching tag and return it if found */ - bool RemovePacketTag (Tag &tag); + Ptr + PeekPacketTag (TypeId tagType) const; + /** * \param tag the tag to search in this packet * \returns true if the requested tag is found, false * otherwise. * - * Search a matching tag and call Tag::Deserialize if it is found. + * Templated version of search for a matching tag and returning it if found + * In addition to non-templated version, there is a DynamicCast to + * the requested tag type */ - bool PeekPacketTag (Tag &tag) const; + template + Ptr + PeekPacketTag () const + { + return DynamicCast (PeekPacketTag (T::GetTypeId ())); + } + /** * Remove all packet tags. */ @@ -542,7 +527,7 @@ public: * \returns an object which can be used to iterate over the list of * packet tags. */ - PacketTagIterator GetPacketTagIterator (void) const; + // PacketTagIterator GetPacketTagIterator (void) const; /* Note: These functions support a temporary solution * to a specific problem in this generic class, i.e. diff --git a/src/network/model/tag.h b/src/network/model/tag.h index f25cecf..7a97306 100644 --- a/src/network/model/tag.h +++ b/src/network/model/tag.h @@ -20,7 +20,7 @@ #ifndef TAG_H #define TAG_H -#include "ns3/object-base.h" +#include "ns3/object.h" #include "tag-buffer.h" #include @@ -33,7 +33,7 @@ namespace ns3 { * * New kinds of tags can be created by subclassing this base class. */ -class Tag : public ObjectBase +class Tag : public Object { public: static TypeId GetTypeId (void); @@ -71,6 +71,13 @@ public: virtual void Print (std::ostream &os) const = 0; }; +inline std::ostream & +operator << (std::ostream &os, const Tag &tag) +{ + tag.Print (os); + return os; +} + } // namespace ns3 #endif /* TAG_H */ -- 1.7.9.5