A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
packet-tag-list.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include "packet-tag-list.h"
21 #include "tag-buffer.h"
22 #include "tag.h"
23 #include "ns3/fatal-error.h"
24 #include "ns3/log.h"
25 #include <cstring>
26 
27 NS_LOG_COMPONENT_DEFINE ("PacketTagList");
28 
29 namespace ns3 {
30 
31 #ifdef USE_FREE_LIST
32 
33 struct PacketTagList::TagData *PacketTagList::g_free = 0;
34 uint32_t PacketTagList::g_nfree = 0;
35 
36 struct PacketTagList::TagData *
37 PacketTagList::AllocData (void) const
38 {
40  struct PacketTagList::TagData *retval;
41  if (g_free != 0)
42  {
43  retval = g_free;
44  g_free = g_free->m_next;
45  g_nfree--;
46  }
47  else
48  {
49  retval = new struct PacketTagList::TagData ();
50  }
51  return retval;
52 }
53 
54 void
55 PacketTagList::FreeData (struct TagData *data) const
56 {
57  NS_LOG_FUNCTION (data);
58  if (g_nfree > 1000)
59  {
60  delete data;
61  return;
62  }
63  g_nfree++;
64  data->next = g_free;
65  data->tid = TypeId ();
66  g_free = data;
67 }
68 #else
69 struct PacketTagList::TagData *
70 PacketTagList::AllocData (void) const
71 {
72  NS_LOG_FUNCTION (this);
73  struct PacketTagList::TagData *retval;
74  retval = new struct PacketTagList::TagData ();
75  return retval;
76 }
77 
78 void
79 PacketTagList::FreeData (struct TagData *data) const
80 {
81  NS_LOG_FUNCTION (this << data);
82  delete data;
83 }
84 #endif
85 
86 bool
88 {
89  NS_LOG_FUNCTION (this << &tag);
90  TypeId tid = tag.GetInstanceTypeId ();
91  bool found = false;
92  for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
93  {
94  if (cur->tid == tid)
95  {
96  found = true;
97  tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE));
98  }
99  }
100  if (!found)
101  {
102  return false;
103  }
104  struct TagData *start = 0;
105  struct TagData **prevNext = &start;
106  for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
107  {
108  if (cur->tid == tid)
109  {
116  continue;
117  }
118  struct TagData *copy = AllocData ();
119  copy->tid = cur->tid;
120  copy->count = 1;
121  copy->next = 0;
122  std::memcpy (copy->data, cur->data, PACKET_TAG_MAX_SIZE);
123  *prevNext = copy;
124  prevNext = &copy->next;
125  }
126  *prevNext = 0;
127  RemoveAll ();
128  m_next = start;
129  return true;
130 }
131 
132 void
133 PacketTagList::Add (const Tag &tag) const
134 {
135  NS_LOG_FUNCTION (this << &tag);
136  // ensure this id was not yet added
137  for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
138  {
139  NS_ASSERT (cur->tid != tag.GetInstanceTypeId ());
140  }
141  struct TagData *head = AllocData ();
142  head->count = 1;
143  head->next = 0;
144  head->tid = tag.GetInstanceTypeId ();
145  head->next = m_next;
147  tag.Serialize (TagBuffer (head->data, head->data+tag.GetSerializedSize ()));
148 
149  const_cast<PacketTagList *> (this)->m_next = head;
150 }
151 
152 bool
153 PacketTagList::Peek (Tag &tag) const
154 {
155  NS_LOG_FUNCTION (this << &tag);
156  TypeId tid = tag.GetInstanceTypeId ();
157  for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
158  {
159  if (cur->tid == tid)
160  {
161  /* found tag */
162  tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE));
163  return true;
164  }
165  }
166  /* no tag found */
167  return false;
168 }
169 
170 const struct PacketTagList::TagData *
171 PacketTagList::Head (void) const
172 {
173  return m_next;
174 }
175 
176 } // namespace ns3
177 
bool Remove(Tag &tag)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
virtual uint32_t GetSerializedSize(void) const =0
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
virtual void Serialize(TagBuffer i) const =0
tag a set of bytes in a packet
Definition: tag.h:36
virtual void Deserialize(TagBuffer i)=0
#define PACKET_TAG_MAX_SIZE
Tag maximum size The maximum size (in bytes) of a Tag is stored in this constant. ...
read and write tag data
Definition: tag-buffer.h:51
virtual TypeId GetInstanceTypeId(void) const =0
a unique identifier for an interface.
Definition: type-id.h:44