--- a/src/common/packet.h Wed Aug 08 09:12:55 2007 +0200
+++ b/src/common/packet.h Wed Aug 08 09:49:56 2007 +0200
@@ -27,6 +27,7 @@
#include "trailer.h"
#include "tags.h"
#include "packet-metadata.h"
+#include "tag.h"
#include "ns3/callback.h"
#include "ns3/assert.h"
@@ -470,18 +471,31 @@
template <typename T>
void Packet::AddTag (T const& 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;
m_tags.Add (tag);
}
template <typename T>
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 <typename T>
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
+
+} // namespace ns3
#endif /* PACKET_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/tag-registry.cc Wed Aug 08 09:49:56 2007 +0200
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * 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 <mathieu.lacage@sophia.inria.fr>
+ */
+#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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/tag-registry.h Wed Aug 08 09:49:56 2007 +0200
@@ -0,0 +1,149 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * 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 <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef TAG_REGISTRY_H
+#define TAG_REGISTRY_H
+
+#include <string>
+#include <stdint.h>
+#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 <typename T>
+ 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<struct TagInfo> TagInfoVector;
+
+ template <typename T>
+ static void DoDestruct (uint8_t *data);
+ template <typename T>
+ static void DoPrint (uint8_t *data, std::ostream &os);
+ template <typename T>
+ static uint32_t DoGetSerializedSize (uint8_t *data);
+ template <typename T>
+ static void DoSerialize (uint8_t *data, Buffer::Iterator start);
+ template <typename T>
+ static uint32_t DoDeserialize (uint8_t *data, Buffer::Iterator start);
+
+ static TagInfoVector *GetInfo (void);
+};
+
+} // namespace ns3
+
+namespace ns3 {
+
+template <typename T>
+void
+TagRegistry::DoDestruct (uint8_t *data)
+{
+ T *tag = reinterpret_cast<T *> (data);
+ tag->~T ();
+}
+template <typename T>
+void
+TagRegistry::DoPrint (uint8_t *data, std::ostream &os)
+{
+ T *tag = reinterpret_cast<T *> (data);
+ tag->Print (os);
+}
+template <typename T>
+uint32_t
+TagRegistry::DoGetSerializedSize (uint8_t *data)
+{
+ T *tag = reinterpret_cast<T *> (data);
+ return tag->GetSerializedSize ();
+}
+template <typename T>
+void
+TagRegistry::DoSerialize (uint8_t *data, Buffer::Iterator start)
+{
+ T *tag = reinterpret_cast<T *> (data);
+ tag->Serialize (start);
+}
+template <typename T>
+uint32_t
+TagRegistry::DoDeserialize (uint8_t *data, Buffer::Iterator start)
+{
+ T *tag = reinterpret_cast<T *> (data);
+ return tag->Deserialize (start);
+}
+
+template <typename T>
+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<T>;
+ info.print = &TagRegistry::DoPrint<T>;
+ info.getSerializedSize = &TagRegistry::DoGetSerializedSize<T>;
+ info.serialize = &TagRegistry::DoSerialize<T>;
+ info.deserialize = &TagRegistry::DoDeserialize<T>;
+ vec->push_back (info);
+ uint32_t uid = vec->size ();
+ return uid;
+}
+
+} // namespace ns3
+
+#endif /* TAG_REGISTRY_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/tag.h Wed Aug 08 09:49:56 2007 +0200
@@ -0,0 +1,49 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * 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 <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef TAG_H
+#define TAG_H
+
+namespace ns3 {
+
+class Tag
+{
+protected:
+ template <typename T>
+ static uint32_t AllocateUid (std::string name);
+};
+
+} // namespace ns3
+
+// implementation below.
+#include "tag-registry.h"
+
+namespace ns3 {
+
+template <typename T>
+uint32_t
+Tag::AllocateUid (std::string name)
+{
+ return TagRegistry::Register<T> (name);
+}
+
+} // namespace ns3
+
+#endif /* TAG_H */
--- a/src/common/tags.cc Wed Aug 08 09:12:55 2007 +0200
+++ b/src/common/tags.cc Wed Aug 08 09:49:56 2007 +0200
@@ -24,67 +24,6 @@
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[Tags::SIZE])
-{
- TagInfo info = (*GetInfo ())[uid - 1];
- info.destruct (data);
-}
-void
-TagRegistry::Print (uint32_t uid, uint8_t data[Tags::SIZE], std::ostream &os)
-{
- TagInfo info = (*GetInfo ())[uid - 1];
- info.print (data, os);
-}
-uint32_t
-TagRegistry::GetSerializedSize (uint32_t uid, uint8_t data[Tags::SIZE])
-{
- TagInfo info = (*GetInfo ())[uid - 1];
- return info.getSerializedSize (data);
-}
-void
-TagRegistry::Serialize (uint32_t uid, uint8_t data[Tags::SIZE], Buffer::Iterator start)
-{
- TagInfo info = (*GetInfo ())[uid - 1];
- info.serialize (data, start);
-}
-uint32_t
-TagRegistry::Deserialize (uint32_t uid, uint8_t data[Tags::SIZE], Buffer::Iterator start)
-{
- TagInfo info = (*GetInfo ())[uid - 1];
- return info.deserialize (data, start);
-}
-
#ifdef USE_FREE_LIST
struct Tags::TagData *Tags::gFree = 0;
@@ -296,10 +235,10 @@
virtual bool RunTests (void);
};
-class myTagA
+class myTagA : public Tag
{
public:
- static uint32_t GetUid (void) {static uint32_t uid = TagRegistry::Register<myTagA> ("myTagA.test.nsnam.org"); return uid;}
+ static uint32_t GetUid (void) {static uint32_t uid = AllocateUid<myTagA> ("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);}
@@ -307,10 +246,10 @@
uint8_t a;
};
-class myTagB
+class myTagB : public Tag
{
public:
- static uint32_t GetUid (void) {static uint32_t uid = TagRegistry::Register<myTagB> ("myTagB.test.nsnam.org"); return uid;}
+ static uint32_t GetUid (void) {static uint32_t uid = AllocateUid<myTagB> ("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);}
@@ -318,21 +257,21 @@
uint32_t b;
};
-class myTagC
+class myTagC : public Tag
{
public:
- static uint32_t GetUid (void) {static uint32_t uid = TagRegistry::Register<myTagC> ("myTagC.test.nsnam.org"); return uid;}
+ static uint32_t GetUid (void) {static uint32_t uid = AllocateUid<myTagC> ("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
+class myInvalidTag : public Tag
{
public:
static uint32_t GetUid (void)
- {static uint32_t uid = TagRegistry::Register<myInvalidTag> ("myinvalidTag.test.nsnam.org"); return uid;}
+ {static uint32_t uid = AllocateUid<myInvalidTag> ("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 {}
@@ -340,10 +279,10 @@
uint8_t invalid [Tags::SIZE+1];
};
-class myTagZ
+class myTagZ : public Tag
{
public:
- static uint32_t GetUid (void) {static uint32_t uid = TagRegistry::Register<myTagZ> ("myTagZ.test.nsnam.org"); return uid;}
+ static uint32_t GetUid (void) {static uint32_t uid = AllocateUid<myTagZ> ("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 {}
@@ -352,11 +291,11 @@
uint8_t z;
};
-class MySmartTag
+class MySmartTag : public Tag
{
public:
static uint32_t GetUid (void)
- {static uint32_t uid = TagRegistry::Register<MySmartTag> ("MySmartTag.test.nsnam.org"); return uid;}
+ {static uint32_t uid = AllocateUid<MySmartTag> ("MySmartTag.test.nsnam.org"); return uid;}
MySmartTag ()
{
//std::cout << "construct" << std::endl;
--- a/src/common/tags.h Wed Aug 08 09:12:55 2007 +0200
+++ b/src/common/tags.h Wed Aug 08 09:49:56 2007 +0200
@@ -114,128 +114,22 @@
/**************************************************************
An implementation of the templates defined above
*************************************************************/
+#include "tag-registry.h"
+#include "tag.h"
#include "ns3/assert.h"
#include <string>
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 <typename T>
- 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[Tags::SIZE]);
- static void Print (uint32_t uid, uint8_t data[Tags::SIZE], std::ostream &os);
- static uint32_t GetSerializedSize (uint32_t uid, uint8_t data[Tags::SIZE]);
- static void Serialize (uint32_t uid, uint8_t data[Tags::SIZE], Buffer::Iterator start);
- static uint32_t Deserialize (uint32_t uid, uint8_t data[Tags::SIZE], Buffer::Iterator start);
-private:
- typedef void (*DestructCb) (uint8_t [Tags::SIZE]);
- typedef void (*PrintCb) (uint8_t [Tags::SIZE], std::ostream &);
- typedef uint32_t (*GetSerializedSizeCb) (uint8_t [Tags::SIZE]);
- typedef void (*SerializeCb) (uint8_t [Tags::SIZE], Buffer::Iterator);
- typedef uint32_t (*DeserializeCb) (uint8_t [Tags::SIZE], Buffer::Iterator);
- struct TagInfo
- {
- std::string uidString;
- DestructCb destruct;
- PrintCb print;
- GetSerializedSizeCb getSerializedSize;
- SerializeCb serialize;
- DeserializeCb deserialize;
- };
- typedef std::vector<struct TagInfo> TagInfoVector;
-
- template <typename T>
- static void DoDestruct (uint8_t data[Tags::SIZE]);
- template <typename T>
- static void DoPrint (uint8_t data[Tags::SIZE], std::ostream &os);
- template <typename T>
- static uint32_t DoGetSerializedSize (uint8_t data[Tags::SIZE]);
- template <typename T>
- static void DoSerialize (uint8_t data[Tags::SIZE], Buffer::Iterator start);
- template <typename T>
- static uint32_t DoDeserialize (uint8_t data[Tags::SIZE], Buffer::Iterator start);
-
- static TagInfoVector *GetInfo (void);
-};
-
-template <typename T>
-void
-TagRegistry::DoDestruct (uint8_t data[Tags::SIZE])
-{
- T *tag = reinterpret_cast<T *> (data);
- tag->~T ();
-}
-template <typename T>
-void
-TagRegistry::DoPrint (uint8_t data[Tags::SIZE], std::ostream &os)
-{
- T *tag = reinterpret_cast<T *> (data);
- tag->Print (os);
-}
-template <typename T>
-uint32_t
-TagRegistry::DoGetSerializedSize (uint8_t data[Tags::SIZE])
-{
- T *tag = reinterpret_cast<T *> (data);
- return tag->GetSerializedSize ();
-}
-template <typename T>
-void
-TagRegistry::DoSerialize (uint8_t data[Tags::SIZE], Buffer::Iterator start)
-{
- T *tag = reinterpret_cast<T *> (data);
- tag->Serialize (start);
-}
-template <typename T>
-uint32_t
-TagRegistry::DoDeserialize (uint8_t data[Tags::SIZE], Buffer::Iterator start)
-{
- T *tag = reinterpret_cast<T *> (data);
- return tag->Deserialize (start);
-}
-
-template <typename T>
-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<T>;
- info.print = &TagRegistry::DoPrint<T>;
- info.getSerializedSize = &TagRegistry::DoGetSerializedSize<T>;
- info.serialize = &TagRegistry::DoSerialize<T>;
- info.deserialize = &TagRegistry::DoDeserialize<T>;
- vec->push_back (info);
- uint32_t uid = vec->size ();
- return uid;
-}
-
template <typename T>
void
Tags::Add (T const&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);
// ensure this id was not yet added
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next)
@@ -256,6 +150,10 @@
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);
return Remove (T::GetUid ());
}
@@ -264,6 +162,10 @@
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)
{
--- a/src/common/wscript Wed Aug 08 09:12:55 2007 +0200
+++ b/src/common/wscript Wed Aug 08 09:49:56 2007 +0200
@@ -13,6 +13,7 @@
'packet-metadata-test.cc',
'packet.cc',
'tags.cc',
+ 'tag-registry.cc',
'pcap-writer.cc',
'variable-tracer-test.cc',
'trace-context.cc',
@@ -32,6 +33,8 @@
'header.h',
'trailer.h',
'tags.h',
+ 'tag-registry.h',
+ 'tag.h',
'packet.h',
'packet-printer.h',
'packet-metadata.h',