diff --git a/src/common/packet.cc b/src/common/packet.cc index 0a141141d..853631bc4 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -103,7 +103,6 @@ Packet::Copy (void) const Packet::Packet () : m_buffer (), - m_tags (), m_tagList (), m_metadata (m_globalUid, 0), m_refCount (1) @@ -113,7 +112,6 @@ Packet::Packet () Packet::Packet (const Packet &o) : m_buffer (o.m_buffer), - m_tags (o.m_tags), m_tagList (o.m_tagList), m_metadata (o.m_metadata), m_refCount (1) @@ -127,7 +125,6 @@ Packet::operator = (const Packet &o) return *this; } m_buffer = o.m_buffer; - m_tags = o.m_tags; m_tagList = o.m_tagList; m_metadata = o.m_metadata; return *this; @@ -135,7 +132,6 @@ Packet::operator = (const Packet &o) Packet::Packet (uint32_t size) : m_buffer (size), - m_tags (), m_tagList (), m_metadata (m_globalUid, size), m_refCount (1) @@ -144,7 +140,6 @@ Packet::Packet (uint32_t size) } Packet::Packet (uint8_t const*buffer, uint32_t size) : m_buffer (), - m_tags (), m_tagList (), m_metadata (m_globalUid, size), m_refCount (1) @@ -155,9 +150,8 @@ Packet::Packet (uint8_t const*buffer, uint32_t size) i.Write (buffer, size); } -Packet::Packet (const Buffer &buffer, const Tags &tags, const MtagList &tagList, const PacketMetadata &metadata) +Packet::Packet (const Buffer &buffer, const MtagList &tagList, const PacketMetadata &metadata) : m_buffer (buffer), - m_tags (tags), m_tagList (tagList), m_metadata (metadata), m_refCount (1) @@ -172,7 +166,7 @@ Packet::CreateFragment (uint32_t start, uint32_t length) const PacketMetadata metadata = m_metadata.CreateFragment (start, end); // again, call the constructor directly rather than // through Create because it is private. - return Ptr (new Packet (buffer, m_tags, m_tagList, metadata), false); + return Ptr (new Packet (buffer, m_tagList, metadata), false); } uint32_t @@ -270,7 +264,6 @@ Packet::RemoveAtStart (uint32_t size) void Packet::RemoveAllTags (void) { - m_tags.RemoveAll (); m_tagList.RemoveAll (); } @@ -289,8 +282,8 @@ Packet::GetUid (void) const void Packet::PrintTags (std::ostream &os) const { - m_tags.Print (os, " "); - // XXX: tagList. + // XXX: + //m_tagList.Print (os, " "); } void @@ -434,20 +427,20 @@ Packet::Serialize (void) const m_metadata.Serialize (buffer.Begin (), reserve); // write tags - reserve = m_tags.GetSerializedSize (); - buffer.AddAtStart (reserve); - m_tags.Serialize (buffer.Begin (), reserve); + //XXX + //reserve = m_tags.GetSerializedSize (); + //buffer.AddAtStart (reserve); + //m_tags.Serialize (buffer.Begin (), reserve); // aggregate byte buffer, metadata, and tags Buffer tmp = m_buffer.CreateFullCopy (); - buffer.AddAtStart (tmp.GetSize ()); - buffer.Begin ().Write (tmp.Begin (), tmp.End ()); + tmp.AddAtEnd (buffer); // write byte buffer size. - buffer.AddAtStart (4); - buffer.Begin ().WriteU32 (m_buffer.GetSize ()); + tmp.AddAtStart (4); + tmp.Begin ().WriteU32 (m_buffer.GetSize ()); - return buffer; + return tmp; } void Packet::Deserialize (Buffer buffer) @@ -460,11 +453,13 @@ Packet::Deserialize (Buffer buffer) // read buffer. buf.RemoveAtEnd (buf.GetSize () - packetSize); m_buffer = buf; + buffer.RemoveAtStart (4 + packetSize); + // read tags - buffer.RemoveAtStart (4 + packetSize); - uint32_t tagsDeserialized = m_tags.Deserialize (buffer.Begin ()); - buffer.RemoveAtStart (tagsDeserialized); + //XXX + //uint32_t tagsDeserialized = m_tags.Deserialize (buffer.Begin ()); + //buffer.RemoveAtStart (tagsDeserialized); // read metadata uint32_t metadataDeserialized = diff --git a/src/common/packet.h b/src/common/packet.h index 4c7665f8c..e069bd6f7 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -24,9 +24,7 @@ #include "buffer.h" #include "header.h" #include "trailer.h" -#include "tags.h" #include "packet-metadata.h" -#include "tag.h" #include "mtag.h" #include "mtag-list.h" #include "ns3/callback.h" @@ -215,63 +213,6 @@ public: * \returns the number of bytes removed from the end of the packet. */ uint32_t RemoveTrailer (Trailer &trailer); - /** - * \param tag a pointer to the tag to attach to this packet. - * - * Attach a tag to this packet. The tag is fully copied - * in a packet-specific internal buffer. This operation - * is expected to be really fast. The copy constructor of the - * tag is invoked to copy it into the tag buffer. - * - * Note that adding a tag is a const operation which is pretty - * un-intuitive. The rationale is that the content and behavior of - * a packet is _not_ changed when a tag is added to a packet: any - * code which was not aware of the new tag is going to work just - * the same if the new tag is added. The real reason why adding a - * tag was made a const operation is to allow a trace sink which gets - * a packet to tag the packet, even if the packet is const (and most - * trace sources should use const packets because it would be - * totally evil to allow a trace sink to modify the content of a - * packet). - * - */ - template - void AddTag (T const &tag) const; - /** - * Remove a tag from this packet. The data stored internally - * for this tag is copied in the input tag if an instance - * of this tag type is present in the internal buffer. If this - * tag type is not present, the input tag is not modified. - * - * This operation can be potentially slow and might trigger - * unexpectedly large memory allocations. It is thus - * usually a better idea to create a copy of this packet, - * and invoke removeAllTags on the copy to remove all - * tags rather than remove the tags one by one from a packet. - * - * \param tag a pointer to the tag to remove from this packet - * \returns true if an instance of this tag type is stored - * in this packet, false otherwise. - */ - template - bool RemoveTag (T &tag); - /** - * Copy a tag stored internally to the input tag. If no instance - * of this tag is present internally, the input tag is not modified. - * The copy constructor of the tag is invoked to copy it into the - * input tag variable. - * - * \param tag a pointer to the tag to read from this packet - * \returns true if an instance of this tag type is stored - * in this packet, false otherwise. - */ - template - bool PeekTag (T &tag) const; - /** - * Remove all the tags stored in this packet. This operation is - * much much faster than invoking removeTag n times. - */ - void RemoveAllTags (void); /** * \param os output stream in which the data should be printed. * @@ -400,6 +341,17 @@ public: * * Tag each byte included in this packet with the * new tag. + * + * Note that adding a tag is a const operation which is pretty + * un-intuitive. The rationale is that the content and behavior of + * a packet is _not_ changed when a tag is added to a packet: any + * code which was not aware of the new tag is going to work just + * the same if the new tag is added. The real reason why adding a + * tag was made a const operation is to allow a trace sink which gets + * a packet to tag the packet, even if the packet is const (and most + * trace sources should use const packets because it would be + * totally evil to allow a trace sink to modify the content of a + * packet). */ void AddMtag (const Mtag &tag) const; /** @@ -415,12 +367,16 @@ public: */ bool FindFirstMatchingTag (Mtag &tag) const; + /** + * Remove all the tags stored in this packet. + */ + void RemoveAllTags (void); + private: - Packet (const Buffer &buffer, const Tags &tags, const MtagList &tagList, const PacketMetadata &metadata); + Packet (const Buffer &buffer, const MtagList &tagList, const PacketMetadata &metadata); Packet (const Packet &o); Packet &operator = (const Packet &o); Buffer m_buffer; - Tags m_tags; MtagList m_tagList; PacketMetadata m_metadata; mutable uint32_t m_refCount; @@ -467,42 +423,4 @@ std::ostream& operator<< (std::ostream& os, const Packet &packet); } // namespace ns3 - -/************************************************** - Start of implementation of templates defined - above - *************************************************/ - -namespace ns3 { - -template -void Packet::AddTag (T const& tag) const -{ - const Tag *parent; - // if the following assignment fails, it is because the - // input to this function is not a subclass of the Tag class. - parent = &tag; - m_tags.Add (tag); -} -template -bool Packet::RemoveTag (T & tag) -{ - Tag *parent; - // if the following assignment fails, it is because the - // input to this function is not a subclass of the Tag class. - parent = &tag; - return m_tags.Remove (tag); -} -template -bool Packet::PeekTag (T & tag) const -{ - Tag *parent; - // if the following assignment fails, it is because the - // input to this function is not a subclass of the Tag class. - parent = &tag; - return m_tags.Peek (tag); -} - -} // namespace ns3 - #endif /* PACKET_H */ diff --git a/src/common/tag-registry.cc b/src/common/tag-registry.cc deleted file mode 100644 index 01ae31fbc..000000000 --- a/src/common/tag-registry.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2006 INRIA - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Mathieu Lacage - */ -#include "tag-registry.h" -#include "ns3/fatal-error.h" - -namespace ns3 { - -TagRegistry::TagInfoVector * -TagRegistry::GetInfo (void) -{ - static TagRegistry::TagInfoVector vector; - return &vector; -} - -std::string -TagRegistry::GetUidString (uint32_t uid) -{ - TagInfo info = (*GetInfo ())[uid - 1]; - return info.uidString; -} -uint32_t -TagRegistry::GetUidFromUidString (std::string uidString) -{ - TagInfoVector *vec = GetInfo (); - uint32_t uid = 1; - for (TagInfoVector::iterator i = vec->begin (); i != vec->end (); i++) - { - if (i->uidString == uidString) - { - return uid; - } - uid++; - } - NS_FATAL_ERROR ("We are trying to deserialize an un-registered type. This can't work."); - return 0; -} - -void -TagRegistry::Destruct (uint32_t uid, uint8_t *data) -{ - TagInfo info = (*GetInfo ())[uid - 1]; - info.destruct (data); -} -void -TagRegistry::Print (uint32_t uid, uint8_t *data, std::ostream &os) -{ - TagInfo info = (*GetInfo ())[uid - 1]; - info.print (data, os); -} -uint32_t -TagRegistry::GetSerializedSize (uint32_t uid, uint8_t *data) -{ - TagInfo info = (*GetInfo ())[uid - 1]; - return info.getSerializedSize (data); -} -void -TagRegistry::Serialize (uint32_t uid, uint8_t *data, Buffer::Iterator start) -{ - TagInfo info = (*GetInfo ())[uid - 1]; - info.serialize (data, start); -} -uint32_t -TagRegistry::Deserialize (uint32_t uid, uint8_t *data, Buffer::Iterator start) -{ - TagInfo info = (*GetInfo ())[uid - 1]; - return info.deserialize (data, start); -} - -} // namespace ns3 diff --git a/src/common/tag-registry.h b/src/common/tag-registry.h deleted file mode 100644 index 52d16f281..000000000 --- a/src/common/tag-registry.h +++ /dev/null @@ -1,148 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2006 INRIA - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Mathieu Lacage - */ -#ifndef TAG_REGISTRY_H -#define TAG_REGISTRY_H - -#include -#include -#include "buffer.h" - -namespace ns3 { - -/** - * \brief a registry of all existing tag types. - * \internal - * - * This class is used to give polymorphic access to the methods - * exported by a tag. It also is used to associate a single - * reliable uid to each unique type. - */ -class TagRegistry -{ -public: - template - static uint32_t Register (std::string uidString); - static std::string GetUidString (uint32_t uid); - static uint32_t GetUidFromUidString (std::string uidString); - static void Destruct (uint32_t uid, uint8_t *data); - static void Print (uint32_t uid, uint8_t *data, std::ostream &os); - static uint32_t GetSerializedSize (uint32_t uid, uint8_t *data); - static void Serialize (uint32_t uid, uint8_t *data, Buffer::Iterator start); - static uint32_t Deserialize (uint32_t uid, uint8_t *data, Buffer::Iterator start); -private: - typedef void (*DestructCb) (uint8_t *); - typedef void (*PrintCb) (uint8_t *, std::ostream &); - typedef uint32_t (*GetSerializedSizeCb) (uint8_t *); - typedef void (*SerializeCb) (uint8_t *, Buffer::Iterator); - typedef uint32_t (*DeserializeCb) (uint8_t *, Buffer::Iterator); - struct TagInfo - { - std::string uidString; - DestructCb destruct; - PrintCb print; - GetSerializedSizeCb getSerializedSize; - SerializeCb serialize; - DeserializeCb deserialize; - }; - typedef std::vector TagInfoVector; - - template - static void DoDestruct (uint8_t *data); - template - static void DoPrint (uint8_t *data, std::ostream &os); - template - static uint32_t DoGetSerializedSize (uint8_t *data); - template - static void DoSerialize (uint8_t *data, Buffer::Iterator start); - template - static uint32_t DoDeserialize (uint8_t *data, Buffer::Iterator start); - - static TagInfoVector *GetInfo (void); -}; - -} // namespace ns3 - -namespace ns3 { - -template -void -TagRegistry::DoDestruct (uint8_t *data) -{ - T *tag = reinterpret_cast (data); - tag->~T (); -} -template -void -TagRegistry::DoPrint (uint8_t *data, std::ostream &os) -{ - T *tag = reinterpret_cast (data); - tag->Print (os); -} -template -uint32_t -TagRegistry::DoGetSerializedSize (uint8_t *data) -{ - T *tag = reinterpret_cast (data); - return tag->GetSerializedSize (); -} -template -void -TagRegistry::DoSerialize (uint8_t *data, Buffer::Iterator start) -{ - T *tag = reinterpret_cast (data); - tag->Serialize (start); -} -template -uint32_t -TagRegistry::DoDeserialize (uint8_t *data, Buffer::Iterator start) -{ - T *tag = reinterpret_cast (data); - return tag->Deserialize (start); -} - -template -uint32_t -TagRegistry::Register (std::string uidString) -{ - TagInfoVector *vec = GetInfo (); - uint32_t j = 0; - for (TagInfoVector::iterator i = vec->begin (); i != vec->end (); i++) - { - if (i->uidString == uidString) - { - return j; - } - j++; - } - TagInfo info; - info.uidString = uidString; - info.destruct = &TagRegistry::DoDestruct; - info.print = &TagRegistry::DoPrint; - info.getSerializedSize = &TagRegistry::DoGetSerializedSize; - info.serialize = &TagRegistry::DoSerialize; - info.deserialize = &TagRegistry::DoDeserialize; - vec->push_back (info); - uint32_t uid = vec->size (); - return uid; -} - -} // namespace ns3 - -#endif /* TAG_REGISTRY_H */ diff --git a/src/common/tag.h b/src/common/tag.h deleted file mode 100644 index b07f78206..000000000 --- a/src/common/tag.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2006 INRIA - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Mathieu Lacage - */ -#ifndef TAG_H -#define TAG_H - -#include -#include - -/** - * \relates ns3::Tag - * \brief this macro should be instantiated exactly once for each - * new type of Tag - * - * This macro will ensure that your new Tag type is registered - * within the tag registry. In most cases, this macro - * is not really needed but, for safety, please, use it all the - * time. - * - * Note: This macro is _absolutely_ needed if you try to run a - * distributed simulation. - */ -#define NS_TAG_ENSURE_REGISTERED(x) \ -static class thisisaveryverylongclassname ##x \ -{ \ - public: \ - thisisaveryverylongclassname ##x () \ - { uint32_t uid; uid = x::GetUid ();} \ -} g_thisisanotherveryveryverylongname ## x; - -namespace ns3 { - -/** - * \brief a tag can be stored in a packet. - * - * A tag is a blob of 16 bytes of data which can be stored in - * a packet: a packet can contain an arbitrary number of tags - * and these tags are considered as "on-the-side" per-packet - * data structures which are not taken into account when calculating - * the size of the payload of a packet. They exist solely as - * simulation-specific objects. - * - * Tags are typically used to: - * - implement per-packet cross-layer communication - * - implement packet coloring: you could store a "color" tag - * in a packet to mark various types of packet for - * simulation analysis - * - * To create a new type of tag, you must create a subclass - * of the Tag base class which defines: - * - a public default constructor: needed for implementation - * purposes of the Packet code. - * - a public copy constructor: needed to copy a tag into - * a packet tag buffer when the user invokes Packet::AddTag - * - a public destructor: needed to destroy the copy of a tag - * stored in a packet buffer when the user invokes Packet::RemoveTag - * or when the packet is destroyed and the last reference to - * a tag instance disapears. - * - a public static method named GetUid: needed to uniquely - * the type of each tag instance. - * - a public method named Print: needed to print the content - * of a tag when the user calls Packet::PrintTags - * - a public method named GetSerializedSize: needed to serialize - * the content of a tag to a byte buffer when a packet must - * be sent from one computing node to another in a parallel - * simulation. If this method returns 0, it means that the - * tag does not need to be transfered from computing node to - * computing node - * - a public method named Serialize: perform the serialization - * to a byte buffer upon transfer to a new computing node in a - * parallel simulation. - * - a public method named Deserialize: invert the serialization - * from a byte buffer after being transfered to a new computing - * node in a parallel simulation. - * - * A detailed example of what these methods should look like - * and how they should be implemented is described in samples/main-packet-tag.cc - */ -class Tag -{ -protected: - /** - * \param name the unique name of the new type of tag - * \returns a newly-allocated uid - * - * This method should be used by subclasses to implement - * their static public GetUid method. - */ - template - static uint32_t AllocateUid (std::string name); -}; - -} // namespace ns3 - -// implementation below. -#include "tag-registry.h" - -namespace ns3 { - -template -uint32_t -Tag::AllocateUid (std::string name) -{ - return TagRegistry::Register (name); -} - -} // namespace ns3 - -#endif /* TAG_H */ diff --git a/src/common/tags.cc b/src/common/tags.cc deleted file mode 100644 index a719417a4..000000000 --- a/src/common/tags.cc +++ /dev/null @@ -1,529 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2006 INRIA - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Mathieu Lacage - */ -#include "tags.h" -#include -#include "ns3/fatal-error.h" - -namespace ns3 { - -#ifdef USE_FREE_LIST - -struct Tags::TagData *Tags::gFree = 0; -uint32_t Tags::gN_free = 0; - -struct Tags::TagData * -Tags::AllocData (void) const -{ - struct Tags::TagData *retval; - if (gFree != 0) - { - retval = gFree; - gFree = gFree->m_next; - gN_free--; - } - else - { - retval = new struct Tags::TagData (); - } - return retval; -} - -void -Tags::FreeData (struct TagData *data) const -{ - if (gN_free > 1000) - { - delete data; - return; - } - gN_free++; - data->m_next = gFree; - data->m_id = 0; - gFree = data; -} -#else -struct Tags::TagData * -Tags::AllocData (void) const -{ - struct Tags::TagData *retval; - retval = new struct Tags::TagData (); - return retval; -} - -void -Tags::FreeData (struct TagData *data) const -{ - delete data; -} -#endif - -bool -Tags::Remove (uint32_t id) -{ - bool found = false; - for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) - { - if (cur->m_id == id) - { - found = true; - } - } - if (!found) - { - return false; - } - struct TagData *start = 0; - struct TagData **prevNext = &start; - for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) - { - if (cur->m_id == id) - { - /** - * 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->m_id = cur->m_id; - copy->m_count = 1; - copy->m_next = 0; - memcpy (copy->m_data, cur->m_data, Tags::SIZE); - *prevNext = copy; - prevNext = ©->m_next; - } - *prevNext = 0; - RemoveAll (); - m_next = start; - return true; -} - -void -Tags::Print (std::ostream &os, std::string separator) const -{ - for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) - { - TagRegistry::Print (cur->m_id, cur->m_data, os); - if (cur->m_next != 0) - { - os << separator; - } - } -} - -uint32_t -Tags::GetSerializedSize (void) const -{ - uint32_t totalSize = 4; // reserve space for the size of the tag data. - for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) - { - uint32_t size = TagRegistry::GetSerializedSize (cur->m_id, cur->m_data); - if (size != 0) - { - std::string uidString = TagRegistry::GetUidString (cur->m_id); - totalSize += 4; // for the size of the string itself. - totalSize += uidString.size (); - totalSize += size; - } - } - return totalSize; -} - -void -Tags::Serialize (Buffer::Iterator i, uint32_t totalSize) const -{ - i.WriteU32 (totalSize); - for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) - { - uint32_t size = TagRegistry::GetSerializedSize (cur->m_id, cur->m_data); - if (size != 0) - { - std::string uidString = TagRegistry::GetUidString (cur->m_id); - i.WriteU32 (uidString.size ()); - uint8_t *buf = (uint8_t *)uidString.c_str (); - i.Write (buf, uidString.size ()); - TagRegistry::Serialize (cur->m_id, cur->m_data, i); - } - } -} -uint32_t -Tags::Deserialize (Buffer::Iterator i) -{ - uint32_t totalSize = i.ReadU32 (); - uint32_t bytesRead = 4; - while (bytesRead < totalSize) - { - uint32_t uidStringSize = i.ReadU32 (); - bytesRead += 4; - std::string uidString; - uidString.reserve (uidStringSize); - for (uint32_t j = 0; j < uidStringSize; j++) - { - uint32_t c = i.ReadU8 (); - uidString.push_back (c); - } - bytesRead += uidStringSize; - uint32_t uid = TagRegistry::GetUidFromUidString (uidString); - struct TagData *newStart = AllocData (); - newStart->m_count = 1; - newStart->m_next = 0; - newStart->m_id = uid; - bytesRead += TagRegistry::Deserialize (uid, newStart->m_data, i); - newStart->m_next = m_next; - m_next = newStart; - } - NS_ASSERT (bytesRead == totalSize); - /** - * The process of serialization/deserialization - * results in an inverted linked-list after - * deserialization so, we invert the linked-list - * in-place here. - * Note: the algorithm below is pretty classic - * but whenever I get to code it, it makes my - * brain hurt :) - */ - struct TagData *prev = 0; - struct TagData *cur = m_next; - while (cur != 0) - { - struct TagData *next = cur->m_next; - cur->m_next = prev; - prev = cur; - cur = next; - } - m_next = prev; - return totalSize; -} - - - -}; // namespace ns3 - -#ifdef RUN_SELF_TESTS - -#include "ns3/test.h" -#include -#include - -namespace ns3 { - -static bool g_a; -static bool g_b; -static bool g_c; -static bool g_z; - -class TagsTest : Test { -public: - TagsTest (); - virtual ~TagsTest (); - virtual bool RunTests (void); -}; - -class myTagA : public Tag -{ -public: - static uint32_t GetUid (void) {static uint32_t uid = AllocateUid ("myTagA.test.nsnam.org"); return uid;} - void Print (std::ostream &os) const {g_a = true;} - uint32_t GetSerializedSize (void) const {return 1;} - void Serialize (Buffer::Iterator i) const {i.WriteU8 (a);} - uint32_t Deserialize (Buffer::Iterator i) {a = i.ReadU8 (); return 1;} - - uint8_t a; -}; -class myTagB : public Tag -{ -public: - static uint32_t GetUid (void) {static uint32_t uid = AllocateUid ("myTagB.test.nsnam.org"); return uid;} - void Print (std::ostream &os) const {g_b = true;} - uint32_t GetSerializedSize (void) const {return 4;} - void Serialize (Buffer::Iterator i) const {i.WriteU32 (b);} - uint32_t Deserialize (Buffer::Iterator i) {b = i.ReadU32 (); return 4;} - - uint32_t b; -}; -class myTagC : public Tag -{ -public: - static uint32_t GetUid (void) {static uint32_t uid = AllocateUid ("myTagC.test.nsnam.org"); return uid;} - void Print (std::ostream &os) const {g_c = true;} - uint32_t GetSerializedSize (void) const {return Tags::SIZE;} - void Serialize (Buffer::Iterator i) const {i.Write (c, Tags::SIZE);} - uint32_t Deserialize (Buffer::Iterator i) {i.Read (c, Tags::SIZE); return Tags::SIZE;} - uint8_t c [Tags::SIZE]; -}; -class myInvalidTag : public Tag -{ -public: - static uint32_t GetUid (void) - {static uint32_t uid = AllocateUid ("myinvalidTag.test.nsnam.org"); return uid;} - void Print (std::ostream &os) const {} - uint32_t GetSerializedSize (void) const {return 0;} - void Serialize (Buffer::Iterator i) const {} - uint32_t Deserialize (Buffer::Iterator i) {return 0;} - - uint8_t invalid [Tags::SIZE+1]; -}; -class myTagZ : public Tag -{ -public: - static uint32_t GetUid (void) {static uint32_t uid = AllocateUid ("myTagZ.test.nsnam.org"); return uid;} - void Print (std::ostream &os) const {g_z = true;} - uint32_t GetSerializedSize (void) const {return 0;} - void Serialize (Buffer::Iterator i) const {} - uint32_t Deserialize (Buffer::Iterator i) {return 0;} - - uint8_t z; -}; - -class MySmartTag : public Tag -{ -public: - static uint32_t GetUid (void) - {static uint32_t uid = AllocateUid ("MySmartTag.test.nsnam.org"); return uid;} - MySmartTag () - { - //std::cout << "construct" << std::endl; - } - MySmartTag (const MySmartTag &o) - { - //std::cout << "copy" << std::endl; - } - ~MySmartTag () - { - //std::cout << "destruct" << std::endl; - } - MySmartTag &operator = (const MySmartTag &o) - { - //std::cout << "assign" << std::endl; - return *this; - } - void Print (std::ostream &os) const {} - uint32_t GetSerializedSize (void) const {return 0;} - void Serialize (Buffer::Iterator i) const {} - uint32_t Deserialize (Buffer::Iterator i) {return 0;} -}; - - -TagsTest::TagsTest () - : Test ("Tags") -{} -TagsTest::~TagsTest () -{} - -bool -TagsTest::RunTests (void) -{ - bool ok = true; - - // build initial tag. - Tags tags; - myTagA a; - a.a = 10; - tags.Add (a); - a.a = 0; - tags.Peek (a); - if (a.a != 10) - { - ok = false; - } - g_a = false; - tags.Print (std::cout, ""); - if (!g_a) - { - ok = false; - } - myTagB b; - b.b = 0xff; - tags.Add (b); - b.b = 0; - tags.Peek (b); - if (b.b != 0xff) - { - ok = false; - } - g_b = false; - g_a = false; - tags.Print (std::cout, ""); - if (!g_a || !g_b) - { - ok = false; - } - // make sure copy contains copy. - Tags other = tags; - g_b = false; - g_a = false; - other.Print (std::cout, ""); - if (!g_a || !g_b) - { - ok = false; - } - g_b = false; - g_a = false; - tags.Print (std::cout, ""); - if (!g_a || !g_b) - { - ok = false; - } - myTagA oA; - oA.a = 0; - other.Peek (oA); - if (oA.a != 10) - { - ok = false; - } - myTagB oB; - oB.b = 1; - other.Peek (oB); - if (oB.b != 0xff) - { - ok = false; - } - // remove data. - other.Remove (oA); - if (other.Peek (oA)) - { - ok = false; - } - g_b = false; - g_a = false; - other.Print (std::cout, ""); - if (g_a || !g_b) - { - ok = false; - } - if (!tags.Peek (oA)) - { - ok = false; - } - other.Remove (oB); - if (other.Peek (oB)) - { - ok = false; - } - if (!tags.Peek (oB)) - { - ok = false; - } - - other = tags; - Tags another = other; - myTagC c; - memset (c.c, 0x66, 16); - another.Add (c); - c.c[0] = 0; - another.Peek (c); - if (!another.Peek (c)) - { - ok = false; - } - if (tags.Peek (c)) - { - ok = false; - } - - other = other; - //other.prettyPrint (std::cout); - - //struct myInvalidTag invalid; - //tags.add (&invalid); - - myTagZ tagZ; - Tags testLastTag; - tagZ.z = 0; - testLastTag.Add (tagZ); - g_z = false; - testLastTag.Print (std::cout, ""); - if (!g_z) - { - ok = false; - } - - MySmartTag smartTag; - { - Tags tmp; - tmp.Add (smartTag); - tmp.Peek (smartTag); - tmp.Remove (smartTag); - } - - { - Tags source; - myTagA aSource; - aSource.a = 0x66; - source.Add (aSource); - Buffer buffer; - uint32_t serialized = source.GetSerializedSize (); - buffer.AddAtStart (serialized); - source.Serialize (buffer.Begin (), serialized); - Tags dest; - dest.Deserialize (buffer.Begin ()); - myTagA aDest; - aDest.a = 0x55; - dest.Peek (aDest); - if (aDest.a != 0x66) - { - ok = false; - } - } - - { - Tags source; - myTagA aSource; - aSource.a = 0x66; - source.Add (aSource); - myTagZ zSource; - zSource.z = 0x77; - source.Add (zSource); - - Buffer buffer; - uint32_t serialized = source.GetSerializedSize (); - buffer.AddAtStart (serialized); - source.Serialize (buffer.Begin (), serialized); - Tags dest; - dest.Deserialize (buffer.Begin ()); - - myTagA aDest; - aDest.a = 0x55; - dest.Peek (aDest); - if (aDest.a != 0x66) - { - ok = false; - } - myTagZ zDest; - zDest.z = 0x44; - dest.Peek (zDest); - if (zDest.z != 0x44) - { - ok = false; - } - } - - return ok; -} - -static TagsTest gTagsTest; - - -}; // namespace ns3 - -#endif /* RUN_SELF_TESTS */ - diff --git a/src/common/tags.h b/src/common/tags.h deleted file mode 100644 index a88b6a6e0..000000000 --- a/src/common/tags.h +++ /dev/null @@ -1,228 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2006 INRIA - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Mathieu Lacage - */ -#ifndef TAGS_H -#define TAGS_H - -#include -#include -#include -#include "buffer.h" - -namespace ns3 { - -/** - * \ingroup constants - * \brief Tag maximum size - * The maximum size (in bytes) of a Tag is stored - * in this constant. - */ -#define TAGS_MAX_SIZE 16 - -class Tags { -public: - inline Tags (); - inline Tags (Tags const &o); - inline Tags &operator = (Tags const &o); - inline ~Tags (); - - template - void Add (T const&tag) const; - - template - bool Remove (T &tag); - - template - bool Peek (T &tag) const; - - void Print (std::ostream &os, std::string separator) const; - uint32_t GetSerializedSize (void) const; - void Serialize (Buffer::Iterator i, uint32_t size) const; - uint32_t Deserialize (Buffer::Iterator i); - - inline void RemoveAll (void); - - enum { - SIZE = TAGS_MAX_SIZE - }; -private: - struct TagData { - uint8_t m_data[Tags::SIZE]; - struct TagData *m_next; - uint32_t m_id; - uint32_t m_count; - }; - - bool Remove (uint32_t id); - struct Tags::TagData *AllocData (void) const; - void FreeData (struct TagData *data) const; - - static struct Tags::TagData *gFree; - static uint32_t gN_free; - - struct TagData *m_next; -}; - -} // namespace ns3 - - - -/************************************************************** - An implementation of the templates defined above - *************************************************************/ -#include "tag-registry.h" -#include "tag.h" -#include "ns3/assert.h" -#include - -namespace ns3 { - -template -void -Tags::Add (T const&tag) const -{ - const Tag *parent; - // if the following assignment fails, it is because the - // input to this function is not a subclass of the Tag class. - parent = &tag; - - NS_ASSERT (sizeof (T) <= Tags::SIZE); - // ensure this id was not yet added - for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) - { - NS_ASSERT (cur->m_id != T::GetUid ()); - } - struct TagData *newStart = AllocData (); - newStart->m_count = 1; - newStart->m_next = 0; - newStart->m_id = T::GetUid (); - void *buf = &newStart->m_data; - new (buf) T (tag); - newStart->m_next = m_next; - const_cast (this)->m_next = newStart; -} - -template -bool -Tags::Remove (T &tag) -{ - Tag *parent; - // if the following assignment fails, it is because the - // input to this function is not a subclass of the Tag class. - parent = &tag; - NS_ASSERT (sizeof (T) <= Tags::SIZE); - if (Peek (tag)) - { - Remove (T::GetUid ()); - return true; - } - else - { - return false; - } -} - -template -bool -Tags::Peek (T &tag) const -{ - Tag *parent; - // if the following assignment fails, it is because the - // input to this function is not a subclass of the Tag class. - parent = &tag; - NS_ASSERT (sizeof (T) <= Tags::SIZE); - for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) - { - if (cur->m_id == T::GetUid ()) - { - /* found tag */ - T *data = reinterpret_cast (&cur->m_data); - tag = T (*data); - return true; - } - } - /* no tag found */ - return false; -} - -Tags::Tags () - : m_next () -{} - -Tags::Tags (Tags const &o) - : m_next (o.m_next) -{ - if (m_next != 0) - { - m_next->m_count++; - } -} - -Tags & -Tags::operator = (Tags const &o) -{ - // self assignment - if (m_next == o.m_next) - { - return *this; - } - RemoveAll (); - m_next = o.m_next; - if (m_next != 0) - { - m_next->m_count++; - } - return *this; -} - -Tags::~Tags () -{ - RemoveAll (); -} - -void -Tags::RemoveAll (void) -{ - struct TagData *prev = 0; - for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) - { - cur->m_count--; - if (cur->m_count > 0) - { - break; - } - if (prev != 0) - { - TagRegistry::Destruct (prev->m_id, prev->m_data); - FreeData (prev); - } - prev = cur; - } - if (prev != 0) - { - TagRegistry::Destruct (prev->m_id, prev->m_data); - FreeData (prev); - } - m_next = 0; -} - - -}; // namespace ns3 - -#endif /* TAGS_H */ diff --git a/src/common/wscript b/src/common/wscript index 36dd83c37..f4759f114 100644 --- a/src/common/wscript +++ b/src/common/wscript @@ -7,8 +7,6 @@ def build(bld): 'packet-metadata.cc', 'packet-metadata-test.cc', 'packet.cc', - 'tags.cc', - 'tag-registry.cc', 'chunk.cc', 'header.cc', 'trailer.cc', @@ -27,9 +25,6 @@ def build(bld): 'chunk.h', 'header.h', 'trailer.h', - 'tags.h', - 'tag-registry.h', - 'tag.h', 'packet.h', 'packet-metadata.h', 'pcap-writer.h',