00001 /* 00002 00003 Copyright (C) 2006-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 "PacketBase.h" 00025 #include "Imports.cpp" 00026 00028 QString PacketBase::protocol() const 00029 { 00030 return "BitTorrent"; 00031 } 00032 00034 00043 00044 00053 PacketBase::PacketBase (Data *dd, PacketType packetType) 00054 : GenericsPacketBase (dd) 00055 { 00056 Q_SD (Data); 00057 d->packetType = packetType; 00058 } 00059 00061 00077 bool PacketBase::readHeader (const QByteArray &rawHeader) 00078 { 00079 Q_SD (Data); 00080 BinaryReader reader (rawHeader, BinaryReader::BigEndian); 00081 qint32 bytesLeft = reader.readInt32(); 00082 QByteArray payload = rawPayload(); 00083 Q_ASSERT (payload.length() == bytesLeft); 00084 if (bytesLeft > 0) { 00085 PacketType packetType = static_cast <PacketType> (payload.at(0)); 00086 // packetType read here must match the value passed to the ctor: 00087 Q_ASSERT (packetType == d->packetType); 00088 } else { 00089 // Keepalives have no payload: 00090 d->packetType = KeepalivePacket; 00091 } 00092 return reader.hasReadAll() && !reader.hasReadPastEnd(); 00093 } 00094 00096 00101 QByteArray PacketBase::writeHeader() const 00102 { 00103 Q_SD (const Data); 00104 QByteArray rawHeader (4, 0); 00105 BinaryWriter writer (&rawHeader, BinaryWriter::BigEndian); 00106 quint32 payloadLength = this->payloadLength(); 00107 Q_ASSERT ((d->packetType == KeepalivePacket && payloadLength == 0) 00108 || (d->packetType != KeepalivePacket && payloadLength > 0)); 00109 writer.writeUInt32 (payloadLength); 00110 Q_ASSERT (4 == writer.bytesWritten()); 00111 return rawHeader; 00112 } 00113 00115 00129 bool PacketBase::readPayload (const QByteArray &rawPayload) 00130 { 00131 BinaryReader reader (rawPayload, BinaryReader::BigEndian); 00132 if (packetType() != KeepalivePacket) 00133 reader.readByte(); // Eat the PacketType marker from payload. 00134 readPayload (reader); 00135 return reader.hasReadAll() && !reader.hasReadPastEnd(); 00136 } 00137 00149 00150 00158 QByteArray PacketBase::writePayload() const 00159 { 00160 BinaryWriter writer (BinaryWriter::BigEndian); 00161 if (packetType() != KeepalivePacket) 00162 writer.writeByte (static_cast <uchar> (packetType())); 00163 writePayload (writer); 00164 Q_ASSERT (writer.hasWrittenAll() && !writer.hasWrittenPastEnd()); 00165 return writer.buffer(); 00166 } 00167