170 lines
5.8 KiB
C++
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()));
|
|
}
|
|
}
|