INET Framework for OMNeT++/OMNEST
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.h"
00020 
00021 Register_Class(TCPMsgBasedSendQueue);
00022 
00023 TCPMsgBasedSendQueue::TCPMsgBasedSendQueue() : TCPSendQueue()
00024 {
00025     begin = end = 0;
00026 }
00027 
00028 TCPMsgBasedSendQueue::~TCPMsgBasedSendQueue()
00029 {
00030     for (PayloadQueue::iterator it=payloadQueue.begin(); it!=payloadQueue.end(); ++it)
00031         delete it->msg;
00032 }
00033 
00034 void TCPMsgBasedSendQueue::init(uint32 startSeq)
00035 {
00036     begin = startSeq;
00037     end = startSeq;
00038 }
00039 
00040 std::string TCPMsgBasedSendQueue::info() const
00041 {
00042     std::stringstream out;
00043     out << "[" << begin << ".." << end << "), " << payloadQueue.size() << " packets";
00044     return out.str();
00045 }
00046 
00047 void TCPMsgBasedSendQueue::enqueueAppData(cPacket *msg)
00048 {
00049     //tcpEV << "sendQ: " << info() << " enqueueAppData(bytes=" << msg->getByteLength() << ")\n";
00050     end += msg->getByteLength();
00051 
00052     Payload payload;
00053     payload.endSequenceNo = end;
00054     payload.msg = msg;
00055     payloadQueue.push_back(payload);
00056 }
00057 
00058 uint32 TCPMsgBasedSendQueue::getBufferStartSeq()
00059 {
00060     return begin;
00061 }
00062 
00063 uint32 TCPMsgBasedSendQueue::getBufferEndSeq()
00064 {
00065     return end;
00066 }
00067 
00068 TCPSegment *TCPMsgBasedSendQueue::createSegmentWithBytes(uint32 fromSeq, ulong numBytes)
00069 {
00070     //tcpEV << "sendQ: " << info() << " createSeg(seq=" << fromSeq << " len=" << numBytes << ")\n";
00071     ASSERT(seqLE(begin,fromSeq) && seqLE(fromSeq+numBytes,end));
00072 
00073     TCPSegment *tcpseg = conn->createTCPSegment(NULL);
00074     tcpseg->setSequenceNo(fromSeq);
00075     tcpseg->setPayloadLength(numBytes);
00076 
00077     // add payload messages whose endSequenceNo is between fromSeq and fromSeq+numBytes
00078     PayloadQueue::iterator i = payloadQueue.begin();
00079     while (i!=payloadQueue.end() && seqLE(i->endSequenceNo, fromSeq))
00080         ++i;
00081     uint32 toSeq = fromSeq+numBytes;
00082     const char *payloadName = NULL;
00083     while (i!=payloadQueue.end() && seqLE(i->endSequenceNo, toSeq))
00084     {
00085         if (!payloadName) payloadName = i->msg->getName();
00086         tcpseg->addPayloadMessage(i->msg->dup(), i->endSequenceNo);
00087         ++i;
00088     }
00089 
00090     // give segment a name
00091     char msgname[80];
00092     if (!payloadName)
00093         sprintf(msgname, "tcpseg(l=%lu,%dmsg)", numBytes, tcpseg->getPayloadArraySize());
00094     else
00095         sprintf(msgname, "%.10s(l=%lu,%dmsg)", payloadName, numBytes, tcpseg->getPayloadArraySize());
00096     tcpseg->setName(msgname);
00097 
00098     return tcpseg;
00099 }
00100 
00101 void TCPMsgBasedSendQueue::discardUpTo(uint32 seqNum)
00102 {
00103     //tcpEV << "sendQ: " << info() << " discardUpTo(seq=" << seqNum << ")\n";
00104     ASSERT(seqLE(begin,seqNum) && seqLE(seqNum,end));
00105     begin = seqNum;
00106 
00107     // remove payload messages whose endSequenceNo is below seqNum
00108     while (!payloadQueue.empty() && seqLE(payloadQueue.front().endSequenceNo, seqNum))
00109     {
00110         delete payloadQueue.front().msg;
00111         payloadQueue.pop_front();
00112     }
00113 }
00114