A Discrete-Event Network Simulator
API
pending-data.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2//
3// Copyright (c) 2006 Georgia Tech Research Corporation
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: Rajib Bhattacharjea<raj.b@gatech.edu>
19//
20
21
22// This is a port of Data PDU Headers from:
23// Georgia Tech Network Simulator
24// George F. Riley. Georgia Tech, Spring 2002
25
26#include <iostream>
27#include <algorithm>
28
29#include <cstring>
30
31#include "ns3/fatal-error.h"
32#include "ns3/log.h"
33
34#include "pending-data.h"
35
36
37namespace ns3
38{
39
40NS_LOG_COMPONENT_DEFINE ("PendingData");
41
42PendingData::PendingData () : size (0), data (0),
43 msgSize (0), responseSize (0)
44{
45 NS_LOG_FUNCTION (this);
46}
47
49 : size (s), data (0), msgSize (msg), responseSize (resp)
50{
51 NS_LOG_FUNCTION (this << s);
52 if (d)
53 {
54 data.push_back (Create<Packet> (d, size));
55 }
56}
57
58PendingData::PendingData(const std::string& s)
59 : size (s.length () + 1), data (0),
60 msgSize (0), responseSize (0)
61{
62 NS_LOG_FUNCTION (this << s.length () + 1);
63 data.push_back (Create<Packet> ((uint8_t*)s.c_str (), size));
64}
65
67 : size (c.Size ()), data (c.data),
68 msgSize (c.msgSize), responseSize (c.responseSize)
69{
70 NS_LOG_FUNCTION (this << c.Size ());
71}
72
74{
75 NS_LOG_FUNCTION (this);
76}
77
79{
80 NS_LOG_FUNCTION (this);
81 return new PendingData (*this);
82};
83
85{ // Copy, but with new size (assumes no associated data);
86 NS_LOG_FUNCTION (this << s);
87 return new PendingData (s, 0, msgSize, responseSize);
88}
89
91{ // Copy, but with new size (assumes no associated data);
92 NS_LOG_FUNCTION (this << s);
93 return new PendingData (s, d, msgSize, responseSize);
94}
95
97{ // Remove all pending data
98 NS_LOG_FUNCTION (this);
99 data.clear ();
100 size = 0;
101}
102
103void PendingData::Add (uint32_t s, const uint8_t* d)
104{
105 NS_LOG_FUNCTION (this << s);
106 data.push_back (Create<Packet> (d,s));
107 size += s;
108}
109
111{
112 NS_LOG_FUNCTION (this);
113 data.push_back (p);
114 size += p->GetSize ();
115}
116
118{
119 NS_LOG_FUNCTION (this << seqFront << seqOffset);
120 uint32_t o1 = OffsetFromSeq (seqFront, seqOffset); // Offset to start of unused data
121 return SizeFromOffset (o1); // Amount of data after offset
122}
123
125{ // Find out how much data is available from offset
126 NS_LOG_FUNCTION (this << offset);
128 if (offset > size) return 0; // No data at requested offset
129 return size - offset; // Available data after offset
130}
131
133{ // f is the first sequence number in this data, o is offset sequence
134 NS_LOG_FUNCTION (this << seqFront << seqOffset);
135 if (seqOffset < seqFront)
136 {
137 return 0; // HuH? Shouldn't happen
138 }
139 return seqOffset - seqFront;
140}
141
143{ // Make a copy of data from starting position "o" for "s" bytes
144 // Return NULL if results in zero length data
145 NS_LOG_FUNCTION (this << s << o);
146 uint32_t s1 = std::min (s, SizeFromOffset (o)); // Insure not beyond end of data
147 if (s1 == 0)
148 {
149 return Create<Packet> (); // No data requested
150 }
151 if (data.size () != 0)
152 { // Actual data exists, make copy and return it
153 uint32_t count = 0;
154 std::vector<Ptr<Packet> >::size_type begin = 0;
155 bool beginFound = false;
156 std::vector<Ptr<Packet> >::size_type end = 0;
157 Ptr<Packet> outPacket;
158 Ptr<Packet> endFragment;
159 for (std::vector<Ptr<Packet> >::size_type i=0; i<data.size (); ++i)
160 {
161 count+=data[i]->GetSize ();
162 if (!beginFound)
163 {
164 if (count > o)
165 {
166 if (count >= o + s1) //then just copy within this packet
167 {
168 Ptr<Packet> toFragment = data[i];
169 uint32_t packetStart = count - toFragment->GetSize ();
170 uint32_t packetOffset = o - packetStart;
171 outPacket = toFragment->CreateFragment (packetOffset, s1);
172 return outPacket;
173 }
174 begin = i;
175 beginFound = true;
176 Ptr<Packet> toFragment = data[begin];
177 uint32_t packetStart = count - toFragment->GetSize ();
178 uint32_t packetOffset = o - packetStart;
179 uint32_t fragmentLength = count - o;
180 outPacket = toFragment->CreateFragment (packetOffset, fragmentLength);
181 }
182 }
183 else
184 {
185 if (count >= o + s1)
186 {
187 end = i;
188 Ptr<Packet> toFragment = data[end];
189 uint32_t packetStart = count - toFragment->GetSize ();
190 uint32_t fragmentLength = o + s1 - packetStart;
191 endFragment = toFragment->CreateFragment (0, fragmentLength);
192 break;
193 }
194 }
195 }
196 for (std::vector<Ptr<Packet> >::size_type i=begin+1; i<end; ++i)
197 {
198 outPacket->AddAtEnd (data[i]);
199 }
200 if (endFragment)
201 {
202 outPacket->AddAtEnd (endFragment);
203 }
204 NS_ASSERT (outPacket->GetSize () == s1);
205 return outPacket;
206 }
207 else
208 { // No actual data, just return dummy-data packet of correct size
209 return Create<Packet> (s1);
210 }
211}
212
214{
215 NS_LOG_FUNCTION (this << s << f << o);
216 return CopyFromOffset (s, OffsetFromSeq (f,o));
217}
218
221{
222 NS_LOG_FUNCTION (this << seqFront << seqOffset);
223 uint32_t count = OffsetFromSeq (seqFront, seqOffset);
224 NS_ASSERT_MSG (count <= size, "Trying to remove more data than in the buffer");
225 if (count == size)
226 {
227 Clear ();
228 return size;
229 }
230 // Remove whole packets, if possible, from the front of the data
231 // Do not perform buffer manipulations within packet; if a whole packet
232 // cannot be removed, leave it alone
233 std::vector<Ptr<Packet> >::iterator endI = data.begin ();
234 uint32_t current = 0;
235 // Any packet whose data has been completely acked can be removed
236 for (std::vector<Ptr<Packet> >::iterator dataI = data.begin (); dataI < data.end (); dataI++)
237 {
238 if (current + (*dataI)->GetSize () > count)
239 {
240 break;
241 }
242 current += (*dataI)->GetSize ();
243 ++endI;
244 }
245 data.erase (data.begin (), endI);
246 size -= current;
247 return current;
248}
249
250} //namespace ns3
#define min(a, b)
Definition: 80211b.c:42
double f(double x, void *params)
Definition: 80211b.c:70
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
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:227
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
class for managing I/O between applications and TCP
Definition: pending-data.h:41
virtual void Add(uint32_t s, const uint8_t *d=0)
Add some data to end.
uint32_t responseSize
Size of response requested.
Definition: pending-data.h:179
uint32_t msgSize
Total size of message.
Definition: pending-data.h:178
virtual ~PendingData()
Definition: pending-data.cc:73
virtual void Clear()
Remove all associated data.
Definition: pending-data.cc:96
uint32_t Size() const
Returns the size of the pending data.
Definition: pending-data.h:69
virtual uint32_t SizeFromOffset(uint32_t offset)
uint32_t size
Number of data bytes.
Definition: pending-data.h:175
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:78
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:84
std::vector< Ptr< Packet > > data
Corresponding data (may be null)
Definition: pending-data.h:176
PendingData * CopySD(uint32_t s, uint8_t *d)
Create a copy of self with new size, new data.
Definition: pending-data.cc:90
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:67
#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:88
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#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]