File indexing completed on 2024-05-19 05:00:08

0001 /* This file is part of the KDE project
0002 
0003    Copyright (C) 2006 Manolo Valdes <nolis71cu@gmail.com>
0004    Copyright (C) 2009 Matthias Fuchs <mat69@gmx.net>
0005 
0006    This program is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 */
0011 
0012 #ifndef SEGMENT_H
0013 #define SEGMENT_H
0014 
0015 #include <QObject>
0016 
0017 #include <KIO/TransferJob>
0018 
0019 #include "core/transfer.h"
0020 
0021 /**
0022  * class Segment
0023  */
0024 
0025 class Segment : public QObject
0026 {
0027     Q_OBJECT
0028 
0029 public:
0030     /**
0031      * The status property describes the current segment status
0032      *
0033      * @param Running The transfer is being executed
0034      * @param Stopped The transfer is stopped
0035      * @param Killed The transfer have been killed due unhandled errors
0036      * @param Timeout The transfer is broken because an error occurred
0037      * @param Finished The transfer exited successfully
0038      */
0039     enum Status { Running, Stopped, Killed, Timeout, Finished };
0040 
0041     Segment(const QUrl &src, const QPair<KIO::fileoffset_t, KIO::fileoffset_t> &segmentSize, const QPair<int, int> &segmentRange, QObject *parent);
0042 
0043     ~Segment() override;
0044 
0045     /**
0046      * Create the segment transfer
0047      */
0048     bool createTransfer();
0049 
0050     /**
0051      * stop the segment transfer
0052      */
0053     bool stopTransfer();
0054 
0055     /**
0056      * Get the value of m_offset set
0057      */
0058     KIO::fileoffset_t offset() const
0059     {
0060         return m_offset;
0061     }
0062 
0063     /**
0064      * Returns the size the current segment has
0065      * @return the size of the segment
0066      */
0067     KIO::filesize_t size() const
0068     {
0069         return m_currentSegSize;
0070     }
0071 
0072     /**
0073      * Returns the written bytes
0074      * @return the value of m_bytesWritten
0075      */
0076     KIO::filesize_t BytesWritten()
0077     {
0078         return m_bytesWritten;
0079     } // TODO needed???
0080 
0081     /**
0082      * Get the job
0083      * @return the value of m_getJob
0084      */
0085     KIO::TransferJob *job()
0086     {
0087         return m_getJob;
0088     } // TODO needed?
0089 
0090     /**
0091      * Get the segment status
0092      * @return the value of m_status
0093      */
0094     Status status() const
0095     {
0096         return m_status;
0097     } // TODO needed?
0098 
0099     QPair<int, int> assignedSegments() const;
0100     QPair<KIO::fileoffset_t, KIO::fileoffset_t> segmentSize() const;
0101     int countUnfinishedSegments() const;
0102     QPair<int, int> split();
0103     bool merge(const QPair<KIO::fileoffset_t, KIO::fileoffset_t> &segmentSize, const QPair<int, int> &segmentRange);
0104     bool findingFileSize() const;
0105 
0106 public Q_SLOTS:
0107     /**
0108      * start the segment transfer
0109      */
0110     bool startTransfer();
0111 
0112     /**
0113      * Called whenever a subjob finishes
0114      * @param job the job that emitted this signal
0115      */
0116     void slotResult(KJob *job);
0117 
0118 Q_SIGNALS:
0119     void data(KIO::fileoffset_t offset, const QByteArray &data, bool &worked);
0120     /**
0121      * Emitted whenever the transfer is closed with an error
0122      */
0123     void error(Segment *segment, const QString &errorText, Transfer::LogLevel logLevel);
0124     void finishedSegment(Segment *segment, int segmentNum, bool connectionFinished = true);
0125     void statusChanged(Segment *);
0126     void speed(ulong speed);
0127     void connectionProblem();
0128     void totalSize(KIO::filesize_t size, QPair<int, int> segmentRange);
0129     void finishedDownload(KIO::filesize_t size);
0130     void canResume();
0131     void urlChanged(const QUrl &newUrl);
0132 
0133 private Q_SLOTS:
0134     void slotData(KIO::Job *job, const QByteArray &data);
0135     void slotCanResume(KIO::Job *job, KIO::filesize_t); // TODO remove
0136     void slotTotalSize(KJob *job, qulonglong size);
0137 
0138     /**
0139      * Writes the buffer, assuming that this segment is finished and the rest should be written.
0140      * Tries to write and if that fails waits for 50 msec and retries again.
0141      * If this whole process still fails after 100 times, then error is emitted.
0142      */
0143     void slotWriteRest();
0144 
0145     void slotRedirection(KIO::Job *, const QUrl &);
0146 
0147 private:
0148     bool writeBuffer();
0149     void setStatus(Status stat, bool doEmit = true);
0150 
0151 private:
0152     bool m_findFilesize;
0153     bool m_canResume;
0154     Status m_status;
0155     int m_currentSegment;
0156     int m_endSegment;
0157     int m_errorCount;
0158     KIO::fileoffset_t m_offset;
0159     KIO::fileoffset_t m_currentSegSize;
0160     KIO::filesize_t m_bytesWritten;
0161     KIO::filesize_t m_totalBytesLeft;
0162     KIO::TransferJob *m_getJob;
0163     QUrl m_url;
0164     QByteArray m_buffer;
0165     QPair<KIO::fileoffset_t, KIO::fileoffset_t> m_segSize;
0166 };
0167 
0168 #endif // SEGMENT_H