20 #include <QtCore/QTimer>
22 Segment::Segment(
const KUrl &src,
const QPair<KIO::fileoffset_t, KIO::fileoffset_t> &segmentSize,
const QPair<int, int> &segmentRange,
QObject *parent)
24 m_findFilesize((segmentRange.first == -1) && (segmentRange.second == -1)),
27 m_currentSegment(segmentRange.first),
28 m_endSegment(segmentRange.second),
30 m_offset(segmentSize.first * segmentRange.first),
31 m_currentSegSize(segmentSize.first),
35 m_segSize(segmentSize)
38 if (m_endSegment - m_currentSegment == 0) {
39 m_currentSegSize = m_segSize.second;
49 m_totalBytesLeft = m_segSize.first * (m_endSegment - m_currentSegment) + m_segSize.second;
57 kDebug(5001) <<
"Closing transfer ...";
58 m_getJob->kill(KJob::Quietly);
64 return m_findFilesize;
69 kDebug(5001) <<
" -- " << m_url;
73 m_getJob = KIO::get(m_url, KIO::Reload, KIO::HideProgressInfo);
75 m_getJob->addMetaData(
"errorPage",
"false" );
76 m_getJob->addMetaData(
"AllowCompressedPage",
"false" );
80 m_getJob->addMetaData(
"resume", KIO::number(m_offset) );
81 connect(m_getJob, SIGNAL(
canResume(KIO::Job*,KIO::filesize_t)),
82 SLOT(slotCanResume(KIO::Job*,KIO::filesize_t)));
84 #if 0 //TODO: we disable that code till it's implemented in kdelibs, also we need to think, which settings we should use
90 connect(m_getJob, SIGNAL(
totalSize(
KJob*,qulonglong)),
this, SLOT(slotTotalSize(
KJob*,qulonglong)));
91 connect(m_getJob, SIGNAL(
data(KIO::Job*,QByteArray)),
92 SLOT(slotData(KIO::Job*,QByteArray)));
94 connect(m_getJob, SIGNAL(redirection(KIO::Job *,
const KUrl &)), SLOT(slotRedirection(KIO::Job *,
const KUrl &)));
98 void Segment::slotRedirection(KIO::Job* ,
const KUrl &url)
104 void Segment::slotCanResume( KIO::Job* job, KIO::filesize_t offset )
116 kDebug(5001) << "Size found for" << m_url;
118 if (m_findFilesize) {
119 int numSegments = size / m_segSize.first;
120 KIO::fileoffset_t rest = size % m_segSize.first;
123 m_segSize.second = rest;
126 m_endSegment = numSegments - 1;
128 m_currentSegment = 0;
129 m_currentSegSize = (numSegments == 1 ? m_segSize.second : m_segSize.first);
130 m_totalBytesLeft =
size;
132 emit
totalSize(size, qMakePair(m_currentSegment, m_endSegment));
133 m_findFilesize =
false;
141 kDebug(5001) << m_url;
145 if (m_getJob && (m_status !=
Running)) {
160 m_getJob->kill(KJob::EmitResult);
169 kDebug(5001) <<
"Job:" << job << m_url <<
"error:" << job->error();
178 if ( !m_buffer.isEmpty() )
180 if (m_findFilesize && !job->error()) {
181 kDebug(5001) <<
"Looping until write the buffer ..." << m_url;
186 if (!m_totalBytesLeft && !m_findFilesize)
195 if (job->error() && (m_status ==
Running)) {
200 void Segment::slotData(KIO::Job *,
const QByteArray& _data)
203 if (m_offset && !m_canResume)
205 kDebug(5001) << m_url <<
"does not allow resuming.";
207 setStatus(
Killed,
false );
208 const QString errorText = KIO::buildErrorString(KIO::ERR_CANNOT_RESUME, m_url.prettyUrl());
213 m_buffer.append(_data);
214 if (!m_findFilesize && m_totalBytesLeft && static_cast<uint>(m_buffer.size()) >= m_totalBytesLeft)
216 kDebug(5001) <<
"Segment::slotData() buffer full. stoping transfer...";
218 m_getJob->kill(KJob::Quietly);
221 m_buffer.truncate(m_totalBytesLeft);
236 bool Segment::writeBuffer()
238 kDebug(5001) <<
"Segment::writeBuffer() sending:" << m_buffer.size() <<
"from job:" << m_getJob;
239 if (m_buffer.isEmpty()) {
244 emit
data(m_offset, m_buffer, worked);
247 m_currentSegSize -= m_buffer.size();
248 if (!m_findFilesize) {
249 m_totalBytesLeft -= m_buffer.size();
251 m_offset += m_buffer.size();
252 m_bytesWritten += m_buffer.size();
254 kDebug(5001) <<
"Segment::writeBuffer() updating segment record of job:" << m_getJob <<
"--" << m_totalBytesLeft <<
"bytes left";
258 if (m_findFilesize) {
263 bool finished =
false;
265 while (m_currentSegSize <= 0 && !finished) {
266 finished = (m_currentSegment == m_endSegment);
271 m_currentSegSize += (m_currentSegment == m_endSegment ? m_segSize.second : m_segSize.first);
278 void Segment::slotWriteRest()
280 if (m_buffer.isEmpty()) {
287 if (m_findFilesize) {
293 if (++m_errorCount >= 100) {
294 kWarning() <<
"Failed to write to the file:" << m_url <<
this;
297 kDebug() <<
"Wait 50 msec:" <<
this;
298 QTimer::singleShot(50,
this, SLOT(slotWriteRest()));
302 void Segment::setStatus(
Status stat,
bool doEmit)
311 return QPair<int, int>(m_currentSegment, m_endSegment);
321 return m_endSegment - m_currentSegment;
331 QPair<int, int> freed = QPair<int, int>(-1, -1);
336 kDebug(5001) <<
"None freed, start:" << m_currentSegment <<
"end:" << m_endSegment;
345 const int newEnd = m_endSegment - free;
346 freed = QPair<int, int>(newEnd + 1, m_endSegment);
347 kDebug(5001) <<
"Start:" << m_currentSegment <<
"old end:" << m_endSegment <<
"new end:" << newEnd <<
"freed:" << freed;
348 m_endSegment = newEnd;
349 m_totalBytesLeft -= m_segSize.first * (free - 1) + m_segSize.second;
354 m_segSize.second = m_segSize.first;
366 if (m_endSegment + 1 == segmentRange.first) {
367 m_endSegment = segmentRange.second;
368 m_segSize.second = segmentSize.second;
369 m_totalBytesLeft += segmentSize.first * (m_endSegment - segmentRange.first) + m_segSize.second;
376 #include "segment.moc"
int countUnfinishedSegments() const
static int saveSegSize()
Get SaveSegSize.
QPair< int, int > split()
static bool speedLimit()
Get SpeedLimit.
static int transferSpeedLimit()
Get TransferSpeedLimit.
QPair< KIO::fileoffset_t, KIO::fileoffset_t > segmentSize() const
bool stopTransfer()
stop the segment transfer
void slotResult(KJob *job)
Called whenever a subjob finishes.
void data(KIO::fileoffset_t offset, const QByteArray &data, bool &worked)
void totalSize(KIO::filesize_t size, QPair< int, int > segmentRange)
bool merge(const QPair< KIO::fileoffset_t, KIO::fileoffset_t > &segmentSize, const QPair< int, int > &segmentRange)
bool startTransfer()
start the segment transfer
Segment(const KUrl &src, const QPair< KIO::fileoffset_t, KIO::fileoffset_t > &segmentSize, const QPair< int, int > &segmentRange, QObject *parent)
bool createTransfer()
Create the segment transfer.
KIO::filesize_t size() const
Returns the size the current segment has.
void finishedSegment(Segment *segment, int segmentNum, bool connectionFinished=true)
void error(Segment *segment, const QString &errorText, Transfer::LogLevel logLevel)
Emitted whenever the transfer is closed with an error.
Status
The status property describes the current segment status.
bool findingFileSize() const
void finishedDownload(KIO::filesize_t size)
void statusChanged(Segment *)
void urlChanged(const KUrl &newUrl)
QPair< int, int > assignedSegments() const