You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
5.8 KiB
169 lines
5.8 KiB
/*************************************************************************** |
|
* 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())); |
|
} |
|
}
|
|
|