PacketReader.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Qt.h"
00024 #include "PacketReader.h"
00025 #include "Protocols/Transports/Connection.h"
00026
00027 using Protocols::Transports::Connection;
00028 using Gnutella::PacketProcessing::PacketReader;
00029 using Gnutella::Packets::Packet;
00030
00031 PacketReader::PacketReader (Connection *connection)
00032 : p()
00033 {
00034 p.payloadLength = 0;
00035 p.headerBytesRead = 0;
00036 p.payloadBytesRead = 0;
00037 p.packet = 0;
00038 p.connection = connection;
00039
00040 QObject::connect (p.connection, SIGNAL (readyRead()),
00041 this, SLOT (readyRead()));
00042 }
00043
00044 PacketReader::~PacketReader()
00045 {
00046
00047
00048
00049 if (p.packet != 0)
00050 delete p.packet;
00051 }
00052
00053 void PacketReader::startReading()
00054 {
00055 p.payloadLength = 0;
00056 p.headerBytesRead = 0;
00057 p.payloadBytesRead = 0;
00058 p.done = false;
00059 if (p.packet) {
00060 delete p.packet;
00061 p.packet = 0;
00062 }
00063 QMetaObject::invokeMethod (this, "readyRead", Qt::QueuedConnection);
00064 }
00065
00066 void PacketReader::readyRead ()
00067 {
00068 using Gnutella::Packets::HeaderLength;
00069 using Gnutella::Packets::MaximalPayloadLength;
00070
00071 if (p.done)
00072 return;
00073
00074 if (p.headerBytesRead < HeaderLength) {
00075 quint64 read = p.connection->read (p.rawHeader + p.headerBytesRead,
00076 HeaderLength - p.headerBytesRead);
00077 if (read > 0)
00078 p.headerBytesRead += read;
00079
00080 if (p.headerBytesRead == HeaderLength) {
00081 p.payloadLength = static_cast <uchar> (p.rawHeader [19])
00082 + (static_cast <uchar> (p.rawHeader [20]) << 8)
00083 + (static_cast <uchar> (p.rawHeader [21]) << 16)
00084 + (static_cast <uchar> (p.rawHeader [22]) << 24);
00085 if (p.payloadLength > MaximalPayloadLength) {
00086 p.done = true;
00087 p.packet = 0;
00088 emit readError();
00089 return;
00090 }
00091 }
00092 }
00093 if (p.headerBytesRead == HeaderLength) {
00094 quint64 read = p.connection->read (p.rawPayload + p.payloadBytesRead,
00095 p.payloadLength - p.payloadBytesRead);
00096 if (read > 0)
00097 p.payloadBytesRead += read;
00098
00099 if (p.payloadBytesRead == p.payloadLength) {
00100
00101 QByteArray newRawHeader (p.rawHeader, HeaderLength);
00102 QByteArray newRawPayload (p.rawPayload, p.payloadLength);
00103
00104 p.packet = Gnutella::Packets::Packet::fromRawData (newRawHeader,
00105 newRawPayload);
00106 p.done = true;
00107
00108 emit packetRead();
00109 return;
00110 }
00111 }
00112 }
00113
00114 const Packet * PacketReader::packet() const
00115 {
00116 Q_ASSERT (p.done == true);
00117
00118 return p.packet;
00119 }