A Discrete-Event Network Simulator
API
pending-data.cc
Go to the documentation of this file.
1//
2// Copyright (c) 2006 Georgia Tech Research Corporation
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License version 2 as
6// published by the Free Software Foundation;
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16//
17// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
18//
19
20// This is a port of Data PDU Headers from:
21// Georgia Tech Network Simulator
22// George F. Riley. Georgia Tech, Spring 2002
23
24#include "pending-data.h"
25
26#include "ns3/fatal-error.h"
27#include "ns3/log.h"
28
29#include <algorithm>
30#include <cstring>
31#include <iostream>
32
33namespace ns3
34{
35
36NS_LOG_COMPONENT_DEFINE("PendingData");
37
39 : size(0),
40 data(0),
41 msgSize(0),
42 responseSize(0)
43{
44 NS_LOG_FUNCTION(this);
45}
46
48 : size(s),
49 data(0),
50 msgSize(msg),
51 responseSize(resp)
52{
53 NS_LOG_FUNCTION(this << s);
54 if (d)
55 {
56 data.push_back(Create<Packet>(d, size));
57 }
58}
59
60PendingData::PendingData(const std::string& s)
61 : size(s.length() + 1),
62 data(0),
63 msgSize(0),
64 responseSize(0)
65{
66 NS_LOG_FUNCTION(this << s.length() + 1);
67 data.push_back(Create<Packet>((uint8_t*)s.c_str(), size));
68}
69
71 : size(c.Size()),
72 data(c.data),
73 msgSize(c.msgSize),
74 responseSize(c.responseSize)
75{
76 NS_LOG_FUNCTION(this << c.Size());
77}
78
80{
81 NS_LOG_FUNCTION(this);
82}
83
86{
87 NS_LOG_FUNCTION(this);
88 return new PendingData(*this);
89};
90
93{ // Copy, but with new size (assumes no associated data);
94 NS_LOG_FUNCTION(this << s);
95 return new PendingData(s, nullptr, msgSize, responseSize);
96}
97
100{ // Copy, but with new size (assumes no associated data);
101 NS_LOG_FUNCTION(this << s);
102 return new PendingData(s, d, msgSize, responseSize);
103}
104
105void
107{ // Remove all pending data
108 NS_LOG_FUNCTION(this);
109 data.clear();
110 size = 0;
111}
112
113void
114PendingData::Add(uint32_t s, const uint8_t* d)
115{
116 NS_LOG_FUNCTION(this << s);
117 data.push_back(Create<Packet>(d, s));
118 size += s;
119}
120
121void
123{
124 NS_LOG_FUNCTION(this);
125 data.push_back(p);
126 size += p->GetSize();
127}
128
131{
132 NS_LOG_FUNCTION(this << seqFront << seqOffset);
133 uint32_t o1 = OffsetFromSeq(seqFront, seqOffset); // Offset to start of unused data
134 return SizeFromOffset(o1); // Amount of data after offset
135}
136
139{ // Find out how much data is available from offset
140 NS_LOG_FUNCTION(this << offset);
142 if (offset > size)
143 {
144 return 0; // No data at requested offset
145 }
146 return size - offset; // Available data after offset
147}
148
151{ // f is the first sequence number in this data, o is offset sequence
152 NS_LOG_FUNCTION(this << seqFront << seqOffset);
153 if (seqOffset < seqFront)
154 {
155 return 0; // HuH? Shouldn't happen
156 }
157 return seqOffset - seqFront;
158}
159
162{ // Make a copy of data from starting position "o" for "s" bytes
163 // Return NULL if results in zero length data
164 NS_LOG_FUNCTION(this << s << o);
165 uint32_t s1 = std::min(s, SizeFromOffset(o)); // Insure not beyond end of data
166 if (s1 == 0)
167 {
168 return Create<Packet>(); // No data requested
169 }
170 if (data.size() != 0)
171 { // Actual data exists, make copy and return it
172 uint32_t count = 0;
173 std::vector<Ptr<Packet>>::size_type begin = 0;
174 bool beginFound = false;
175 std::vector<Ptr<Packet>>::size_type end = 0;
176 Ptr<Packet> outPacket;
177 Ptr<Packet> endFragment;
178 for (std::vector<Ptr<Packet>>::size_type i = 0; i < data.size(); ++i)
179 {
180 count += data[i]->GetSize();
181 if (!beginFound)
182 {
183 if (count > o)
184 {
185 if (count >= o + s1) // then just copy within this packet
186 {
187 Ptr<Packet> toFragment = data[i];
188 uint32_t packetStart = count - toFragment->GetSize();
189 uint32_t packetOffset = o - packetStart;
190 outPacket = toFragment->CreateFragment(packetOffset, s1);
191 return outPacket;
192 }
193 begin = i;
194 beginFound = true;
195 Ptr<Packet> toFragment = data[begin];
196 uint32_t packetStart = count - toFragment->GetSize();
197 uint32_t packetOffset = o - packetStart;
198 uint32_t fragmentLength = count - o;
199 outPacket = toFragment->CreateFragment(packetOffset, fragmentLength);
200 }
201 }
202 else
203 {
204 if (count >= o + s1)
205 {
206 end = i;
207 Ptr<Packet> toFragment = data[end];
208 uint32_t packetStart = count - toFragment->GetSize();
209 uint32_t fragmentLength = o + s1 - packetStart;
210 endFragment = toFragment->CreateFragment(0, fragmentLength);
211 break;
212 }
213 }
214 }
215 for (std::vector<Ptr<Packet>>::size_type i = begin + 1; i < end; ++i)
216 {
217 outPacket->AddAtEnd(data[i]);
218 }
219 if (endFragment)
220 {
221 outPacket->AddAtEnd(endFragment);
222 }
223 NS_ASSERT(outPacket->GetSize() == s1);
224 return outPacket;
225 }
226 else
227 { // No actual data, just return dummy-data packet of correct size
228 return Create<Packet>(s1);
229 }
230}
231
234{
235 NS_LOG_FUNCTION(this << s << f << o);
236 return CopyFromOffset(s, OffsetFromSeq(f, o));
237}
238
241{
242 NS_LOG_FUNCTION(this << seqFront << seqOffset);
243 uint32_t count = OffsetFromSeq(seqFront, seqOffset);
244 NS_ASSERT_MSG(count <= size, "Trying to remove more data than in the buffer");
245 if (count == size)
246 {
247 Clear();
248 return size;
249 }
250 // Remove whole packets, if possible, from the front of the data
251 // Do not perform buffer manipulations within packet; if a whole packet
252 // cannot be removed, leave it alone
253 std::vector<Ptr<Packet>>::iterator endI = data.begin();
254 uint32_t current = 0;
255 // Any packet whose data has been completely acked can be removed
256 for (std::vector<Ptr<Packet>>::iterator dataI = data.begin(); dataI < data.end(); dataI++)
257 {
258 if (current + (*dataI)->GetSize() > count)
259 {
260 break;
261 }
262 current += (*dataI)->GetSize();
263 ++endI;
264 }
265 data.erase(data.begin(), endI);
266 size -= current;
267 return current;
268}
269
270} // namespace ns3
#define min(a, b)
Definition: 80211b.c:42
double f(double x, void *params)
Definition: 80211b.c:71
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:354
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:238
class for managing I/O between applications and TCP
Definition: pending-data.h:42
uint32_t responseSize
Size of response requested.
Definition: pending-data.h:189
uint32_t msgSize
Total size of message.
Definition: pending-data.h:188
virtual ~PendingData()
Definition: pending-data.cc:79
virtual void Clear()
Remove all associated data.
uint32_t Size() const
Returns the size of the pending data.
Definition: pending-data.h:70
virtual uint32_t SizeFromOffset(uint32_t offset)
uint32_t size
Number of data bytes.
Definition: pending-data.h:185
virtual uint32_t RemoveToSeq(const SequenceNumber32 &seqFront, const SequenceNumber32 &seqOffset)
Permits object to clear any pending data between seqFront and seqOffset - 1).
virtual uint32_t SizeFromSeq(const SequenceNumber32 &seqFront, const SequenceNumber32 &seqOffset)
This method returns the number of bytes in the PendingData buffer beyond the sequence number specifie...
PendingData * Copy() const
Create a copy of self.
Definition: pending-data.cc:85
virtual Ptr< Packet > CopyFromOffset(uint32_t s, uint32_t o)
Copy data starting from a give offset.
PendingData * CopyS(uint32_t s)
Create a copy of self with new size.
Definition: pending-data.cc:92
std::vector< Ptr< Packet > > data
Corresponding data (may be null)
Definition: pending-data.h:186
virtual void Add(uint32_t s, const uint8_t *d=nullptr)
Add some data to end.
PendingData * CopySD(uint32_t s, uint8_t *d)
Create a copy of self with new size, new data.
Definition: pending-data.cc:99
virtual Ptr< Packet > CopyFromSeq(uint32_t s, const SequenceNumber32 &f, const SequenceNumber32 &o)
Copy data starting from a give offset.
virtual uint32_t OffsetFromSeq(const SequenceNumber32 &seqFront, const SequenceNumber32 &seqOffset)
Subtracts seqFront from seqOffset after enforcing seqFront is less than seqOffset.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint8_t data[writeSize]