src/common/tags.h
changeset 122 6b8f1eda5c57
parent 111 ad64f88919b5
child 131 f4fb87e77034
equal deleted inserted replaced
121:f8bc1a370b82 122:6b8f1eda5c57
    44     inline Tags (Tags const &o);
    44     inline Tags (Tags const &o);
    45     inline Tags &operator = (Tags const &o);
    45     inline Tags &operator = (Tags const &o);
    46     inline ~Tags ();
    46     inline ~Tags ();
    47 
    47 
    48     template <typename T>
    48     template <typename T>
    49     void add (T const&tag);
    49     void Add (T const&tag);
    50 
    50 
    51     template <typename T>
    51     template <typename T>
    52     bool remove (T &tag);
    52     bool Remove (T &tag);
    53 
    53 
    54     template <typename T>
    54     template <typename T>
    55     bool peek (T &tag) const;
    55     bool Peek (T &tag) const;
    56 
    56 
    57     void prettyPrint (std::ostream &os);
    57     void PrettyPrint (std::ostream &os);
    58 
    58 
    59     inline void removeAll (void);
    59     inline void RemoveAll (void);
    60 
    60 
    61     enum {
    61     enum {
    62         SIZE = TAGS_MAX_SIZE
    62         SIZE = TAGS_MAX_SIZE
    63     };
    63     };
    64 private:
    64 private:
    67         uint32_t m_id;
    67         uint32_t m_id;
    68         uint32_t m_count;
    68         uint32_t m_count;
    69         uint8_t m_data[Tags::SIZE];
    69         uint8_t m_data[Tags::SIZE];
    70     };
    70     };
    71 
    71 
    72     bool remove (uint32_t id);
    72     bool Remove (uint32_t id);
    73     struct Tags::TagData *allocData (void);
    73     struct Tags::TagData *AllocData (void);
    74     void freeData (struct TagData *data);
    74     void FreeData (struct TagData *data);
    75 
    75 
    76     static struct Tags::TagData *gFree;
    76     static struct Tags::TagData *gFree;
    77     static uint32_t gN_free;
    77     static uint32_t gN_free;
    78 
    78 
    79     struct TagData *m_next;
    79     struct TagData *m_next;
    96      * \param fn a function which can pretty-print an instance
    96      * \param fn a function which can pretty-print an instance
    97      *        of type T in the output stream.
    97      *        of type T in the output stream.
    98      */
    98      */
    99     TagRegistration<T> (std::string uuid, void(*fn) (T *, std::ostream &));
    99     TagRegistration<T> (std::string uuid, void(*fn) (T *, std::ostream &));
   100 private:
   100 private:
   101     static void prettyPrinterCb (uint8_t *buf, std::ostream &os);
   101     static void PrettyPrinterCb (uint8_t *buf, std::ostream &os);
   102     static void(*m_prettyPrinter) (T *, std::ostream &);
   102     static void(*m_prettyPrinter) (T *, std::ostream &);
   103 };
   103 };
   104 
   104 
   105 }; // namespace ns3
   105 }; // namespace ns3
   106 
   106 
   115 namespace ns3 {
   115 namespace ns3 {
   116 
   116 
   117 class TagRegistry {
   117 class TagRegistry {
   118 public:
   118 public:
   119     typedef void (*PrettyPrinter) (uint8_t [Tags::SIZE], std::ostream &);
   119     typedef void (*PrettyPrinter) (uint8_t [Tags::SIZE], std::ostream &);
   120     static void record (std::string uuid, PrettyPrinter prettyPrinter);
   120     static void Record (std::string uuid, PrettyPrinter prettyPrinter);
   121     static uint32_t lookupUid (std::string uuid);
   121     static uint32_t LookupUid (std::string uuid);
   122     static void prettyPrint (uint32_t uid, uint8_t buf[Tags::SIZE], std::ostream &os);
   122     static void PrettyPrint (uint32_t uid, uint8_t buf[Tags::SIZE], std::ostream &os);
   123 private:
   123 private:
   124     typedef std::vector<std::pair<std::string,PrettyPrinter> > TagsData;
   124     typedef std::vector<std::pair<std::string,PrettyPrinter> > TagsData;
   125     typedef std::vector<std::pair<std::string,PrettyPrinter> >::const_iterator TagsDataCI;
   125     typedef std::vector<std::pair<std::string,PrettyPrinter> >::const_iterator TagsDataCI;
   126     static bool m_sorted;
   126     static bool m_sorted;
   127     static TagsData m_registry;
   127     static TagsData m_registry;
   135  * from the constructor of another static variable.
   135  * from the constructor of another static variable.
   136  */
   136  */
   137 template <typename T>
   137 template <typename T>
   138 class TypeUid {
   138 class TypeUid {
   139 public:
   139 public:
   140     static void record (std::string uuid);
   140     static void Record (std::string uuid);
   141     static const uint32_t getUid (void);
   141     static const uint32_t GetUid (void);
   142 private:
   142 private:
   143     static std::string *getUuid (void);
   143     static std::string *GetUuid (void);
   144     T m_realType;
   144     T m_realType;
   145 };
   145 };
   146 
   146 
   147 template <typename T>
   147 template <typename T>
   148 void TypeUid<T>::record (std::string uuid)
   148 void TypeUid<T>::Record (std::string uuid)
   149 {
   149 {
   150     *(getUuid ()) = uuid;
   150     *(GetUuid ()) = uuid;
   151 }
   151 }
   152 
   152 
   153 template <typename T>
   153 template <typename T>
   154 const uint32_t TypeUid<T>::getUid (void)
   154 const uint32_t TypeUid<T>::GetUid (void)
   155 {
   155 {
   156     static const uint32_t uid = TagRegistry::lookupUid (*(getUuid ()));
   156     static const uint32_t uid = TagRegistry::LookupUid (*(GetUuid ()));
   157     return uid;
   157     return uid;
   158 }
   158 }
   159 
   159 
   160 template <typename T>
   160 template <typename T>
   161 std::string *TypeUid<T>::getUuid (void)
   161 std::string *TypeUid<T>::GetUuid (void)
   162 {
   162 {
   163     static std::string uuid;
   163     static std::string uuid;
   164     return &uuid;
   164     return &uuid;
   165 }
   165 }
   166 
   166 
   175 template <typename T>
   175 template <typename T>
   176 TagRegistration<T>::TagRegistration (std::string uuid, void (*prettyPrinter) (T *, std::ostream &))
   176 TagRegistration<T>::TagRegistration (std::string uuid, void (*prettyPrinter) (T *, std::ostream &))
   177 {
   177 {
   178     assert (sizeof (T) <= Tags::SIZE);
   178     assert (sizeof (T) <= Tags::SIZE);
   179     m_prettyPrinter  = prettyPrinter;
   179     m_prettyPrinter  = prettyPrinter;
   180     TagRegistry::record (uuid, &TagRegistration<T>::prettyPrinterCb);
   180     TagRegistry::Record (uuid, &TagRegistration<T>::PrettyPrinterCb);
   181     TypeUid<T>::record (uuid);
   181     TypeUid<T>::Record (uuid);
   182 }
   182 }
   183 template <typename T>
   183 template <typename T>
   184 void 
   184 void 
   185 TagRegistration<T>::prettyPrinterCb (uint8_t *buf, std::ostream &os)
   185 TagRegistration<T>::PrettyPrinterCb (uint8_t *buf, std::ostream &os)
   186 {
   186 {
   187     assert (sizeof (T) <= Tags::SIZE);
   187     assert (sizeof (T) <= Tags::SIZE);
   188     T *tag = reinterpret_cast<T *> (buf);
   188     T *tag = reinterpret_cast<T *> (buf);
   189     (*m_prettyPrinter) (tag, os);
   189     (*m_prettyPrinter) (tag, os);
   190 }
   190 }
   195 
   195 
   196 
   196 
   197 
   197 
   198 template <typename T>
   198 template <typename T>
   199 void 
   199 void 
   200 Tags::add (T const&tag)
   200 Tags::Add (T const&tag)
   201 {
   201 {
   202     assert (sizeof (T) <= Tags::SIZE);
   202     assert (sizeof (T) <= Tags::SIZE);
   203     uint8_t const*buf = reinterpret_cast<uint8_t const*> (&tag);
   203     uint8_t const*buf = reinterpret_cast<uint8_t const*> (&tag);
   204     // ensure this id was not yet added
   204     // ensure this id was not yet added
   205     for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
   205     for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
   206         assert (cur->m_id != TypeUid<T>::getUid ());
   206         assert (cur->m_id != TypeUid<T>::GetUid ());
   207     }
   207     }
   208     struct TagData *newStart = allocData ();
   208     struct TagData *newStart = AllocData ();
   209     newStart->m_count = 1;
   209     newStart->m_count = 1;
   210     newStart->m_next = 0;
   210     newStart->m_next = 0;
   211     newStart->m_id = TypeUid<T>::getUid ();
   211     newStart->m_id = TypeUid<T>::GetUid ();
   212     memcpy (newStart->m_data, buf, sizeof (T));
   212     memcpy (newStart->m_data, buf, sizeof (T));
   213     newStart->m_next = m_next;
   213     newStart->m_next = m_next;
   214     m_next = newStart;
   214     m_next = newStart;
   215 }
   215 }
   216 
   216 
   217 template <typename T>
   217 template <typename T>
   218 bool
   218 bool
   219 Tags::remove (T &tag)
   219 Tags::Remove (T &tag)
   220 {
   220 {
   221     assert (sizeof (T) <= Tags::SIZE);
   221     assert (sizeof (T) <= Tags::SIZE);
   222     return remove (TypeUid<T>::getUid ());
   222     return Remove (TypeUid<T>::GetUid ());
   223 }
   223 }
   224 
   224 
   225 template <typename T>
   225 template <typename T>
   226 bool
   226 bool
   227 Tags::peek (T &tag) const
   227 Tags::Peek (T &tag) const
   228 {
   228 {
   229     assert (sizeof (T) <= Tags::SIZE);
   229     assert (sizeof (T) <= Tags::SIZE);
   230     uint8_t *buf = reinterpret_cast<uint8_t *> (&tag);
   230     uint8_t *buf = reinterpret_cast<uint8_t *> (&tag);
   231     for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
   231     for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
   232         if (cur->m_id == TypeUid<T>::getUid ()) {
   232         if (cur->m_id == TypeUid<T>::GetUid ()) {
   233             /* found tag */
   233             /* found tag */
   234             memcpy (buf, cur->m_data, sizeof (T));
   234             memcpy (buf, cur->m_data, sizeof (T));
   235             return true;
   235             return true;
   236         }
   236         }
   237     }
   237     }
   256 {
   256 {
   257     // self assignment
   257     // self assignment
   258     if (m_next == o.m_next) {
   258     if (m_next == o.m_next) {
   259         return *this;
   259         return *this;
   260     }
   260     }
   261     removeAll ();
   261     RemoveAll ();
   262     m_next = o.m_next;
   262     m_next = o.m_next;
   263     if (m_next != 0) {
   263     if (m_next != 0) {
   264         m_next->m_count++;
   264         m_next->m_count++;
   265     }
   265     }
   266     return *this;
   266     return *this;
   267 }
   267 }
   268 
   268 
   269 Tags::~Tags ()
   269 Tags::~Tags ()
   270 {
   270 {
   271     removeAll ();
   271     RemoveAll ();
   272 }
   272 }
   273 
   273 
   274 void
   274 void
   275 Tags::removeAll (void)
   275 Tags::RemoveAll (void)
   276 {
   276 {
   277     struct TagData *prev = 0;
   277     struct TagData *prev = 0;
   278     for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
   278     for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next) {
   279         cur->m_count--;
   279         cur->m_count--;
   280         if (cur->m_count > 0) {
   280         if (cur->m_count > 0) {
   281             break;
   281             break;
   282         }
   282         }
   283         if (prev != 0) {
   283         if (prev != 0) {
   284             freeData (prev);
   284             FreeData (prev);
   285         }
   285         }
   286         prev = cur;
   286         prev = cur;
   287     }
   287     }
   288     if (prev != 0) {
   288     if (prev != 0) {
   289         freeData (prev);
   289         FreeData (prev);
   290     }
   290     }
   291     m_next = 0;
   291     m_next = 0;
   292 }
   292 }
   293 
   293 
   294 
   294