diff --git a/src/internet-node/pending-data.cc b/src/internet-node/pending-data.cc index 1988b271e..7ca185a19 100644 --- a/src/internet-node/pending-data.cc +++ b/src/internet-node/pending-data.cc @@ -29,7 +29,6 @@ #include #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 (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 ((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 (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 (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 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 (data+o, s1); + uint32_t count = 0; + std::vector >::size_type begin = 0; + bool beginFound = false; + std::vector >::size_type end = 0; + Ptr outPacket; + Ptr endFragment; + for (std::vector >::size_type i=0;iGetSize(); + if (!beginFound) + { + if (count > o) + { + if (count >= o + s1) //then just copy within this packet + { + Ptr 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 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 toFragment = data[end]; + uint32_t packetStart = count - toFragment->GetSize(); + uint32_t fragmentLength = o + s1 - packetStart; + endFragment = toFragment->CreateFragment(0, fragmentLength); + break; + } + } + } + for (std::vector >::size_type i=begin+1;iAddAtEnd (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 (s1); } } diff --git a/src/internet-node/pending-data.h b/src/internet-node/pending-data.h index fc7ccc621..e55c002f6 100644 --- a/src/internet-node/pending-data.h +++ b/src/internet-node/pending-data.h @@ -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 > 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