Tcp tx buffer (pendingdata) uses Ptr<Packet> internally; tagging should work

This commit is contained in:
Raj Bhattacharjea
2008-06-05 16:49:59 -04:00
parent de2475ddc3
commit 60c2ddafa8
2 changed files with 69 additions and 72 deletions

View File

@@ -29,7 +29,6 @@
#include <string.h>
#include "pending-data.h"
#include "ns3/packet.h"
#include "ns3/fatal-error.h"
namespace ns3
{
@@ -41,37 +40,28 @@ PendingData::PendingData () : size (0), data (0),
PendingData::PendingData (uint32_t s, uint8_t* d, uint32_t msg, uint32_t resp)
: size (s), data (0), msgSize (msg), responseSize (resp)
{ // Make a copy of the data
{
if (d)
{
data = new uint8_t[s];
memcpy (data, d, s);
data.push_back (Create<Packet> (d, size));
}
}
PendingData::PendingData(const std::string& s)
: size (s.length () + 1), data ((uint8_t*)strdup(s.c_str ())),
: size (s.length () + 1), data (0),
msgSize (0), responseSize (0)
{
data.push_back (Create<Packet> ((uint8_t*)s.c_str(), size));
}
PendingData::PendingData(const PendingData& c)
: size (c.Size ()), data (0),
: size (c.Size ()), data (c.data),
msgSize (c.msgSize), responseSize (c.responseSize)
{ // Copy constructor
if (c.Contents())
{ // Has data
data = new uint8_t[Size ()];
memcpy(data, c.Contents (), Size ());
}
{
}
PendingData::~PendingData()
{ // destructor
if (data)
{
delete [] data;
}
{
}
PendingData* PendingData::Copy () const
@@ -91,64 +81,23 @@ PendingData* PendingData::CopySD (uint32_t s, uint8_t* d)
void PendingData::Clear ()
{ // Remove all pending data
if (data)
{
delete [] data; // Free memory if used
}
data = 0;
data.clear();
size = 0;
}
void PendingData::Add (uint32_t s, const uint8_t* d)
{
if (data)
{ // PendingData exists, realloc and copy
uint8_t* n = new uint8_t[Size () + s];
memcpy(n, data, Size ());
if (d)
{ // New data specified
memcpy(n + Size (), d, s); // Append the new data
}
else
{
memset(n + Size (), 0, s); // Apend zeros
}
delete [] data; // Delete the old data
data = n; // Points to new one
}
if (d == 0)
{
data.push_back(Create<Packet> (d,s));
}
else
{ // No existing data, see if new data
if (d)
{
data = new uint8_t[s];
memcpy (data, d, s);
}
}
{
data.push_back(Create<Packet> (s));
}
size += s;
}
void PendingData::Remove(uint32_t s)
{
uint32_t r = s > Size () ? Size () : s;
size -= r; // Reduce size from current
if (data)
{ // data actually exists, realloc and copy
if (size)
{
uint8_t* d = new uint8_t[Size ()];
memcpy(d, data, Size ());
delete [] data;
data = d;
}
else
{ // Zero size, so don't need the data anymore
delete [] data;
data = NULL;
}
}
}
uint32_t PendingData::SizeFromSeq (const SequenceNumber& f, const SequenceNumber& o)
{
uint32_t o1 = OffsetFromSeq (f,o); // Offset to start of unused data
@@ -178,12 +127,61 @@ Ptr<Packet> PendingData::CopyFromOffset (uint32_t s, uint32_t o)
{
return 0; // No data requested
}
if (data)
if (data.size() != 0)
{ // Actual data exists, make copy and return it
return Create<Packet> (data+o, s1);
uint32_t count = 0;
std::vector<Ptr<Packet> >::size_type begin = 0;
bool beginFound = false;
std::vector<Ptr<Packet> >::size_type end = 0;
Ptr<Packet> outPacket;
Ptr<Packet> endFragment;
for (std::vector<Ptr<Packet> >::size_type i=0;i<data.size();++i)
{
count+=data[i]->GetSize();
if (!beginFound)
{
if (count > o)
{
if (count >= o + s1) //then just copy within this packet
{
Ptr<Packet> toFragment = data[i];
uint32_t packetStart = count - toFragment->GetSize();
uint32_t packetOffset = o - packetStart;
outPacket = toFragment->CreateFragment (packetOffset, s1);
return outPacket;
}
begin = i;
beginFound = true;
Ptr<Packet> toFragment = data[begin];
uint32_t packetStart = count - toFragment->GetSize();
uint32_t packetOffset = o - packetStart;
uint32_t fragmentLength = count - o;
outPacket = toFragment->CreateFragment (packetOffset, fragmentLength);
}
}
else
{
if (count > o + s1)
{
end = i;
Ptr<Packet> toFragment = data[end];
uint32_t packetStart = count - toFragment->GetSize();
uint32_t fragmentLength = o + s1 - packetStart;
endFragment = toFragment->CreateFragment(0, fragmentLength);
break;
}
}
}
for (std::vector<Ptr<Packet> >::size_type i=begin+1;i<end;++i)
{
outPacket->AddAtEnd (data[i]);
}
outPacket->AddAtEnd(endFragment);
NS_ASSERT(outPacket->GetSize() == s);
return outPacket;
}
else
{ // No actual data, just return non-data pdu of correct size
{ // No actual data, just return dummy-data packet of correct size
return Create<Packet> (s1);
}
}

View File

@@ -24,6 +24,7 @@
#ifndef __datapdu_h__
#define __datapdu_h__
#include "ns3/packet.h"
#include "pending-data.h"
#include "sequence-number.h"
@@ -47,7 +48,6 @@ public:
uint8_t* Construct (uint8_t*, uint32_t&); // Construct from buffer
virtual void Clear ();// Remove all associated data
virtual void Add (uint32_t s, const uint8_t* d = 0);// Add some data to end
virtual void Remove (uint32_t); // Remove data from head
// Inquire available data from (f,o) sequence pair
virtual uint32_t SizeFromSeq (const SequenceNumber&, const SequenceNumber&);
// Inquire available data from offset
@@ -60,10 +60,9 @@ public:
PendingData* Copy () const; // Create a copy of this header
PendingData* CopyS (uint32_t); // Copy with new size
PendingData* CopySD (uint32_t, uint8_t*); // Copy with new size, new data
virtual uint8_t* Contents() const { return data;}
public:
uint32_t size; // Number of data bytes
uint8_t* data; // Corresponding data (may be null)
std::vector<Ptr<Packet> > data; // Corresponding data (may be null)
// The next two fields allow simulated applications to exchange some info
uint32_t msgSize; // Total size of message
uint32_t responseSize;// Size of response requested