INET Framework for OMNeT++/OMNEST
old/queues/TCPMsgBasedSendQueue.cc
Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2004 Andras Varga
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 
00019 #include "TCPMsgBasedSendQueue_old.h"
00020 
00021 using namespace tcp_old;
00022 
00023 Register_Class(TCPMsgBasedSendQueue);
00024 
00025 TCPMsgBasedSendQueue::TCPMsgBasedSendQueue() : TCPSendQueue()
00026 {
00027     begin = end = 0;
00028 }
00029 
00030 TCPMsgBasedSendQueue::~TCPMsgBasedSendQueue()
00031 {
00032     for (PayloadQueue::iterator it=payloadQueue.begin(); it!=payloadQueue.end(); ++it)
00033         delete it->msg;
00034 }
00035 
00036 void TCPMsgBasedSendQueue::init(uint32 startSeq)
00037 {
00038     begin = startSeq;
00039     end = startSeq;
00040 }
00041 
00042 std::string TCPMsgBasedSendQueue::info() const
00043 {
00044     std::stringstream out;
00045     out << "[" << begin << ".." << end << "), " << payloadQueue.size() << " packets";
00046     return out.str();
00047 }
00048 
00049 void TCPMsgBasedSendQueue::enqueueAppData(cPacket *msg)
00050 {
00051     //tcpEV << "sendQ: " << info() << " enqueueAppData(bytes=" << msg->getByteLength() << ")\n";
00052     end += msg->getByteLength();
00053 
00054     Payload payload;
00055     payload.endSequenceNo = end;
00056     payload.msg = msg;
00057     payloadQueue.push_back(payload);
00058 }
00059 
00060 uint32 TCPMsgBasedSendQueue::getBufferStartSeq()
00061 {
00062     return begin;
00063 }
00064 
00065 uint32 TCPMsgBasedSendQueue::getBufferEndSeq()
00066 {
00067     return end;
00068 }
00069 
00070 TCPSegment *TCPMsgBasedSendQueue::createSegmentWithBytes(uint32 fromSeq, ulong numBytes)
00071 {
00072     //tcpEV << "sendQ: " << info() << " createSeg(seq=" << fromSeq << " len=" << numBytes << ")\n";
00073     ASSERT(seqLE(begin,fromSeq) && seqLE(fromSeq+numBytes,end));
00074 
00075     TCPSegment *tcpseg = conn->createTCPSegment(NULL);
00076     tcpseg->setSequenceNo(fromSeq);
00077     tcpseg->setPayloadLength(numBytes);
00078 
00079     // add payload messages whose endSequenceNo is between fromSeq and fromSeq+numBytes
00080     PayloadQueue::iterator i = payloadQueue.begin();
00081     while (i!=payloadQueue.end() && seqLE(i->endSequenceNo, fromSeq))
00082         ++i;
00083     uint32 toSeq = fromSeq+numBytes;
00084     const char *payloadName = NULL;
00085     while (i!=payloadQueue.end() && seqLE(i->endSequenceNo, toSeq))
00086     {
00087         if (!payloadName) payloadName = i->msg->getName();
00088         tcpseg->addPayloadMessage(i->msg->dup(), i->endSequenceNo);
00089         ++i;
00090     }
00091 
00092     // give segment a name
00093     char msgname[80];
00094     if (!payloadName)
00095         sprintf(msgname, "tcpseg(l=%lu,%dmsg)", numBytes, tcpseg->getPayloadArraySize());
00096     else
00097         sprintf(msgname, "%.10s(l=%lu,%dmsg)", payloadName, numBytes, tcpseg->getPayloadArraySize());
00098     tcpseg->setName(msgname);
00099 
00100     return tcpseg;
00101 }
00102 
00103 void TCPMsgBasedSendQueue::discardUpTo(uint32 seqNum)
00104 {
00105     //tcpEV << "sendQ: " << info() << " discardUpTo(seq=" << seqNum << ")\n";
00106     ASSERT(seqLE(begin,seqNum) && seqLE(seqNum,end));
00107     begin = seqNum;
00108 
00109     // remove payload messages whose endSequenceNo is below seqNum
00110     while (!payloadQueue.empty() && seqLE(payloadQueue.front().endSequenceNo, seqNum))
00111     {
00112         delete payloadQueue.front().msg;
00113         payloadQueue.pop_front();
00114     }
00115 }
00116