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 } |