PacketProtocol.cpp

Go to the documentation of this file.
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 "PacketProtocol.h"
00025 #include "AllowedFast.h"
00026 #include "BadPacket.h"
00027 #include "BitField.h"
00028 #include "Cancel.h"
00029 #include "Choke.h"
00030 #include "Have.h"
00031 #include "HaveAll.h"
00032 #include "HaveNone.h"
00033 #include "Interested.h"
00034 #include "Keepalive.h"
00035 #include "NotInterested.h"
00036 #include "Piece.h"
00037 #include "Port.h"
00038 #include "RejectRequest.h"
00039 #include "Request.h"
00040 #include "SuggestPiece.h"
00041 #include "Unchoke.h"
00042 #include "Imports.cpp"
00043 
00045 int PacketProtocol::headerLength() const
00046 {
00047     return HeaderLength;
00048 }
00049 
00051 
00058 int PacketProtocol::payloadLength (const QByteArray &header) const
00059 {
00060     Q_ASSERT (header.length() == HeaderLength);
00061     // First four bytes are a big-endian integer saying how many bytes follow:
00062     qint32 length = 0;
00063     length |= header [3];
00064     length |= header [2] << 8;
00065     length |= header [1] << 16;
00066     length |= header [0] << 24;
00067     return length;
00068 }
00069 
00071 
00082 GenericsPacket PacketProtocol::createPacket (const QByteArray &rawHeader,
00083                                              const QByteArray &rawPayload) const
00084 {
00085     Q_ASSERT (rawHeader.length() == HeaderLength);
00086     Packet packet;
00087     if (rawPayload.length() == 0) // Only Keepalive has no payload.
00088         packet = Keepalive();
00089     else
00090         packet = getPacketFromTypeByte (rawPayload [0]);
00091     return parsedOrBadPacket (packet, rawHeader, rawPayload);
00092 }
00093 
00095 Packet PacketProtocol::getPacketFromTypeByte (uchar byte)
00096 {
00097     PacketType type = static_cast <PacketType> (byte);
00098     switch (type)
00099     {
00100     case BitFieldPacket:
00101         return BitField();
00102     case CancelPacket:
00103         return Cancel();
00104     case ChokePacket:
00105         return Choke();
00106     case HavePacket:
00107         return Have();
00108     case InterestedPacket:
00109         return Interested();
00110     case NotInterestedPacket:
00111         return NotInterested();
00112     case PiecePacket:
00113         return Piece();
00114     case RequestPacket:
00115         return Request();
00116     case UnchokePacket:
00117         return Unchoke();
00118     case PortPacket:
00119         return Port();
00120     case SuggestPiecePacket:
00121         return SuggestPiece();
00122     case HaveAllPacket:
00123         return HaveAll();
00124     case HaveNonePacket:
00125         return HaveNone();
00126     case RejectRequestPacket:
00127         return RejectRequest();
00128     case AllowedFastPacket:
00129         return AllowedFast();
00130     case KeepalivePacket: // 0xFF is not a valid packet type
00131         // fallback to BadPacket:
00132     default:
00133         return BadPacket (type);
00134     }
00135 }
00136 
00138 
00149 Packet PacketProtocol::parsedOrBadPacket (Packet &packet,
00150                                           const QByteArray &rawHeader,
00151                                           const QByteArray &rawPayload)
00152 {
00153     if (packet->parse (rawHeader, rawPayload))
00154         return packet;
00155     else
00156         return BadPacket (packet->packetType(), rawHeader, rawPayload);
00157 }