|
@@ -8,6 +8,34 @@
|
|
|
//---------------------------------------------------------------------------
|
|
|
#define TRANSFER_BUF_SIZE 32768
|
|
|
//---------------------------------------------------------------------------
|
|
|
+TFileOperationProgressType::TPersistence::TPersistence()
|
|
|
+{
|
|
|
+ Clear(true, true);
|
|
|
+}
|
|
|
+//---------------------------------------------------------------------------
|
|
|
+bool TFileOperationProgressType::IsIndeterminateOperation(TFileOperation Operation)
|
|
|
+{
|
|
|
+ return (Operation == foCalculateSize);
|
|
|
+}
|
|
|
+//---------------------------------------------------------------------------
|
|
|
+void TFileOperationProgressType::TPersistence::Clear(bool Batch, bool Speed)
|
|
|
+{
|
|
|
+ if (Batch)
|
|
|
+ {
|
|
|
+ TotalTransferred = 0;
|
|
|
+ StartTime = Now();
|
|
|
+ SkipToAll = false;
|
|
|
+ BatchOverwrite = boNo;
|
|
|
+ CPSLimit = 0;
|
|
|
+ CounterSet = false;
|
|
|
+ }
|
|
|
+ if (Speed)
|
|
|
+ {
|
|
|
+ Ticks.clear();
|
|
|
+ TotalTransferredThen.clear();
|
|
|
+ }
|
|
|
+}
|
|
|
+//---------------------------------------------------------------------------
|
|
|
__fastcall TFileOperationProgressType::TFileOperationProgressType()
|
|
|
{
|
|
|
FOnProgress = NULL;
|
|
@@ -41,6 +69,8 @@ void __fastcall TFileOperationProgressType::Init()
|
|
|
{
|
|
|
FSection = new TCriticalSection();
|
|
|
FUserSelectionsSection = new TCriticalSection();
|
|
|
+ FRestored = false;
|
|
|
+ FPersistence.Side = osCurrent; // = undefined value
|
|
|
}
|
|
|
//---------------------------------------------------------------------------
|
|
|
void __fastcall TFileOperationProgressType::Assign(const TFileOperationProgressType & Other)
|
|
@@ -62,7 +92,7 @@ void __fastcall TFileOperationProgressType::AssignButKeepSuspendState(const TFil
|
|
|
Assign(Other);
|
|
|
}
|
|
|
//---------------------------------------------------------------------------
|
|
|
-void __fastcall TFileOperationProgressType::Clear()
|
|
|
+void __fastcall TFileOperationProgressType::DoClear(bool Batch, bool Speed)
|
|
|
{
|
|
|
FFileName = L"";
|
|
|
FFullFileName = L"";
|
|
@@ -71,30 +101,28 @@ void __fastcall TFileOperationProgressType::Clear()
|
|
|
FCount = -1;
|
|
|
FFilesFinished = 0;
|
|
|
FFilesFinishedSuccessfully = 0;
|
|
|
- FStartTime = Now();
|
|
|
FSuspended = false;
|
|
|
FSuspendTime = 0;
|
|
|
FInProgress = false;
|
|
|
FDone = false;
|
|
|
FFileInProgress = false;
|
|
|
- FTotalTransferred = 0;
|
|
|
FTotalSkipped = 0;
|
|
|
FTotalSize = 0;
|
|
|
FSkippedSize = 0;
|
|
|
FTotalSizeSet = false;
|
|
|
FOperation = foNone;
|
|
|
FTemp = false;
|
|
|
- FSkipToAll = false;
|
|
|
- FBatchOverwrite = boNo;
|
|
|
+ FPersistence.Clear(Batch, Speed);
|
|
|
// to bypass check in ClearTransfer()
|
|
|
FTransferSize = 0;
|
|
|
- FCPSLimit = 0;
|
|
|
- FTicks.clear();
|
|
|
- FTotalTransferredThen.clear();
|
|
|
- FCounterSet = false;
|
|
|
ClearTransfer();
|
|
|
}
|
|
|
//---------------------------------------------------------------------------
|
|
|
+void __fastcall TFileOperationProgressType::Clear()
|
|
|
+{
|
|
|
+ DoClear(true, true);
|
|
|
+}
|
|
|
+//---------------------------------------------------------------------------
|
|
|
void __fastcall TFileOperationProgressType::ClearTransfer()
|
|
|
{
|
|
|
if ((TransferSize > 0) && (TransferredSize < TransferSize))
|
|
@@ -125,15 +153,16 @@ void __fastcall TFileOperationProgressType::Start(TFileOperation AOperation,
|
|
|
|
|
|
{
|
|
|
TGuard Guard(FSection); // not really needed, just for consistency
|
|
|
- Clear();
|
|
|
+ DoClear(!FRestored, (FPersistence.Side != osCurrent) && (FPersistence.Side != ASide));
|
|
|
+ FTotalTransferBase = FPersistence.TotalTransferred;
|
|
|
FOperation = AOperation;
|
|
|
- FSide = ASide;
|
|
|
+ FPersistence.Side = ASide;
|
|
|
FCount = ACount;
|
|
|
FInProgress = true;
|
|
|
FCancel = csContinue;
|
|
|
FDirectory = ADirectory;
|
|
|
FTemp = ATemp;
|
|
|
- FCPSLimit = ACPSLimit;
|
|
|
+ FPersistence.CPSLimit = ACPSLimit;
|
|
|
}
|
|
|
|
|
|
try
|
|
@@ -194,9 +223,9 @@ void __fastcall TFileOperationProgressType::Resume()
|
|
|
// by the time the progress was suspended
|
|
|
unsigned long Stopped = (GetTickCount() - FSuspendTime);
|
|
|
size_t i = 0;
|
|
|
- while (i < FTicks.size())
|
|
|
+ while (i < FPersistence.Ticks.size())
|
|
|
{
|
|
|
- FTicks[i] += Stopped;
|
|
|
+ FPersistence.Ticks[i] += Stopped;
|
|
|
++i;
|
|
|
}
|
|
|
}
|
|
@@ -236,7 +265,15 @@ int __fastcall TFileOperationProgressType::TotalTransferProgress() const
|
|
|
{
|
|
|
TGuard Guard(FSection);
|
|
|
DebugAssert(TotalSizeSet);
|
|
|
- int Result = FTotalSize > 0 ? (int)(((FTotalTransferred + FTotalSkipped) * 100)/FTotalSize) : 0;
|
|
|
+ int Result;
|
|
|
+ if (FTotalSize > 0)
|
|
|
+ {
|
|
|
+ Result = (int)(((FPersistence.TotalTransferred - FTotalTransferBase + FTotalSkipped) * 100)/FTotalSize);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Result = 0;
|
|
|
+ }
|
|
|
return Result < 100 ? Result : 100;
|
|
|
}
|
|
|
//---------------------------------------------------------------------------
|
|
@@ -328,9 +365,9 @@ bool __fastcall TFileOperationProgressType::IsLocallyDone()
|
|
|
//---------------------------------------------------------------------------
|
|
|
void __fastcall TFileOperationProgressType::SetSpeedCounters()
|
|
|
{
|
|
|
- if ((CPSLimit > 0) && !FCounterSet)
|
|
|
+ if ((CPSLimit > 0) && !FPersistence.CounterSet)
|
|
|
{
|
|
|
- FCounterSet = true;
|
|
|
+ FPersistence.CounterSet = true;
|
|
|
Configuration->Usage->Inc(L"SpeedLimitUses");
|
|
|
}
|
|
|
}
|
|
@@ -510,7 +547,7 @@ unsigned long __fastcall TFileOperationProgressType::GetCPSLimit()
|
|
|
else
|
|
|
{
|
|
|
TGuard Guard(FSection);
|
|
|
- Result = FCPSLimit;
|
|
|
+ Result = FPersistence.CPSLimit;
|
|
|
}
|
|
|
return Result;
|
|
|
}
|
|
@@ -524,7 +561,7 @@ void __fastcall TFileOperationProgressType::SetCPSLimit(unsigned long ACPSLimit)
|
|
|
else
|
|
|
{
|
|
|
TGuard Guard(FSection);
|
|
|
- FCPSLimit = ACPSLimit;
|
|
|
+ FPersistence.CPSLimit = ACPSLimit;
|
|
|
}
|
|
|
}
|
|
|
//---------------------------------------------------------------------------
|
|
@@ -538,7 +575,7 @@ TBatchOverwrite __fastcall TFileOperationProgressType::GetBatchOverwrite()
|
|
|
else
|
|
|
{
|
|
|
TGuard Guard(FSection); // not really needed
|
|
|
- Result = FBatchOverwrite;
|
|
|
+ Result = FPersistence.BatchOverwrite;
|
|
|
}
|
|
|
return Result;
|
|
|
}
|
|
@@ -552,7 +589,7 @@ void __fastcall TFileOperationProgressType::SetBatchOverwrite(TBatchOverwrite AB
|
|
|
else
|
|
|
{
|
|
|
TGuard Guard(FSection); // not really needed
|
|
|
- FBatchOverwrite = ABatchOverwrite;;
|
|
|
+ FPersistence.BatchOverwrite = ABatchOverwrite;;
|
|
|
}
|
|
|
}
|
|
|
//---------------------------------------------------------------------------
|
|
@@ -566,7 +603,7 @@ bool __fastcall TFileOperationProgressType::GetSkipToAll()
|
|
|
else
|
|
|
{
|
|
|
TGuard Guard(FSection); // not really needed
|
|
|
- Result = FSkipToAll;
|
|
|
+ Result = FPersistence.SkipToAll;
|
|
|
}
|
|
|
return Result;
|
|
|
}
|
|
@@ -580,7 +617,7 @@ void __fastcall TFileOperationProgressType::SetSkipToAll()
|
|
|
else
|
|
|
{
|
|
|
TGuard Guard(FSection); // not really needed
|
|
|
- FSkipToAll = true;
|
|
|
+ FPersistence.SkipToAll = true;
|
|
|
}
|
|
|
}
|
|
|
//---------------------------------------------------------------------------
|
|
@@ -600,11 +637,11 @@ void __fastcall TFileOperationProgressType::RollbackTransferFromTotals(__int64 A
|
|
|
{
|
|
|
TGuard Guard(FSection);
|
|
|
|
|
|
- DebugAssert(ATransferredSize <= FTotalTransferred);
|
|
|
+ DebugAssert(ATransferredSize <= FPersistence.TotalTransferred - FTotalTransferBase);
|
|
|
DebugAssert(ASkippedSize <= FTotalSkipped);
|
|
|
- FTotalTransferred -= ATransferredSize;
|
|
|
- FTicks.clear();
|
|
|
- FTotalTransferredThen.clear();
|
|
|
+ FPersistence.TotalTransferred -= ATransferredSize;
|
|
|
+ FPersistence.Ticks.clear();
|
|
|
+ FPersistence.TotalTransferredThen.clear();
|
|
|
FTotalSkipped -= ASkippedSize;
|
|
|
|
|
|
if (FParent != NULL)
|
|
@@ -627,27 +664,27 @@ void __fastcall TFileOperationProgressType::AddTransferredToTotals(__int64 ASize
|
|
|
{
|
|
|
TGuard Guard(FSection);
|
|
|
|
|
|
- FTotalTransferred += ASize;
|
|
|
+ FPersistence.TotalTransferred += ASize;
|
|
|
if (ASize >= 0)
|
|
|
{
|
|
|
unsigned long Ticks = GetTickCount();
|
|
|
- if (FTicks.empty() ||
|
|
|
- (FTicks.back() > Ticks) || // ticks wrap after 49.7 days
|
|
|
- ((Ticks - FTicks.back()) >= MSecsPerSec))
|
|
|
+ if (FPersistence.Ticks.empty() ||
|
|
|
+ (FPersistence.Ticks.back() > Ticks) || // ticks wrap after 49.7 days
|
|
|
+ ((Ticks - FPersistence.Ticks.back()) >= MSecsPerSec))
|
|
|
{
|
|
|
- FTicks.push_back(Ticks);
|
|
|
- FTotalTransferredThen.push_back(FTotalTransferred);
|
|
|
+ FPersistence.Ticks.push_back(Ticks);
|
|
|
+ FPersistence.TotalTransferredThen.push_back(FPersistence.TotalTransferred);
|
|
|
}
|
|
|
|
|
|
- if (FTicks.size() > 10)
|
|
|
+ if (FPersistence.Ticks.size() > 10)
|
|
|
{
|
|
|
- FTicks.erase(FTicks.begin());
|
|
|
- FTotalTransferredThen.erase(FTotalTransferredThen.begin());
|
|
|
+ FPersistence.Ticks.erase(FPersistence.Ticks.begin());
|
|
|
+ FPersistence.TotalTransferredThen.erase(FPersistence.TotalTransferredThen.begin());
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- FTicks.clear();
|
|
|
+ FPersistence.Ticks.clear();
|
|
|
}
|
|
|
|
|
|
if (FParent != NULL)
|
|
@@ -762,7 +799,7 @@ unsigned int __fastcall TFileOperationProgressType::CPS()
|
|
|
unsigned int __fastcall TFileOperationProgressType::GetCPS()
|
|
|
{
|
|
|
unsigned int Result;
|
|
|
- if (FTicks.empty())
|
|
|
+ if (FPersistence.Ticks.empty())
|
|
|
{
|
|
|
Result = 0;
|
|
|
}
|
|
@@ -770,14 +807,14 @@ unsigned int __fastcall TFileOperationProgressType::GetCPS()
|
|
|
{
|
|
|
unsigned long Ticks = (Suspended ? FSuspendTime : GetTickCount());
|
|
|
unsigned long TimeSpan;
|
|
|
- if (Ticks < FTicks.front())
|
|
|
+ if (Ticks < FPersistence.Ticks.front())
|
|
|
{
|
|
|
// clocks has wrapped, guess 10 seconds difference
|
|
|
TimeSpan = 10000;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- TimeSpan = (Ticks - FTicks.front());
|
|
|
+ TimeSpan = (Ticks - FPersistence.Ticks.front());
|
|
|
}
|
|
|
|
|
|
if (TimeSpan == 0)
|
|
@@ -786,7 +823,7 @@ unsigned int __fastcall TFileOperationProgressType::GetCPS()
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- __int64 Transferred = (FTotalTransferred - FTotalTransferredThen.front());
|
|
|
+ __int64 Transferred = (FPersistence.TotalTransferred - FPersistence.TotalTransferredThen.front());
|
|
|
Result = (unsigned int)(Transferred * MSecsPerSec / TimeSpan);
|
|
|
}
|
|
|
}
|
|
@@ -812,10 +849,10 @@ TDateTime __fastcall TFileOperationProgressType::TotalTimeLeft()
|
|
|
DebugAssert(FTotalSizeSet);
|
|
|
unsigned int CurCps = GetCPS();
|
|
|
// sanity check
|
|
|
- if ((CurCps > 0) && (FTotalSize > FTotalSkipped + FTotalTransferred))
|
|
|
+ __int64 Processed = FTotalSkipped + FPersistence.TotalTransferred - FTotalTransferBase;
|
|
|
+ if ((CurCps > 0) && (FTotalSize > Processed))
|
|
|
{
|
|
|
- return TDateTime((double)((double)(FTotalSize - FTotalSkipped - FTotalTransferred) / CurCps) /
|
|
|
- SecsPerDay);
|
|
|
+ return TDateTime((double)((double)(FTotalSize - Processed) / CurCps) / SecsPerDay);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -826,7 +863,7 @@ TDateTime __fastcall TFileOperationProgressType::TotalTimeLeft()
|
|
|
__int64 __fastcall TFileOperationProgressType::GetTotalTransferred()
|
|
|
{
|
|
|
TGuard Guard(FSection);
|
|
|
- return FTotalTransferred;
|
|
|
+ return FPersistence.TotalTransferred;
|
|
|
}
|
|
|
//---------------------------------------------------------------------------
|
|
|
__int64 __fastcall TFileOperationProgressType::GetTotalSize()
|
|
@@ -879,3 +916,17 @@ UnicodeString __fastcall TFileOperationProgressType::GetLogStr(bool Done)
|
|
|
UnicodeString CPSStr = FormatSize(CPS());
|
|
|
return FORMAT(L"Transferred: %s, %s: %s, CPS: %s/s", (Transferred, TimeLabel, TimeStr, CPSStr));
|
|
|
}
|
|
|
+//---------------------------------------------------------------------------
|
|
|
+void __fastcall TFileOperationProgressType::Store(TPersistence & Persistence)
|
|
|
+{
|
|
|
+ // in this current use, we do not need this to be guarded actually, as it's used only for a single-threaded synchronization
|
|
|
+ TGuard Guard(FSection);
|
|
|
+ Persistence = FPersistence;
|
|
|
+}
|
|
|
+//---------------------------------------------------------------------------
|
|
|
+void __fastcall TFileOperationProgressType::Restore(TPersistence & Persistence)
|
|
|
+{
|
|
|
+ TGuard Guard(FSection);
|
|
|
+ FPersistence = Persistence;
|
|
|
+ FRestored = true;
|
|
|
+}
|