#ifndef _SEND_H_ #define _SEND_H_ //============================================================================= // // File : DccFileTransfer.h // Creation date : Tue Sep 24 09 2000 15:06:12 by Szymon Stefanek // // This file is part of the KVIrc IRC client distribution // Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) // // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //============================================================================= #include "DccDescriptor.h" #include "DccWindow.h" #include "DccThread.h" #include "KviWindow.h" #include "KviCString.h" #include "kvi_sockettype.h" #include "KviPointerList.h" #include "KviFileTransfer.h" #include "KviTimeUtils.h" #include "KviTalHBox.h" #include "KviTalVBox.h" #include #include #include #include #include #include class QSpinBox; class QTimer; class QPainter; class DccFileTransfer; class DccMarshal; class QMenu; struct KviDccSendThreadOptions { KviCString szFileName; quint64 uStartPosition; int iPacketSize; int iIdleStepLengthInMSec; bool bFastSend; bool bNoAcks; bool bIsTdcc; unsigned int uMaxBandwidth; }; class DccSendThread : public DccThread { public: DccSendThread(QObject * par, kvi_socket_t fd, KviDccSendThreadOptions * opt); ~DccSendThread(); private: // stats: SHARED!!! uint m_uAverageSpeed; uint m_uInstantSpeed; quint64 m_uFilePosition; quint64 m_uAckedBytes = 0; quint64 m_uTotalSentBytes = 0; // internal unsigned long m_uStartTime; unsigned long m_uInstantSpeedInterval; quint64 m_uInstantSentBytes; KviDccSendThreadOptions * m_pOpt; KviMSecTimeInterval * m_pTimeInterval; // used for computing the instant bandwidth but not only public: void initGetInfo(); uint averageSpeed() { return m_uAverageSpeed; }; uint instantSpeed() { return m_uInstantSpeed; }; quint64 filePosition() { return m_uFilePosition; }; // sent ONLY in this session quint64 sentBytes() { return m_uTotalSentBytes; }; quint64 ackedBytes() { return m_uAckedBytes; }; unsigned int bandwidthLimit() { return m_pOpt->uMaxBandwidth; }; void setBandwidthLimit(unsigned int uMaxBandwidth) { m_pOpt->uMaxBandwidth = uMaxBandwidth; }; void doneGetInfo(); protected: void updateStats(); virtual void run(); }; struct KviDccRecvThreadOptions { bool bResume; KviCString szFileName; quint64 uTotalFileSize; int iIdleStepLengthInMSec; bool bSendZeroAck; bool bSend64BitAck; bool bNoAcks; bool bIsTdcc; unsigned int uMaxBandwidth; }; class DccRecvThread : public DccThread { public: DccRecvThread(QObject * par, kvi_socket_t fd, KviDccRecvThreadOptions * opt); ~DccRecvThread(); protected: KviDccRecvThreadOptions * m_pOpt; // stats: SHARED! uint m_uAverageSpeed; uint m_uInstantSpeed; quint64 m_uFilePosition; quint64 m_uTotalReceivedBytes; // internal unsigned long m_uStartTime; KviMSecTimeInterval * m_pTimeInterval; // used for computing the instant bandwidth quint64 m_uInstantReceivedBytes; quint64 m_uInstantSpeedInterval; QFile * m_pFile; public: void initGetInfo(); uint averageSpeed() { return m_uAverageSpeed; }; uint instantSpeed() { return m_uInstantSpeed; }; quint64 filePosition() { return m_uFilePosition; }; // received ONLY in this session quint64 receivedBytes() { return m_uTotalReceivedBytes; }; unsigned int bandwidthLimit() { return m_pOpt->uMaxBandwidth; }; void setBandwidthLimit(unsigned int uMaxBandwidth) { m_pOpt->uMaxBandwidth = uMaxBandwidth; }; void doneGetInfo(); protected: void postMessageEvent(const char * msg); void updateStats(); bool sendAck(qint64 filePos, bool bUse64BitAck = false); virtual void run(); }; class DccFileTransferBandwidthDialog : public QDialog { Q_OBJECT public: DccFileTransferBandwidthDialog(QWidget * pParent, DccFileTransfer * t); ~DccFileTransferBandwidthDialog(); protected: DccFileTransfer * m_pTransfer; QCheckBox * m_pEnableLimitCheck; QSpinBox * m_pLimitBox; protected: void closeEvent(QCloseEvent * e) override; protected slots: void okClicked(); void cancelClicked(); }; class DccFileTransfer : public KviFileTransfer, public DccMarshalOutputContext { enum GeneralStatus { Connecting, Transferring, Success, Failure }; Q_OBJECT public: DccFileTransfer(DccDescriptor * dcc); ~DccFileTransfer(); private: DccSendThread * m_pSlaveSendThread; DccRecvThread * m_pSlaveRecvThread; DccDescriptor * m_pDescriptor; DccMarshal * m_pMarshal; KviCString m_szTarget; KviCString m_szDccType; QString m_szTransferIdString; QString m_szStatusString; GeneralStatus m_eGeneralStatus; QString m_szTransferLog; // html kvi_time_t m_tTransferStartTime; kvi_time_t m_tTransferEndTime; // cached stats quint64 m_uTotalFileSize; // total file size to transfer unsigned int m_uMaxBandwidth; DccFileTransferBandwidthDialog * m_pBandwidthDialog; QTimer * m_pResumeTimer; // used to signal resume timeout public: bool resumeAccepted(const char * filename, const char * port, const char * szZeroPortTag); bool doResume(const char * filename, const char * port, quint64 filePos); static void init(); static void done(); static unsigned int runningTransfersCount(); static DccFileTransfer * nonFailedTransferWithLocalFileName(const QString & szLocalFileName); static unsigned int transferCount(); static bool handleResumeAccepted(const char * filename, const char * port, const char * szZeroPortTag); static bool handleResumeRequest(const char * filename, const char * port, quint64 filePos); bool event(QEvent * e) override; KviWindow * dccMarshalOutputWindow() override; const char * dccMarshalOutputContextString() override; void displayPaint(QPainter * p, int column, QRect rect) override; int displayHeight(int iLineSpacing) override; void fillContextPopup(QMenu * m) override; virtual void fillStatusString(QString & szBuffer); bool active() override; QString tipText() override; QString localFileName() override; bool isFileUpload() { return m_pDescriptor->isFileUpload(); }; unsigned int averageSpeed(); unsigned int instantSpeed(); unsigned int transferredBytes(); int bandwidthLimit(); void setBandwidthLimit(int iVal); virtual DccThread * getSlaveThread(); protected: void startConnection(); void listenOrConnect(); void addToTransferLog(const QString & s); void outputAndLog(const QString & s); void outputAndLog(int msgtype, const QString & s); KviWindow * eventWindow(); protected slots: void connectionInProgress(); void sslError(const char * msg); void startingSSLHandshake(); void handleMarshalError(KviError::Code); void connected(); void bandwidthDialogDestroyed(); void configureBandwidth(); void resumeTimedOut(); public slots: void abort(); void retryDCC(); void retryTDCC(); void retryRevDCC(); }; #endif //_SEND_H_