Pong.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2005-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #include "Qt.h"
00024 #include "Pong.h"
00025 
00026 using namespace Gnutella::Packets;
00027 
00029 enum Constants
00030 {
00031     MinimalPayloadLength = 14   
00032 };
00033 
00034 
00039 Pong::Pong(quint16 port, const QHostAddress &ipAddress, quint32 sharedFiles, quint32 sharedKilobytes)
00040     : Packet (PongDescriptor)
00041 {
00042     d = new Data;
00043 
00044     d->ref.init (1);
00045 
00046     d->port = port;
00047     d->ipAddress = ipAddress;
00048     d->sharedFiles = sharedFiles;
00049     d->sharedKilobytes = sharedKilobytes;
00050 }
00051 
00055 Pong::Pong(const QByteArray &rawHeader, const QByteArray &rawPayload)
00056     : Packet (rawHeader, rawPayload)
00057 {
00058     d = new Data;
00059 
00060     d->ref.init (1);
00061 
00062     parse();
00063 }
00064 
00068 Pong::~Pong()
00069 {
00070     if (!d->ref.deref())
00071         delete d;
00072 }
00073 
00075 
00078 Pong & Pong::operator= (const Pong &other)
00079 {
00080     Data *x = other.d;
00081     x->ref.ref();
00082     x = qAtomicSetPtr(&d, x);
00083     if (!x->ref.deref())
00084         delete x;
00085 
00086     Packet::operator= (other);
00087     return *this;
00088 }
00089 
00090 void Pong::invalidatePayload()
00091 {
00092     if (d->ref != 1) {
00093         Data *x = new Data;
00094         x->ref.init (1);
00095 
00096         x->port                 = d->port;
00097         x->ipAddress            = d->ipAddress;
00098         x->sharedFiles          = d->sharedFiles;
00099         x->sharedKilobytes      = d->sharedKilobytes;
00100         x->ggepBlock            = d->ggepBlock;
00101 
00102         x = qAtomicSetPtr (&d, x);
00103         if (!x->ref.deref())
00104             delete x;
00105     };
00106     Packet::invalidatePayload();
00107 }
00108 
00109 bool Pong::prepareReadPayload (const QByteArray &rawPayload)
00110 {
00111     if (payloadLength() < MinimalPayloadLength)
00112         return false;
00113 
00114     const char *extensionRawData = rawPayload.constData() + MinimalPayloadLength;
00115     int extensionSize = rawPayload.length() - MinimalPayloadLength;
00116     QByteArray extensionData = QByteArray::fromRawData (extensionRawData, extensionSize);
00117 
00118     d->ggepBlock.prepareRead (extensionData);
00119     return true;
00120 }
00121 
00122 void Pong::readPayload (QDataStream &stream)
00123 {
00124     stream >> d->port;
00125     Gnutella::Packets::operator>> (stream, d->ipAddress);
00126     stream >> d->sharedFiles;
00127     stream >> d->sharedKilobytes;
00128     stream >> d->ggepBlock;
00129 }
00130 
00131 int Pong::prepareWritePayload() const
00132 {
00133     return MinimalPayloadLength + d->ggepBlock.prepareWrite();
00134 }
00135 
00136 void Pong::writePayload (QDataStream &stream) const
00137 {
00138     stream << d->port;
00139     Gnutella::Packets::operator<< (stream, d->ipAddress);
00140     stream << d->sharedFiles;
00141     stream << d->sharedKilobytes;
00142     stream << d->ggepBlock;
00143 }