/* * Copyright 2008 Ben Boeckel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ // Header include #include "PacketMaker.h" // Protocol includes #include "ProgressMeter.h" // Qt includes #include #include #include bool readFromBuffer(char* dest, QIODevice* src, const int size, Signet::Protocol::ProgressMeter* progressMeter = 0) { int totalRead = 0; if (progressMeter) progressMeter->setExpectedSize(size); while ((totalRead < size) && src->waitForReadyRead(30000)) { int read = src->read(dest + totalRead, size - totalRead); if (read < 0) { if (progressMeter) progressMeter->failure(); return false; } totalRead += read; if (progressMeter) progressMeter->setValue(totalRead); } if (progressMeter) progressMeter->success(); return true; } void Signet::Protocol::PacketMaker::rawData(QIODevice* device, const QByteArray& data, const QStringList& receivers) { Packet packet(Packet::RawData, receivers); packet.write(data); packet.dump(device); } void Signet::Protocol::PacketMaker::deny(QIODevice* device, const QStringList& receivers) { Packet packet(Packet::Denial, receivers); packet.dump(device); } void Signet::Protocol::PacketMaker::accept(QIODevice* device, const QStringList& receivers) { Packet packet(Packet::Acceptance, receivers); packet.dump(device); } void Signet::Protocol::PacketMaker::ack(QIODevice* device, const QStringList& receivers) { Packet packet(Packet::Acceptance, receivers); packet.dump(device); } void Signet::Protocol::PacketMaker::challenge(QIODevice* device, const QByteArray& id, const QStringList& receivers) { Packet packet(Packet::ChallengeRequest, receivers); packet.write(id); packet.dump(device); } void Signet::Protocol::PacketMaker::challengeKey(QIODevice* device, const QByteArray& key, const QStringList& receivers) { Packet packet(Packet::ChallengeKey, receivers); packet.write(key); packet.dump(device); } void Signet::Protocol::PacketMaker::challengeResponse(QIODevice* device, const QByteArray& response, const QStringList& receivers) { Packet packet(Packet::ChallengeResponse, receivers); packet.write(response); packet.dump(device); } void Signet::Protocol::PacketMaker::makeConnection(QIODevice* device, const QStringList& receivers) { Packet packet(Packet::ConnectRequest, receivers); packet.dump(device); } void Signet::Protocol::PacketMaker::dropConnection(QIODevice* device, const QStringList& receivers) { Packet packet(Packet::DisconnectRequest, receivers); packet.dump(device); } void Signet::Protocol::PacketMaker::unknownReceiver(QIODevice* device, const QStringList& receivers) { Packet packet(Packet::UnknownReceiver, receivers); packet.dump(device); } void Signet::Protocol::PacketMaker::unhandledRequest(QIODevice* device, const QStringList& receivers) { Packet packet(Packet::UnhandledPacket, receivers); packet.dump(device); } Signet::Protocol::Packet Signet::Protocol::PacketMaker::unwrap(QIODevice* device, ProgressMeter* progressMeter) { union { char raw[4]; qint32 sectionSize; qint16 packetType; qint8 sectionType; }; QStringList receivers; if (!readFromBuffer(raw, device, 2)) return Packet(); packetType = qFromBigEndian(packetType); if (!readFromBuffer(raw, device, 1)) return Packet(); while (sectionType == Packet::Receiver) { if (!readFromBuffer(raw, device, 4)) return Packet(); char* buffer = new char[sectionSize + 1]; buffer[sectionSize] = '\0'; sectionSize = qFromBigEndian(sectionSize); if (!readFromBuffer(buffer, device, sectionSize)) { delete [] buffer; return Packet(); } receivers << QString::fromUtf8(buffer); delete [] buffer; if (!readFromBuffer(raw, device, 1)) return Packet(); } if ((sectionType != Packet::Payload) || !readFromBuffer(raw, device, 4)) return Packet(); char* buffer = new char[sectionSize]; sectionSize = qFromBigEndian(sectionSize); if (!readFromBuffer(buffer, device, sectionSize, progressMeter)) { delete [] buffer; return Packet(); } Packet packet(packetType, receivers); packet.write(QByteArray(buffer, sectionSize)); delete [] buffer; return packet; }