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
byte-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) 2008 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 "
byte-tag-list.h
"
21
#include "ns3/log.h"
22
#include <vector>
23
#include <cstring>
24
25
NS_LOG_COMPONENT_DEFINE
(
"ByteTagList"
);
26
27
#define USE_FREE_LIST 1
28
#define FREE_LIST_SIZE 1000
29
#define OFFSET_MAX (2147483647)
30
31
namespace
ns3 {
32
33
struct
ByteTagListData
{
34
uint32_t
size
;
35
uint32_t
count
;
36
uint32_t
dirty
;
37
uint8_t
data
[4];
38
};
39
40
#ifdef USE_FREE_LIST
41
static
class
ByteTagListDataFreeList
:
public
std::vector<struct ByteTagListData *>
42
{
43
public
:
44
~ByteTagListDataFreeList
();
45
}
g_freeList
;
46
static
uint32_t
g_maxSize
= 0;
47
48
ByteTagListDataFreeList::~ByteTagListDataFreeList
()
49
{
50
NS_LOG_FUNCTION
(
this
);
51
for
(ByteTagListDataFreeList::iterator i = begin ();
52
i != end (); i++)
53
{
54
uint8_t *buffer = (uint8_t *)(*i);
55
delete
[] buffer;
56
}
57
}
58
#endif
/* USE_FREE_LIST */
59
60
ByteTagList::Iterator::Item::Item
(
TagBuffer
buf_)
61
: buf (buf_)
62
{
63
NS_LOG_FUNCTION
(
this
<< &buf_);
64
}
65
66
bool
67
ByteTagList::Iterator::HasNext
(
void
)
const
68
{
69
NS_LOG_FUNCTION
(
this
);
70
return
m_current
<
m_end
;
71
}
72
struct
ByteTagList::Iterator::Item
73
ByteTagList
::
Iterator::Next
(void)
74
{
75
NS_ASSERT
(
HasNext
());
76
struct
Item
item =
Item
(
TagBuffer
(
m_current
+16,
m_end
));
77
item.
tid
.
SetUid
(
m_nextTid
);
78
item.
size
=
m_nextSize
;
79
item.
start
= std::max (
m_nextStart
,
m_offsetStart
);
80
item.
end
= std::min (
m_nextEnd
,
m_offsetEnd
);
81
m_current
+= 4 + 4 + 4 + 4 + item.
size
;
82
item.
buf
.
TrimAtEnd
(
m_end
-
m_current
);
83
PrepareForNext
();
84
return
item;
85
}
86
void
87
ByteTagList::Iterator::PrepareForNext
(
void
)
88
{
89
NS_LOG_FUNCTION
(
this
);
90
while
(
m_current
<
m_end
)
91
{
92
TagBuffer
buf =
TagBuffer
(
m_current
,
m_end
);
93
m_nextTid
= buf.
ReadU32
();
94
m_nextSize
= buf.
ReadU32
();
95
m_nextStart
= buf.
ReadU32
();
96
m_nextEnd
= buf.
ReadU32
();
97
if
(
m_nextStart
>=
m_offsetEnd
||
m_nextEnd
<=
m_offsetStart
)
98
{
99
m_current
+= 4 + 4 + 4 + 4 +
m_nextSize
;
100
}
101
else
102
{
103
break
;
104
}
105
}
106
}
107
ByteTagList::Iterator::Iterator
(uint8_t *
start
, uint8_t *end, int32_t offsetStart, int32_t offsetEnd)
108
:
m_current
(start),
109
m_end
(end),
110
m_offsetStart
(offsetStart),
111
m_offsetEnd
(offsetEnd)
112
{
113
NS_LOG_FUNCTION
(
this
<< &start << &end << offsetStart << offsetEnd);
114
PrepareForNext
();
115
}
116
117
uint32_t
118
ByteTagList::Iterator::GetOffsetStart
(
void
)
const
119
{
120
NS_LOG_FUNCTION
(
this
);
121
return
m_offsetStart;
122
}
123
124
125
ByteTagList::ByteTagList
()
126
:
m_used
(0),
127
m_data
(0)
128
{
129
NS_LOG_FUNCTION
(
this
);
130
}
131
ByteTagList::ByteTagList
(
const
ByteTagList
&o)
132
: m_used (o.m_used),
133
m_data (o.m_data)
134
{
135
NS_LOG_FUNCTION
(
this
<< &o);
136
if
(
m_data
!= 0)
137
{
138
m_data
->
count
++;
139
}
140
}
141
ByteTagList
&
142
ByteTagList::operator =
(
const
ByteTagList
&o)
143
{
144
if
(
this
== &o)
145
{
146
return
*
this
;
147
}
148
149
Deallocate
(
m_data
);
150
m_data
= o.
m_data
;
151
m_used
= o.
m_used
;
152
if
(
m_data
!= 0)
153
{
154
m_data
->
count
++;
155
}
156
return
*
this
;
157
}
158
ByteTagList::~ByteTagList
()
159
{
160
NS_LOG_FUNCTION
(
this
);
161
Deallocate
(
m_data
);
162
m_data
= 0;
163
m_used
= 0;
164
}
165
166
TagBuffer
167
ByteTagList::Add
(
TypeId
tid, uint32_t bufferSize, int32_t
start
, int32_t end)
168
{
169
NS_LOG_FUNCTION
(
this
<< tid << bufferSize << start << end);
170
uint32_t spaceNeeded =
m_used
+ bufferSize + 4 + 4 + 4 + 4;
171
NS_ASSERT
(
m_used
<= spaceNeeded);
172
if
(
m_data
== 0)
173
{
174
m_data
=
Allocate
(spaceNeeded);
175
m_used
= 0;
176
}
177
else
if
(
m_data
->
size
< spaceNeeded ||
178
(
m_data
->
count
!= 1 &&
m_data
->
dirty
!=
m_used
))
179
{
180
struct
ByteTagListData
*newData =
Allocate
(spaceNeeded);
181
std::memcpy (&newData->
data
, &
m_data
->
data
,
m_used
);
182
Deallocate
(
m_data
);
183
m_data
= newData;
184
}
185
TagBuffer
tag =
TagBuffer
(&
m_data
->
data
[
m_used
],
186
&
m_data
->
data
[spaceNeeded]);
187
tag.
WriteU32
(tid.
GetUid
());
188
tag.
WriteU32
(bufferSize);
189
tag.
WriteU32
(start);
190
tag.
WriteU32
(end);
191
m_used
= spaceNeeded;
192
m_data
->
dirty
=
m_used
;
193
return
tag;
194
}
195
196
void
197
ByteTagList::Add
(
const
ByteTagList
&o)
198
{
199
NS_LOG_FUNCTION
(
this
<< &o);
200
ByteTagList::Iterator
i = o.
BeginAll
();
201
while
(i.
HasNext
())
202
{
203
ByteTagList::Iterator::Item
item = i.
Next
();
204
TagBuffer
buf =
Add
(item.
tid
, item.
size
, item.
start
, item.
end
);
205
buf.
CopyFrom
(item.
buf
);
206
}
207
}
208
209
void
210
ByteTagList::RemoveAll
(
void
)
211
{
212
NS_LOG_FUNCTION
(
this
);
213
Deallocate
(
m_data
);
214
m_data
= 0;
215
m_used
= 0;
216
}
217
218
ByteTagList::Iterator
219
ByteTagList::BeginAll
(
void
)
const
220
{
221
NS_LOG_FUNCTION
(
this
);
222
// I am not totally sure but I might need to use
223
// INT32_MIN instead of zero below.
224
return
Begin
(0,
OFFSET_MAX
);
225
}
226
227
ByteTagList::Iterator
228
ByteTagList::Begin
(int32_t offsetStart, int32_t offsetEnd)
const
229
{
230
NS_LOG_FUNCTION
(
this
<< offsetStart << offsetEnd);
231
if
(
m_data
== 0)
232
{
233
return
Iterator
(0, 0, offsetStart, offsetEnd);
234
}
235
else
236
{
237
return
Iterator
(
m_data
->
data
, &
m_data
->
data
[
m_used
], offsetStart, offsetEnd);
238
}
239
}
240
241
bool
242
ByteTagList::IsDirtyAtEnd
(int32_t appendOffset)
243
{
244
NS_LOG_FUNCTION
(
this
<< appendOffset);
245
ByteTagList::Iterator
i =
BeginAll
();
246
while
(i.
HasNext
())
247
{
248
ByteTagList::Iterator::Item
item = i.
Next
();
249
if
(item.
end
> appendOffset)
250
{
251
return
true
;
252
}
253
}
254
return
false
;
255
}
256
257
bool
258
ByteTagList::IsDirtyAtStart
(int32_t prependOffset)
259
{
260
NS_LOG_FUNCTION
(
this
<< prependOffset);
261
ByteTagList::Iterator
i =
BeginAll
();
262
while
(i.
HasNext
())
263
{
264
ByteTagList::Iterator::Item
item = i.
Next
();
265
if
(item.
start
< prependOffset)
266
{
267
return
true
;
268
}
269
}
270
return
false
;
271
}
272
273
void
274
ByteTagList::AddAtEnd
(int32_t adjustment, int32_t appendOffset)
275
{
276
NS_LOG_FUNCTION
(
this
<< adjustment << appendOffset);
277
if
(adjustment == 0 && !
IsDirtyAtEnd
(appendOffset))
278
{
279
return
;
280
}
281
ByteTagList
list
;
282
ByteTagList::Iterator
i =
BeginAll
();
283
while
(i.
HasNext
())
284
{
285
ByteTagList::Iterator::Item
item = i.
Next
();
286
item.
start
+= adjustment;
287
item.
end
+= adjustment;
288
289
if
(item.
start
>= appendOffset)
290
{
291
continue
;
292
}
293
else
if
(item.
start
< appendOffset && item.
end
> appendOffset)
294
{
295
item.
end
= appendOffset;
296
}
297
else
298
{
299
// nothing to do.
300
}
301
TagBuffer
buf = list.
Add
(item.
tid
, item.
size
, item.
start
, item.
end
);
302
buf.
CopyFrom
(item.
buf
);
303
}
304
*
this
=
list
;
305
}
306
307
void
308
ByteTagList::AddAtStart
(int32_t adjustment, int32_t prependOffset)
309
{
310
NS_LOG_FUNCTION
(
this
<< adjustment << prependOffset);
311
if
(adjustment == 0 && !
IsDirtyAtStart
(prependOffset))
312
{
313
return
;
314
}
315
ByteTagList
list
;
316
ByteTagList::Iterator
i =
BeginAll
();
317
while
(i.
HasNext
())
318
{
319
ByteTagList::Iterator::Item
item = i.
Next
();
320
item.
start
+= adjustment;
321
item.
end
+= adjustment;
322
323
if
(item.
end
<= prependOffset)
324
{
325
continue
;
326
}
327
else
if
(item.
end
> prependOffset && item.
start
< prependOffset)
328
{
329
item.
start
= prependOffset;
330
}
331
else
332
{
333
// nothing to do.
334
}
335
TagBuffer
buf = list.
Add
(item.
tid
, item.
size
, item.
start
, item.
end
);
336
buf.
CopyFrom
(item.
buf
);
337
}
338
*
this
=
list
;
339
}
340
341
#ifdef USE_FREE_LIST
342
343
struct
ByteTagListData
*
344
ByteTagList::Allocate
(uint32_t size)
345
{
346
NS_LOG_FUNCTION
(
this
<< size);
347
while
(!
g_freeList
.empty ())
348
{
349
struct
ByteTagListData
*
data
=
g_freeList
.back ();
350
g_freeList
.pop_back ();
351
NS_ASSERT
(data != 0);
352
if
(data->
size
>= size)
353
{
354
data->
count
= 1;
355
data->
dirty
= 0;
356
return
data
;
357
}
358
uint8_t *buffer = (uint8_t *)data;
359
delete
[] buffer;
360
}
361
uint8_t *buffer =
new
uint8_t [std::max (size,
g_maxSize
) +
sizeof
(
struct
ByteTagListData
) - 4];
362
struct
ByteTagListData
*
data
= (
struct
ByteTagListData
*)buffer;
363
data->
count
= 1;
364
data->
size
= size;
365
data->
dirty
= 0;
366
return
data
;
367
}
368
369
void
370
ByteTagList::Deallocate
(
struct
ByteTagListData
*
data
)
371
{
372
NS_LOG_FUNCTION
(
this
<< data);
373
if
(data == 0)
374
{
375
return
;
376
}
377
g_maxSize
= std::max (
g_maxSize
, data->
size
);
378
data->
count
--;
379
if
(data->
count
== 0)
380
{
381
if
(
g_freeList
.size () >
FREE_LIST_SIZE
||
382
data->
size
<
g_maxSize
)
383
{
384
uint8_t *buffer = (uint8_t *)data;
385
delete
[] buffer;
386
}
387
else
388
{
389
g_freeList
.push_back (data);
390
}
391
}
392
}
393
394
#else
/* USE_FREE_LIST */
395
396
struct
ByteTagListData
*
397
ByteTagList::Allocate
(uint32_t size)
398
{
399
NS_LOG_FUNCTION
(
this
<< size);
400
uint8_t *buffer =
new
uint8_t [size +
sizeof
(
struct
ByteTagListData
) - 4];
401
struct
ByteTagListData
*
data
= (
struct
ByteTagListData
*)buffer;
402
data->
count
= 1;
403
data->
size
= size;
404
data->
dirty
= 0;
405
return
data
;
406
}
407
408
void
409
ByteTagList::Deallocate
(
struct
ByteTagListData *
data
)
410
{
411
NS_LOG_FUNCTION
(
this
<< data);
412
if
(data == 0)
413
{
414
return
;
415
}
416
data->count--;
417
if
(data->count == 0)
418
{
419
uint8_t *buffer = (uint8_t *)data;
420
delete
[] buffer;
421
}
422
}
423
424
#endif
/* USE_FREE_LIST */
425
426
427
}
// namespace ns3
src
network
model
byte-tag-list.cc
Generated on Fri Dec 21 2012 19:00:43 for ns-3 by
1.8.1.2