qftrans/crecievethread.cpp
2009-04-20 13:29:36 +02:00

170 lines
5.8 KiB
C++

/***************************************************************************
* Copyright (C) 2008 by Oliver Groß *
* z.o.gross@gmx.de *
* *
* 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 2 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, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "crecievethread.h"
#include <QTcpSocket>
#include <QByteArray>
#include <QDataStream>
#include <QFile>
#include <QDir>
namespace qftrans {
CRecieveThread::CRecieveThread(QString & destinationDir, QTcpSocket * socket, QObject * parent) :
QThread(parent), m_Socket(socket), m_DestinationDir(destinationDir)
{
}
CRecieveThread::~CRecieveThread() {
}
void CRecieveThread::setDestinationDir(QString & value) {
m_DestinationDir = value;
}
// TODO removeDownload(...)
void CRecieveThread::removeDownload(TransferData * /*data*/) {
}
void CRecieveThread::readData() {
QDataStream in(m_Socket);
in.setVersion(QDataStream::Qt_4_0);
if (m_Socket->bytesAvailable() >= (qint64)(sizeof(TransferHeader))) {
in.readRawData((char *)(&m_LastHeader), sizeof(TransferHeader));
m_LastHeaderValid = (qstrcmp(m_LastHeader.descriptor, DESCRIPTOR_STRING) == 0);
qDebug() << "got header" << m_LastHeader.type;
if (m_LastHeaderValid)
qDebug() << "valid";
else
qDebug() << "invalid";
qDebug() << "id" << m_LastHeader.id;
qDebug() << "length" << m_LastHeader.length;
}
else
m_LastHeaderValid = false;
TransferData * target = NULL;
while (m_LastHeaderValid) {
qDebug() << "available Bytes" << m_Socket->bytesAvailable();
if (m_Socket->bytesAvailable() >= m_LastHeader.length) {
//look for existing id
if (m_LastHeader.type == HT_ACK) {
qDebug() << "got HT_ACK .. requesting to start upload";
emit uploadStartRequest(m_LastHeader.id);
}
else {
if (m_DataDict.contains(m_LastHeader.id)) {
if (m_LastHeader.type == HT_CLOSE) {
//finished or canceled by peer
qDebug() << "download closed py peer";
emit downloadRemoved(m_DataDict.take(m_LastHeader.id));
}
else
//assign target
target = m_DataDict[m_LastHeader.id];
}
//id not in dict
else if (m_LastHeader.type == HT_ID) {
//new file announced
qDebug() << "download announced";
TransferData * newFile = new TransferData;
m_DataDict.insert(m_LastHeader.id, newFile);
newFile->transfered = 0;
newFile->size = 0;
newFile->localFile = false;
newFile->status = TS_WAITING;
newFile->fileDir = m_DestinationDir;
}
//check valid target and data available
if (target && m_LastHeader.length) {
switch (m_LastHeader.type) {
case HT_ID:
target->status = TS_WAITING;
QFile::remove(target->fileDir + QDir::separator() + target->fileName);
emit downloadUpdated(target);
break;
case HT_SIZE:
qDebug() << "reading size..";
in >> target->size;
qDebug() << "got size:" << target->size;
break;
case HT_NAME:
qDebug() << "reading filename..";
in >> target->fileName;
qDebug() << "got filename:" << target->fileName;
qDebug() << "requesting to send HT_ACK";
emit downloadAcknowledged(m_LastHeader.id);
break;
case HT_DATA: {
// qDebug() << "got data" << target->transfered << '/' << target->size;
if (target->status == TS_WAITING) {
target->status = TS_TRANSFERING;
emit downloadAdded(target);
}
char * buffer = new char[m_LastHeader.length];
in.readRawData(buffer, m_LastHeader.length);
// QFile file(target->fileDir + QDir::separator() + target->fileName);
// file.open(QIODevice::WriteOnly | QIODevice::Append);
// QDataStream out(&file);
// out.writeRawData((const char *)(buffer), m_LastHeader.length);
target->transfered += m_LastHeader.length;
delete[] buffer;
emit downloadUpdated(target);
}
break;
default:
in.skipRawData(m_LastHeader.length);
break;
}
}
}
}
if (m_Socket->bytesAvailable() >= (qint64)(sizeof(TransferHeader))) {
in.readRawData((char *)(&m_LastHeader), sizeof(TransferHeader));
m_LastHeaderValid = (qstrcmp(m_LastHeader.descriptor, DESCRIPTOR_STRING) == 0);
qDebug() << "got header" << m_LastHeader.type;
if (m_LastHeaderValid)
qDebug() << "valid";
else
qDebug() << "invalid";
qDebug() << "id" << m_LastHeader.id;
qDebug() << "length" << m_LastHeader.length;
}
else
m_LastHeaderValid = false;
}
}
void CRecieveThread::run() {
qDebug() << "start reciever thread";
connect(m_Socket, SIGNAL(readyRead()), this, SLOT(readData()));
exec();
disconnect(m_Socket, SIGNAL(readyRead()), this, SLOT(readData()));
}
}