A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
packet-tag-list.cc
Go to the documentation of this file.
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
26
#include "
packet-tag-list.h
"
27
#include "
tag-buffer.h
"
28
#include "
tag.h
"
29
#include "ns3/fatal-error.h"
30
#include "ns3/log.h"
31
#include <cstring>
32
33
NS_LOG_COMPONENT_DEFINE
(
"PacketTagList"
);
34
35
namespace
ns3 {
36
37
bool
38
PacketTagList::COWTraverse
(
Tag
& tag,
PacketTagList::COWWriter
Writer)
39
{
40
TypeId
tid = tag.
GetInstanceTypeId
();
41
NS_LOG_FUNCTION
(
this
<< tid);
42
NS_LOG_INFO
(
"looking for "
<< tid);
43
44
// trivial case when list is empty
45
if
(
m_next
== 0)
46
{
47
return
false
;
48
}
49
50
bool
found =
false
;
51
52
struct
TagData
** prevNext = &
m_next
;
// previous node's next pointer
53
struct
TagData
* cur =
m_next
;
// cursor to current node
54
struct
TagData
* it = 0;
// utility
55
56
// Search from the head of the list until we find tid or a merge
57
while
(cur != 0)
58
{
59
if
(cur->
count
> 1)
60
{
61
// found merge
62
NS_LOG_INFO
(
"found initial merge before tid"
);
63
break
;
64
}
65
else
if
(cur->
tid
== tid)
66
{
67
NS_LOG_INFO
(
"found tid before initial merge, calling writer"
);
68
found = (this->*Writer)(tag,
true
, cur, prevNext);
69
break
;
70
}
71
else
72
{
73
// no merge or tid found yet, move on
74
prevNext = &cur->
next
;
75
cur = cur->
next
;
76
}
77
}
// while !found && !cow
78
79
// did we find it or run out of tags?
80
if
(cur == 0 || found)
81
{
82
NS_LOG_INFO
(
"returning after header with found: "
<< found);
83
return
found;
84
}
85
86
// From here on out, we have to copy the list
87
// until we find tid, then link past it
88
89
// Before we do all that work, let's make sure tid really exists
90
for
(it = cur; it != 0; it = it->
next
)
91
{
92
if
(it->
tid
== tid)
93
{
94
break
;
95
}
96
}
97
if
(it == 0)
98
{
99
// got to end of list without finding tid
100
NS_LOG_INFO
(
"tid not found after first merge"
);
101
return
found;
102
}
103
104
// At this point cur is a merge, but untested for tid
105
NS_ASSERT
(cur != 0);
106
NS_ASSERT
(cur->
count
> 1);
107
108
/*
109
Walk the remainder of the list, copying, until we find tid
110
As we put a copy of the cur node onto our list,
111
we move the merge point down the list.
112
113
Starting position End position
114
T1 is a merge T1.count decremented
115
T2 is a merge
116
T1' is a copy of T1
117
118
other other
119
\ \
120
Prev -> T1 -> T2 -> ... T1 -> T2 -> ...
121
/ / /|
122
pNext cur Prev -> T1' --/ |
123
/ |
124
pNext cur
125
126
When we reach tid, we link past it, decrement count, and we're done.
127
*/
128
129
// Should normally check for null cur pointer,
130
// but since we know tid exists, we'll skip this test
131
while
(
/* cur && */
cur->
tid
!= tid)
132
{
133
NS_ASSERT
(cur != 0);
134
NS_ASSERT
(cur->
count
> 1);
135
cur->
count
--;
// unmerge cur
136
struct
TagData
* copy =
new
struct
TagData
();
137
copy->
tid
= cur->
tid
;
138
copy->
count
= 1;
139
memcpy (copy->
data
, cur->
data
,
TagData::MAX_SIZE
);
140
copy->
next
= cur->
next
;
// merge into tail
141
copy->
next
->
count
++;
// mark new merge
142
*prevNext = copy;
// point prior list at copy
143
prevNext = ©->
next
;
// advance
144
cur = copy->
next
;
145
}
146
// Sanity check:
147
NS_ASSERT
(cur != 0);
// cur should be non-zero
148
NS_ASSERT
(cur->
tid
== tid);
// cur->tid should be tid
149
NS_ASSERT
(cur->
count
> 1);
// cur should be a merge
150
151
// link around tid, removing it from our list
152
found = (this->*Writer)(tag,
false
, cur, prevNext);
153
return
found;
154
155
}
156
157
bool
158
PacketTagList::Remove
(
Tag
& tag)
159
{
160
return
COWTraverse
(tag, &
PacketTagList::RemoveWriter
);
161
}
162
163
// COWWriter implementing Remove
164
bool
165
PacketTagList::RemoveWriter
(
Tag
& tag,
bool
preMerge,
166
struct
PacketTagList::TagData
* cur,
167
struct
PacketTagList::TagData
** prevNext)
168
{
169
NS_LOG_FUNCTION_NOARGS
();
170
171
// found tid
172
bool
found =
true
;
173
tag.
Deserialize
(
TagBuffer
(cur->
data
,
174
cur->
data
+
TagData::MAX_SIZE
));
175
*prevNext = cur->
next
;
// link around cur
176
177
if
(preMerge)
178
{
179
// found tid before first merge, so delete cur
180
delete
cur;
181
}
182
else
183
{
184
// cur is always a merge at this point
185
// unmerge cur, since we linked around it already
186
cur->
count
--;
187
if
(cur->
next
!= 0)
188
{
189
// there's a next, so make it a merge
190
cur->
next
->
count
++;
191
}
192
}
193
return
found;
194
}
195
196
bool
197
PacketTagList::Replace
(
Tag
& tag)
198
{
199
bool
found =
COWTraverse
(tag, &
PacketTagList::ReplaceWriter
);
200
if
(!found)
201
{
202
Add
(tag);
203
}
204
return
found;
205
}
206
207
// COWWriter implementing Replace
208
bool
209
PacketTagList::ReplaceWriter
(
Tag
& tag,
bool
preMerge,
210
struct
PacketTagList::TagData
* cur,
211
struct
PacketTagList::TagData
** prevNext)
212
{
213
NS_LOG_FUNCTION_NOARGS
();
214
215
// found tid
216
bool
found =
true
;
217
if
(preMerge)
218
{
219
// found tid before first merge, so just rewrite
220
tag.
Serialize
(
TagBuffer
(cur->
data
,
221
cur->
data
+ tag.
GetSerializedSize
()));
222
}
223
else
224
{
225
// cur is always a merge at this point
226
// need to copy, replace, and link past cur
227
cur->
count
--;
// unmerge cur
228
struct
TagData
* copy =
new
struct
TagData
();
229
copy->
tid
= tag.
GetInstanceTypeId
();
230
copy->
count
= 1;
231
tag.
Serialize
(
TagBuffer
(copy->
data
,
232
copy->
data
+ tag.
GetSerializedSize
()));
233
copy->
next
= cur->
next
;
// merge into tail
234
if
(copy->
next
!= 0)
235
{
236
copy->
next
->
count
++;
// mark new merge
237
}
238
*prevNext = copy;
// point prior list at copy
239
}
240
return
found;
241
}
242
243
void
244
PacketTagList::Add
(
const
Tag
&tag)
const
245
{
246
NS_LOG_FUNCTION
(
this
<< tag.
GetInstanceTypeId
());
247
// ensure this id was not yet added
248
for
(
struct
TagData
*cur =
m_next
; cur != 0; cur = cur->
next
)
249
{
250
NS_ASSERT
(cur->tid != tag.
GetInstanceTypeId
());
251
}
252
struct
TagData
* head =
new
struct
TagData
();
253
head->
count
= 1;
254
head->
next
= 0;
255
head->
tid
= tag.
GetInstanceTypeId
();
256
head->
next
=
m_next
;
257
NS_ASSERT
(tag.
GetSerializedSize
() <=
TagData::MAX_SIZE
);
258
tag.
Serialize
(
TagBuffer
(head->
data
, head->
data
+ tag.
GetSerializedSize
()));
259
260
const_cast<
PacketTagList
*
>
(
this
)->
m_next
= head;
261
}
262
263
bool
264
PacketTagList::Peek
(
Tag
&tag)
const
265
{
266
NS_LOG_FUNCTION
(
this
<< tag.
GetInstanceTypeId
());
267
TypeId
tid = tag.
GetInstanceTypeId
();
268
for
(
struct
TagData
*cur =
m_next
; cur != 0; cur = cur->
next
)
269
{
270
if
(cur->tid == tid)
271
{
272
/* found tag */
273
tag.
Deserialize
(
TagBuffer
(cur->data, cur->data +
TagData::MAX_SIZE
));
274
return
true
;
275
}
276
}
277
/* no tag found */
278
return
false
;
279
}
280
281
const
struct
PacketTagList::TagData
*
282
PacketTagList::Head
(
void
)
const
283
{
284
return
m_next
;
285
}
286
287
}
/* namespace ns3 */
288
ns3::PacketTagList::TagData::data
uint8_t data[MAX_SIZE]
Definition:
packet-tag-list.h:164
tag.h
ns3::PacketTagList::Remove
bool Remove(Tag &tag)
Definition:
packet-tag-list.cc:158
NS_LOG_FUNCTION
#define NS_LOG_FUNCTION(parameters)
Definition:
log.h:311
NS_LOG_COMPONENT_DEFINE
NS_LOG_COMPONENT_DEFINE("PacketTagList")
ns3::PacketTagList::TagData::next
struct TagData * next
Definition:
packet-tag-list.h:165
ns3::Tag::GetSerializedSize
virtual uint32_t GetSerializedSize(void) const =0
ns3::PacketTagList::Head
const struct PacketTagList::TagData * Head(void) const
Definition:
packet-tag-list.cc:282
ns3::PacketTagList
List of the packet tags stored in a packet.
Definition:
packet-tag-list.h:129
NS_ASSERT
#define NS_ASSERT(condition)
Definition:
assert.h:64
NS_LOG_INFO
#define NS_LOG_INFO(msg)
Definition:
log.h:264
NS_LOG_FUNCTION_NOARGS
#define NS_LOG_FUNCTION_NOARGS()
Definition:
log.h:275
ns3::PacketTagList::Peek
bool Peek(Tag &tag) const
Definition:
packet-tag-list.cc:264
tag-buffer.h
ns3::PacketTagList::Add
void Add(Tag const &tag) const
Definition:
packet-tag-list.cc:244
ns3::PacketTagList::ReplaceWriter
bool ReplaceWriter(Tag &tag, bool preMerge, struct TagData *cur, struct TagData **prevNext)
Definition:
packet-tag-list.cc:209
ns3::PacketTagList::TagData
Definition:
packet-tag-list.h:140
ns3::PacketTagList::Replace
bool Replace(Tag &tag)
Definition:
packet-tag-list.cc:197
ns3::PacketTagList::RemoveWriter
bool RemoveWriter(Tag &tag, bool preMerge, struct TagData *cur, struct TagData **prevNext)
Definition:
packet-tag-list.cc:165
packet-tag-list.h
Defines a linked list of Packet tags, including copy-on-write semantics.
ns3::Tag::Serialize
virtual void Serialize(TagBuffer i) const =0
ns3::Tag
tag a set of bytes in a packet
Definition:
tag.h:36
ns3::PacketTagList::COWTraverse
bool COWTraverse(Tag &tag, PacketTagList::COWWriter Writer)
Definition:
packet-tag-list.cc:38
ns3::PacketTagList::m_next
struct TagData * m_next
Definition:
packet-tag-list.h:292
ns3::Tag::Deserialize
virtual void Deserialize(TagBuffer i)=0
ns3::PacketTagList::TagData::MAX_SIZE
Definition:
packet-tag-list.h:161
ns3::TagBuffer
read and write tag data
Definition:
tag-buffer.h:51
ns3::ObjectBase::GetInstanceTypeId
virtual TypeId GetInstanceTypeId(void) const =0
ns3::PacketTagList::TagData::tid
TypeId tid
Definition:
packet-tag-list.h:166
ns3::PacketTagList::COWWriter
bool(PacketTagList::* COWWriter)(Tag &tag, bool preMerge, struct TagData *cur, struct TagData **prevNext)
Definition:
packet-tag-list.h:253
ns3::TypeId
a unique identifier for an interface.
Definition:
type-id.h:49
ns3::PacketTagList::TagData::count
uint32_t count
Definition:
packet-tag-list.h:167
src
network
model
packet-tag-list.cc
Generated on Sun Apr 20 2014 11:14:59 for ns-3 by
1.8.6