diff options
Diffstat (limited to 'plugins/CopyEngine/Ultracopier-0.3/WriteThread.cpp')
-rw-r--r-- | plugins/CopyEngine/Ultracopier-0.3/WriteThread.cpp | 182 |
1 files changed, 173 insertions, 9 deletions
diff --git a/plugins/CopyEngine/Ultracopier-0.3/WriteThread.cpp b/plugins/CopyEngine/Ultracopier-0.3/WriteThread.cpp index fc46d1f..448e8dc 100644 --- a/plugins/CopyEngine/Ultracopier-0.3/WriteThread.cpp +++ b/plugins/CopyEngine/Ultracopier-0.3/WriteThread.cpp @@ -5,7 +5,6 @@ WriteThread::WriteThread() { stopIt=false; - /// \test lot of level of priority isOpen.release(); start(); moveToThread(this); @@ -15,15 +14,22 @@ WriteThread::WriteThread() stat=Idle; #endif CurentCopiedSize=0; + buffer=false; + putInPause=false; + needRemoveTheFile=false; + blockSize=1024*1024; } WriteThread::~WriteThread() { - stop(); + stopIt=true; + needRemoveTheFile=true; freeBlock.release(); + // useless because stopIt will close all thread, but if thread not runing run it + //endIsDetected(); emit internalStartClose(); - disconnect(this); isOpen.acquire(); + disconnect(this); quit(); wait(); } @@ -36,6 +42,7 @@ void WriteThread::run() connect(this,SIGNAL(internalStartClose()), this,SLOT(internalClose()), Qt::QueuedConnection); connect(this,SIGNAL(internalStartEndOfFile()), this,SLOT(internalEndOfFile()), Qt::QueuedConnection); connect(this,SIGNAL(internalStartFlushAndSeekToZero()), this,SLOT(internalFlushAndSeekToZero()),Qt::QueuedConnection); + connect(this,SIGNAL(internalStartChecksum()), this,SLOT(checkSum()), Qt::QueuedConnection); exec(); } @@ -92,7 +99,10 @@ bool WriteThread::internalOpen() if(stopIt) return false; //try open it - if(file.open(QIODevice::ReadWrite)) + QIODevice::OpenMode flags=QIODevice::ReadWrite; + if(!buffer) + flags|=QIODevice::Unbuffered; + if(file.open(flags)) { if(stopIt) return false; @@ -107,6 +117,7 @@ bool WriteThread::internalOpen() stat=Idle; #endif isOpen.acquire(); + needRemoveTheFile=false; return true; } else @@ -123,7 +134,7 @@ bool WriteThread::internalOpen() } } -void WriteThread::open(const QString &name,const quint64 &startSize) +void WriteThread::open(const QString &name,const quint64 &startSize,const bool &buffer) { ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"["+QString::number(id)+"] open destination: "+name); if(stopIt) @@ -131,6 +142,7 @@ void WriteThread::open(const QString &name,const quint64 &startSize) fakeMode=false; this->name=name; this->startSize=startSize; + this->buffer=buffer; endDetected=false; emit internalStartOpen(); } @@ -170,11 +182,15 @@ bool WriteThread::write(const QByteArray &data) void WriteThread::stop() { ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"["+QString::number(id)+"] stop()"); + needRemoveTheFile=true; stopIt=true; + if(isOpen.available()>0) + return; freeBlock.release(); // useless because stopIt will close all thread, but if thread not runing run it endIsDetected(); - //emit internalStartClose(); + //for the stop for skip: void TransferThread::skip() + emit internalStartClose(); } void WriteThread::flushBuffer() @@ -262,11 +278,20 @@ void WriteThread::internalClose(bool emitSignal) #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Close; #endif - if(!fakeMode) + if(!fakeMode && file.isOpen()) { - if(startSize!=CurentCopiedSize) - file.resize(CurentCopiedSize); + if(!needRemoveTheFile) + { + if(startSize!=CurentCopiedSize) + file.resize(CurentCopiedSize); + } file.close(); + if(needRemoveTheFile) + { + if(file.remove()) + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"["+QString::number(id)+"] unable to remove the destination file"); + } + needRemoveTheFile=false; } #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Idle; @@ -294,6 +319,7 @@ void WriteThread::reopen() { ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"["+QString::number(id)+"] start"); stopIt=true; + endDetected=false; emit internalStartReopen(); } @@ -324,12 +350,150 @@ void WriteThread::fakeWriteIsStopped() emit writeIsStopped(); } +/// do the checksum +void WriteThread::startCheckSum() +{ + emit internalStartChecksum(); +} + +/** \brief set block size +\param block the new block size in KB +\return Return true if succes */ +bool WriteThread::setBlockSize(const int blockSize) +{ + if(blockSize<1 || blockSize>16384) + { + this->blockSize=blockSize*1024; + //set the new max speed because the timer have changed + setMaxSpeed(maxSpeed); + return true; + } + else + return false; +} + +/*! \brief Set the max speed +\param tempMaxSpeed Set the max speed in KB/s, 0 for no limit */ +int WriteThread::setMaxSpeed(const int maxSpeed) +{ + if(this->maxSpeed==0 && maxSpeed==0 && waitNewClockForSpeed.available()>0) + waitNewClockForSpeed.tryAcquire(waitNewClockForSpeed.available()); + this->maxSpeed=maxSpeed; + if(this->maxSpeed>0) + { + int NewInterval,newMultiForBigSpeed=0; + do + { + newMultiForBigSpeed++; + NewInterval=(blockSize*newMultiForBigSpeed)/(this->maxSpeed); + } + while (NewInterval<ULTRACOPIER_PLUGIN_MINTIMERINTERVAL); + if(NewInterval>ULTRACOPIER_PLUGIN_MAXTIMERINTERVAL) + { + NewInterval=ULTRACOPIER_PLUGIN_MAXTIMERINTERVAL; + newMultiForBigSpeed=1; + blockSize=this->maxSpeed*NewInterval; + } + MultiForBigSpeed=newMultiForBigSpeed; + return NewInterval; + } + else + { + waitNewClockForSpeed.release(); + return 0; + } +} + +/// \brief For give timer every X ms +void WriteThread::timeOfTheBlockCopyFinished() +{ + if(waitNewClockForSpeed.available()<ULTRACOPIER_PLUGIN_NUMSEMSPEEDMANAGEMENT) + waitNewClockForSpeed.release(); + //why not just use waitNewClockForSpeed.release() ? +} + void WriteThread::flushAndSeekToZero() { stopIt=true; emit internalStartFlushAndSeekToZero(); } + +void WriteThread::checkSum() +{ + //QByteArray blockArray; + QCryptographicHash hash(QCryptographicHash::Sha1); + endDetected=false; + lastGoodPosition=0; + file.seek(0); + int sizeReaden=0; + do + { + //read one block + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Read; + #endif + blockArray=file.read(blockSize); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + + if(file.error()!=QFile::NoError) + { + errorString_internal=tr("Unable to read the source file: ")+file.errorString()+" ("+QString::number(file.error())+")"; + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"["+QString::number(id)+"] "+QString("file.error()!=QFile::NoError: %1, error: %2").arg(QString::number(file.error())).arg(errorString_internal)); + emit error(); + return; + } + sizeReaden=blockArray.size(); + if(sizeReaden>0) + { + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Checksum; + #endif + hash.addData(blockArray); + #ifdef ULTRACOPIER_PLUGIN_DEBUG + stat=Idle; + #endif + + if(stopIt) + break; + + lastGoodPosition+=blockArray.size(); + + //wait for limitation speed if stop not query + if(maxSpeed>0) + { + numberOfBlockCopied++; + if(numberOfBlockCopied>=MultiForBigSpeed) + { + numberOfBlockCopied=0; + waitNewClockForSpeed.acquire(); + if(stopIt) + break; + } + } + } + } + while(sizeReaden>0 && !stopIt); + if(lastGoodPosition>file.size()) + { + errorString_internal=tr("File truncated during the read, possible data change"); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"["+QString::number(id)+"] "+QString("Source truncated during the read: %1 (%2)").arg(file.errorString()).arg(QString::number(file.error()))); + emit error(); + return; + } + if(stopIt) + { +/* if(putInPause) + emit isInPause();*/ + stopIt=false; + return; + } + emit checksumFinish(hash.result()); + ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"["+QString::number(id)+"] stop the read"); +} + void WriteThread::internalFlushAndSeekToZero() { flushBuffer(); |