summaryrefslogtreecommitdiff
path: root/plugins/CopyEngine/Ultracopier-0.3/WriteThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/CopyEngine/Ultracopier-0.3/WriteThread.cpp')
-rw-r--r--plugins/CopyEngine/Ultracopier-0.3/WriteThread.cpp182
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();