| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021 | 
							- //---------------------------------------------------------------------------
 
- #include <vcl.h>
 
- #pragma hdrstop
 
- #include "Common.h"
 
- #include "FileOperationProgress.h"
 
- #include "CoreMain.h"
 
- #include "Interface.h"
 
- //---------------------------------------------------------------------------
 
- #define TRANSFER_BUF_SIZE 32768
 
- //---------------------------------------------------------------------------
 
- TFileOperationStatistics::TFileOperationStatistics()
 
- {
 
-   memset(this, 0, sizeof(*this));
 
- }
 
- //---------------------------------------------------------------------------
 
- //---------------------------------------------------------------------------
 
- TFileOperationProgressType::TPersistence::TPersistence()
 
- {
 
-   FStatistics = NULL;
 
-   Clear(true, true);
 
- }
 
- //---------------------------------------------------------------------------
 
- bool TFileOperationProgressType::IsIndeterminateOperation(TFileOperation Operation)
 
- {
 
-   return (Operation == foCalculateSize);
 
- }
 
- //---------------------------------------------------------------------------
 
- bool TFileOperationProgressType::IsTransferOperation(TFileOperation Operation)
 
- {
 
-   return (Operation == foCopy) || (Operation == foMove);
 
- }
 
- //---------------------------------------------------------------------------
 
- 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;
 
-   FOnFinished = NULL;
 
-   FParent = NULL;
 
-   Init();
 
-   Clear();
 
- }
 
- //---------------------------------------------------------------------------
 
- __fastcall TFileOperationProgressType::TFileOperationProgressType(
 
-   TFileOperationProgressEvent AOnProgress, TFileOperationFinished AOnFinished,
 
-   TFileOperationProgressType * Parent)
 
- {
 
-   FOnProgress = AOnProgress;
 
-   FOnFinished = AOnFinished;
 
-   FParent = Parent;
 
-   FReset = false;
 
-   Init();
 
-   Clear();
 
- }
 
- //---------------------------------------------------------------------------
 
- __fastcall TFileOperationProgressType::~TFileOperationProgressType()
 
- {
 
-   DebugAssert(!InProgress || FReset);
 
-   DebugAssert(!Suspended || FReset);
 
-   SAFE_DESTROY(FSection);
 
-   SAFE_DESTROY(FUserSelectionsSection);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::Init()
 
- {
 
-   FSection = new TCriticalSection();
 
-   FUserSelectionsSection = new TCriticalSection();
 
-   FRestored = false;
 
-   FPersistence.Side = osCurrent; // = undefined value
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::Assign(const TFileOperationProgressType & Other)
 
- {
 
-   TValueRestorer<TCriticalSection *> SectionRestorer(FSection);
 
-   TValueRestorer<TCriticalSection *> UserSelectionsSectionRestorer(FUserSelectionsSection);
 
-   TGuard Guard(FSection);
 
-   TGuard OtherGuard(Other.FSection);
 
-   *this = Other;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::AssignButKeepSuspendState(const TFileOperationProgressType & Other)
 
- {
 
-   TGuard Guard(FSection);
 
-   TValueRestorer<unsigned int> SuspendTimeRestorer(FSuspendTime);
 
-   TValueRestorer<bool> SuspendedRestorer(FSuspended);
 
-   Assign(Other);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::DoClear(bool Batch, bool Speed)
 
- {
 
-   FFileName = L"";
 
-   FFullFileName = L"";
 
-   FDirectory = L"";
 
-   FAsciiTransfer = false;
 
-   FCount = -1;
 
-   FFilesFinished = 0;
 
-   FFilesFinishedSuccessfully = 0;
 
-   FSuspended = false;
 
-   FSuspendTime = 0;
 
-   FInProgress = false;
 
-   FDone = false;
 
-   FFileInProgress = false;
 
-   FTotalSkipped = 0;
 
-   FTotalSize = 0;
 
-   FSkippedSize = 0;
 
-   FTotalSizeSet = false;
 
-   FOperation = foNone;
 
-   FTemp = false;
 
-   FPersistence.Clear(Batch, Speed);
 
-   // to bypass check in ClearTransfer()
 
-   FTransferSize = 0;
 
-   ClearTransfer();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::Clear()
 
- {
 
-   DoClear(true, true);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::ClearTransfer()
 
- {
 
-   if ((TransferSize > 0) && (TransferredSize < TransferSize))
 
-   {
 
-     TGuard Guard(FSection);
 
-     __int64 RemainingSize = (TransferSize - TransferredSize);
 
-     AddSkipped(RemainingSize);
 
-   }
 
-   FLocalSize = 0;
 
-   FTransferSize = 0;
 
-   FLocallyUsed = 0;
 
-   FSkippedSize = 0;
 
-   FTransferredSize = 0;
 
-   FTransferringFile = false;
 
-   FLastSecond = 0;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::Start(TFileOperation AOperation,
 
-   TOperationSide ASide, int ACount)
 
- {
 
-   Start(AOperation, ASide, ACount, false, L"", 0, odoIdle);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::Start(TFileOperation AOperation,
 
-   TOperationSide ASide, int ACount, bool ATemp,
 
-   const UnicodeString ADirectory, unsigned long ACPSLimit, TOnceDoneOperation InitialOnceDoneOperation)
 
- {
 
-   {
 
-     TGuard Guard(FSection); // not really needed, just for consistency
 
-     DoClear(!FRestored, (FPersistence.Side != osCurrent) && (FPersistence.Side != ASide));
 
-     FTotalTransferBase = FPersistence.TotalTransferred;
 
-     FOperation = AOperation;
 
-     FPersistence.Side = ASide;
 
-     FCount = ACount;
 
-     FInProgress = true;
 
-     FCancel = csContinue;
 
-     FDirectory = ADirectory;
 
-     FTemp = ATemp;
 
-     FInitialOnceDoneOperation = InitialOnceDoneOperation;
 
-     FPersistence.CPSLimit = ACPSLimit;
 
-   }
 
-   try
 
-   {
 
-     DoProgress();
 
-   }
 
-   catch (...)
 
-   {
 
-     // connection can be lost during progress callbacks
 
-     ClearTransfer();
 
-     FInProgress = false;
 
-     throw;
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::Reset()
 
- {
 
-   FReset = true;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::Stop()
 
- {
 
-   // added to include remaining bytes to TotalSkipped, in case
 
-   // the progress happens to update before closing
 
-   ClearTransfer();
 
-   FInProgress = false;
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetDone()
 
- {
 
-   FDone = true;
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::Suspend()
 
- {
 
-   {
 
-     TGuard Guard(FSection);
 
-     DebugAssert(!Suspended);
 
-     FSuspended = true;
 
-     FSuspendTime = GetTickCount();
 
-   }
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::Resume()
 
- {
 
-   {
 
-     TGuard Guard(FSection);
 
-     DebugAssert(Suspended);
 
-     FSuspended = false;
 
-     // shift timestamps for CPS calculation in advance
 
-     // by the time the progress was suspended
 
-     unsigned long Stopped = (GetTickCount() - FSuspendTime);
 
-     size_t i = 0;
 
-     while (i < FPersistence.Ticks.size())
 
-     {
 
-       FPersistence.Ticks[i] += Stopped;
 
-       ++i;
 
-     }
 
-   }
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- int __fastcall TFileOperationProgressType::OperationProgress() const
 
- {
 
-   int Result;
 
-   if (FCount > 0)
 
-   {
 
-     Result = (FFilesFinished * 100)/FCount;
 
-   }
 
-   else
 
-   {
 
-     Result = 0;
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- int __fastcall TFileOperationProgressType::TransferProgress()
 
- {
 
-   int Result;
 
-   if (TransferSize)
 
-   {
 
-     Result = (int)((TransferredSize * 100)/TransferSize);
 
-   }
 
-   else
 
-   {
 
-     Result = 0;
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- int __fastcall TFileOperationProgressType::TotalTransferProgress() const
 
- {
 
-   TGuard Guard(FSection);
 
-   DebugAssert(TotalSizeSet);
 
-   int Result;
 
-   if (FTotalSize > 0)
 
-   {
 
-     Result = (int)(((FPersistence.TotalTransferred - FTotalTransferBase + FTotalSkipped) * 100)/FTotalSize);
 
-   }
 
-   else
 
-   {
 
-     Result = 0;
 
-   }
 
-   return Result < 100 ? Result : 100;
 
- }
 
- //---------------------------------------------------------------------------
 
- int __fastcall TFileOperationProgressType::OverallProgress() const
 
- {
 
-   if (TotalSizeSet)
 
-   {
 
-     DebugAssert(IsTransfer());
 
-     return TotalTransferProgress();
 
-   }
 
-   else
 
-   {
 
-     return OperationProgress();
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::Progress()
 
- {
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::DoProgress()
 
- {
 
-   SystemRequired();
 
-   FOnProgress(*this);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::Finish(UnicodeString FileName,
 
-   bool Success, TOnceDoneOperation & OnceDoneOperation)
 
- {
 
-   DebugAssert(InProgress);
 
-   // Cancel reader is guarded
 
-   FOnFinished(Operation, Side, Temp, FileName,
 
-     Success && (Cancel == csContinue), OnceDoneOperation);
 
-   FFilesFinished++;
 
-   if (Success)
 
-   {
 
-     FFilesFinishedSuccessfully++;
 
-   }
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::Succeeded(int Count)
 
- {
 
-   if (FPersistence.Statistics != NULL)
 
-   {
 
-     if (IsTransfer())
 
-     {
 
-       __int64 Transferred = FTransferredSize - FSkippedSize;
 
-       if (Side == osLocal)
 
-       {
 
-         FPersistence.Statistics->FilesUploaded += Count;
 
-         FPersistence.Statistics->TotalUploaded += Transferred;
 
-       }
 
-       else
 
-       {
 
-         FPersistence.Statistics->FilesDownloaded += Count;
 
-         FPersistence.Statistics->TotalDownloaded += Transferred;
 
-       }
 
-     }
 
-     else if (Operation == foDelete)
 
-     {
 
-       if (Side == osLocal)
 
-       {
 
-         FPersistence.Statistics->FilesDeletedLocal += Count;
 
-       }
 
-       else
 
-       {
 
-         FPersistence.Statistics->FilesDeletedRemote += Count;
 
-       }
 
-     }
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetFile(UnicodeString AFileName, bool AFileInProgress)
 
- {
 
-   FFullFileName = AFileName;
 
-   if (Side == osRemote)
 
-   {
 
-     // historically set were passing filename-only for remote site operations,
 
-     // now we need to collect a full paths, so we pass in full path,
 
-     // but still want to have filename-only in FileName
 
-     AFileName = UnixExtractFileName(AFileName);
 
-   }
 
-   FFileName = AFileName;
 
-   FFileInProgress = AFileInProgress;
 
-   ClearTransfer();
 
-   FFileStartTime = Now();
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetFileInProgress()
 
- {
 
-   DebugAssert(!FileInProgress);
 
-   FFileInProgress = true;
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetLocalSize(__int64 ASize)
 
- {
 
-   FLocalSize = ASize;
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::AddLocallyUsed(__int64 ASize)
 
- {
 
-   FLocallyUsed += ASize;
 
-   if (LocallyUsed > LocalSize)
 
-   {
 
-     FLocalSize = LocallyUsed;
 
-   }
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall TFileOperationProgressType::IsLocallyDone()
 
- {
 
-   DebugAssert(LocallyUsed <= LocalSize);
 
-   return (LocallyUsed == LocalSize);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetSpeedCounters()
 
- {
 
-   if ((CPSLimit > 0) && !FPersistence.CounterSet)
 
-   {
 
-     FPersistence.CounterSet = true;
 
-     Configuration->Usage->Inc(L"SpeedLimitUses");
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- // Used in WebDAV and S3 protocols
 
- void __fastcall TFileOperationProgressType::ThrottleToCPSLimit(
 
-   unsigned long Size)
 
- {
 
-   unsigned long Remaining = Size;
 
-   while (Remaining > 0)
 
-   {
 
-     Remaining -= AdjustToCPSLimit(Remaining);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- unsigned long __fastcall TFileOperationProgressType::AdjustToCPSLimit(
 
-   unsigned long Size)
 
- {
 
-   SetSpeedCounters();
 
-   // CPSLimit reader is guarded, we cannot block whole method as it can last long.
 
-   if (CPSLimit > 0)
 
-   {
 
-     // we must not return 0, hence, if we reach zero,
 
-     // we wait until the next second
 
-     do
 
-     {
 
-       unsigned int Second = (GetTickCount() / MSecsPerSec);
 
-       if (Second != FLastSecond)
 
-       {
 
-         FRemainingCPS = CPSLimit;
 
-         FLastSecond = Second;
 
-       }
 
-       if (FRemainingCPS == 0)
 
-       {
 
-         SleepEx(100, true);
 
-         DoProgress();
 
-       }
 
-     }
 
-     while ((CPSLimit > 0) && (FRemainingCPS == 0));
 
-     // CPSLimit may have been dropped in DoProgress
 
-     if (CPSLimit > 0)
 
-     {
 
-       if (FRemainingCPS < Size)
 
-       {
 
-         Size = FRemainingCPS;
 
-       }
 
-       FRemainingCPS -= Size;
 
-     }
 
-   }
 
-   return Size;
 
- }
 
- //---------------------------------------------------------------------------
 
- // Use in SCP protocol only
 
- unsigned long __fastcall TFileOperationProgressType::LocalBlockSize()
 
- {
 
-   unsigned long Result = TRANSFER_BUF_SIZE;
 
-   if (LocallyUsed + Result > LocalSize)
 
-   {
 
-     Result = (unsigned long)(LocalSize - LocallyUsed);
 
-   }
 
-   Result = AdjustToCPSLimit(Result);
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetTotalSize(__int64 ASize)
 
- {
 
-   TGuard Guard(FSection); // not really needed, just for consistency
 
-   FTotalSize = ASize;
 
-   FTotalSizeSet = true;
 
-   // parent has its own totals
 
-   if (FParent != NULL)
 
-   {
 
-     DebugAssert(FParent->TotalSizeSet);
 
-   }
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetTransferSize(__int64 ASize)
 
- {
 
-   FTransferSize = ASize;
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetTransferringFile(bool ATransferringFile)
 
- {
 
-   FTransferringFile = ATransferringFile;
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall TFileOperationProgressType::PassCancelToParent(TCancelStatus ACancel)
 
- {
 
-   bool Result;
 
-   if (ACancel < csCancel)
 
-   {
 
-     // do not propagate csCancelFile,
 
-     // though it's not supported for queue atm, so we do not expect it here
 
-     DebugFail();
 
-     Result = false;
 
-   }
 
-   else if (ACancel == csCancel)
 
-   {
 
-     Result = true;
 
-   }
 
-   else
 
-   {
 
-     // csCancelTransfer and csRemoteAbort are used with SCP only, which does not use parallel transfers
 
-     DebugFail();
 
-     Result = false;
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetCancel(TCancelStatus ACancel)
 
- {
 
-   TGuard Guard(FSection);
 
-   FCancel = ACancel;
 
-   if ((FParent != NULL) && PassCancelToParent(ACancel))
 
-   {
 
-     FParent->SetCancel(ACancel);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetCancelAtLeast(TCancelStatus ACancel)
 
- {
 
-   TGuard Guard(FSection);
 
-   if (FCancel < ACancel)
 
-   {
 
-     FCancel = ACancel;
 
-   }
 
-   if ((FParent != NULL) && PassCancelToParent(ACancel))
 
-   {
 
-     FParent->SetCancelAtLeast(ACancel);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- TCancelStatus __fastcall TFileOperationProgressType::GetCancel()
 
- {
 
-   TCancelStatus Result = FCancel;
 
-   if (FParent != NULL)
 
-   {
 
-     TGuard Guard(FSection);
 
-     TCancelStatus ParentCancel = FParent->Cancel;
 
-     if (ParentCancel > Result)
 
-     {
 
-       Result = ParentCancel;
 
-     }
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall TFileOperationProgressType::ClearCancelFile()
 
- {
 
-   TGuard Guard(FSection);
 
-   // Not propagated to parent, as this is local flag, see also PassCancelToParent
 
-   bool Result = (Cancel == csCancelFile);
 
-   if (Result)
 
-   {
 
-     FCancel = csContinue;
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- unsigned long __fastcall TFileOperationProgressType::GetCPSLimit()
 
- {
 
-   unsigned int Result;
 
-   if (FParent != NULL)
 
-   {
 
-     Result = FParent->CPSLimit;
 
-   }
 
-   else
 
-   {
 
-     TGuard Guard(FSection);
 
-     Result = FPersistence.CPSLimit;
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetCPSLimit(unsigned long ACPSLimit)
 
- {
 
-   if (FParent != NULL)
 
-   {
 
-     FParent->SetCPSLimit(ACPSLimit);
 
-   }
 
-   else
 
-   {
 
-     TGuard Guard(FSection);
 
-     FPersistence.CPSLimit = ACPSLimit;
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- TBatchOverwrite __fastcall TFileOperationProgressType::GetBatchOverwrite()
 
- {
 
-   TBatchOverwrite Result;
 
-   if (FParent != NULL)
 
-   {
 
-     Result = FParent->BatchOverwrite;
 
-   }
 
-   else
 
-   {
 
-     TGuard Guard(FSection); // not really needed
 
-     Result = FPersistence.BatchOverwrite;
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetBatchOverwrite(TBatchOverwrite ABatchOverwrite)
 
- {
 
-   if (FParent != NULL)
 
-   {
 
-     FParent->SetBatchOverwrite(ABatchOverwrite);
 
-   }
 
-   else
 
-   {
 
-     TGuard Guard(FSection); // not really needed
 
-     FPersistence.BatchOverwrite = ABatchOverwrite;;
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- bool __fastcall TFileOperationProgressType::GetSkipToAll()
 
- {
 
-   bool Result;
 
-   if (FParent != NULL)
 
-   {
 
-     Result = FParent->SkipToAll;
 
-   }
 
-   else
 
-   {
 
-     TGuard Guard(FSection); // not really needed
 
-     Result = FPersistence.SkipToAll;
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetSkipToAll()
 
- {
 
-   if (FParent != NULL)
 
-   {
 
-     FParent->SetSkipToAll();
 
-   }
 
-   else
 
-   {
 
-     TGuard Guard(FSection); // not really needed
 
-     FPersistence.SkipToAll = true;
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::ChangeTransferSize(__int64 ASize)
 
- {
 
-   // reflect change on file size (due to text transfer mode conversion particularly)
 
-   // on total transfer size
 
-   if (TotalSizeSet)
 
-   {
 
-     AddTotalSize(ASize - TransferSize);
 
-   }
 
-   FTransferSize = ASize;
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::RollbackTransferFromTotals(__int64 ATransferredSize, __int64 ASkippedSize)
 
- {
 
-   TGuard Guard(FSection);
 
-   DebugAssert(ATransferredSize <= FPersistence.TotalTransferred - FTotalTransferBase);
 
-   DebugAssert(ASkippedSize <= FTotalSkipped);
 
-   FPersistence.TotalTransferred -= ATransferredSize;
 
-   FPersistence.Ticks.clear();
 
-   FPersistence.TotalTransferredThen.clear();
 
-   FTotalSkipped -= ASkippedSize;
 
-   if (FParent != NULL)
 
-   {
 
-     FParent->RollbackTransferFromTotals(ATransferredSize, ASkippedSize);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::RollbackTransfer()
 
- {
 
-   FTransferredSize -= FSkippedSize;
 
-   RollbackTransferFromTotals(FTransferredSize, FSkippedSize);
 
-   FSkippedSize = 0;
 
-   FTransferredSize = 0;
 
-   FTransferSize = 0;
 
-   FLocallyUsed = 0;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::AddTransferredToTotals(__int64 ASize)
 
- {
 
-   TGuard Guard(FSection);
 
-   FPersistence.TotalTransferred += ASize;
 
-   if (ASize >= 0)
 
-   {
 
-     unsigned long Ticks = GetTickCount();
 
-     if (FPersistence.Ticks.empty() ||
 
-         (FPersistence.Ticks.back() > Ticks) || // ticks wrap after 49.7 days
 
-         ((Ticks - FPersistence.Ticks.back()) >= MSecsPerSec))
 
-     {
 
-       FPersistence.Ticks.push_back(Ticks);
 
-       FPersistence.TotalTransferredThen.push_back(FPersistence.TotalTransferred);
 
-     }
 
-     if (FPersistence.Ticks.size() > 10)
 
-     {
 
-       FPersistence.Ticks.erase(FPersistence.Ticks.begin());
 
-       FPersistence.TotalTransferredThen.erase(FPersistence.TotalTransferredThen.begin());
 
-     }
 
-   }
 
-   else
 
-   {
 
-     FPersistence.Ticks.clear();
 
-   }
 
-   if (FParent != NULL)
 
-   {
 
-     FParent->AddTransferredToTotals(ASize);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::AddTotalSize(__int64 ASize)
 
- {
 
-   if (ASize != 0)
 
-   {
 
-     TGuard Guard(FSection);
 
-     FTotalSize += ASize;
 
-     if (FParent != NULL)
 
-     {
 
-       FParent->AddTotalSize(ASize);
 
-     }
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::AddTransferred(__int64 ASize,
 
-   bool AddToTotals)
 
- {
 
-   FTransferredSize += ASize;
 
-   if (TransferredSize > TransferSize)
 
-   {
 
-     // this can happen with SFTP when downloading file that
 
-     // grows while being downloaded
 
-     if (TotalSizeSet)
 
-     {
 
-       // we should probably guard this with AddToTotals
 
-       AddTotalSize(TransferredSize - TransferSize);
 
-     }
 
-     FTransferSize = TransferredSize;
 
-   }
 
-   if (AddToTotals)
 
-   {
 
-     AddTransferredToTotals(ASize);
 
-   }
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::AddSkipped(__int64 ASize)
 
- {
 
-   TGuard Guard(FSection);
 
-   FTotalSkipped += ASize;
 
-   if (FParent != NULL)
 
-   {
 
-     FParent->AddSkipped(ASize);
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::AddResumed(__int64 ASize)
 
- {
 
-   AddSkipped(ASize);
 
-   FSkippedSize += ASize;
 
-   AddTransferred(ASize, false);
 
-   AddLocallyUsed(ASize);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::AddSkippedFileSize(__int64 ASize)
 
- {
 
-   AddSkipped(ASize);
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- // Use in SCP protocol only
 
- unsigned long __fastcall TFileOperationProgressType::TransferBlockSize()
 
- {
 
-   unsigned long Result = TRANSFER_BUF_SIZE;
 
-   if (TransferredSize + Result > TransferSize)
 
-   {
 
-     Result = (unsigned long)(TransferSize - TransferredSize);
 
-   }
 
-   Result = AdjustToCPSLimit(Result);
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- unsigned long __fastcall TFileOperationProgressType::StaticBlockSize()
 
- {
 
-   return TRANSFER_BUF_SIZE;
 
- }
 
- //---------------------------------------------------------------------------
 
- bool TFileOperationProgressType::IsTransferDoneChecked()
 
- {
 
-   DebugAssert(TransferredSize <= TransferSize);
 
-   return IsTransferDone();
 
- }
 
- //---------------------------------------------------------------------------
 
- // Note that this does not work correctly, if the file is larger than expected (at least with the FTP protocol)
 
- bool TFileOperationProgressType::IsTransferDone()
 
- {
 
-   return (TransferredSize == TransferSize);
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::SetAsciiTransfer(bool AAsciiTransfer)
 
- {
 
-   FAsciiTransfer = AAsciiTransfer;
 
-   DoProgress();
 
- }
 
- //---------------------------------------------------------------------------
 
- TDateTime __fastcall TFileOperationProgressType::TimeElapsed()
 
- {
 
-   return Now() - StartTime;
 
- }
 
- //---------------------------------------------------------------------------
 
- unsigned int __fastcall TFileOperationProgressType::CPS()
 
- {
 
-   TGuard Guard(FSection);
 
-   return GetCPS();
 
- }
 
- //---------------------------------------------------------------------------
 
- inline static unsigned int CalculateCPS(__int64 Transferred, unsigned int MSecElapsed)
 
- {
 
-   unsigned int Result;
 
-   if (MSecElapsed == 0)
 
-   {
 
-     Result = 0;
 
-   }
 
-   else
 
-   {
 
-     Result = (unsigned int)(Transferred * MSecsPerSec / MSecElapsed);
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- // Has to be called from a guarded method
 
- unsigned int __fastcall TFileOperationProgressType::GetCPS()
 
- {
 
-   unsigned int Result;
 
-   if (FPersistence.Ticks.empty())
 
-   {
 
-     Result = 0;
 
-   }
 
-   else
 
-   {
 
-     unsigned long Ticks = (Suspended ? FSuspendTime : GetTickCount());
 
-     unsigned long TimeSpan;
 
-     if (Ticks < FPersistence.Ticks.front())
 
-     {
 
-       // clocks has wrapped, guess 10 seconds difference
 
-       TimeSpan = 10000;
 
-     }
 
-     else
 
-     {
 
-       TimeSpan = (Ticks - FPersistence.Ticks.front());
 
-     }
 
-     __int64 Transferred = (FPersistence.TotalTransferred - FPersistence.TotalTransferredThen.front());
 
-     Result = CalculateCPS(Transferred, TimeSpan);
 
-   }
 
-   return Result;
 
- }
 
- //---------------------------------------------------------------------------
 
- TDateTime __fastcall TFileOperationProgressType::TimeExpected()
 
- {
 
-   unsigned int CurCps = CPS();
 
-   if (CurCps)
 
-   {
 
-     return TDateTime((double)(((double)(TransferSize - TransferredSize)) / CurCps) / SecsPerDay);
 
-   }
 
-   else
 
-   {
 
-     return 0;
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- TDateTime __fastcall TFileOperationProgressType::TotalTimeLeft()
 
- {
 
-   TGuard Guard(FSection);
 
-   DebugAssert(FTotalSizeSet);
 
-   unsigned int CurCps = GetCPS();
 
-   // sanity check
 
-   __int64 Processed = FTotalSkipped + FPersistence.TotalTransferred - FTotalTransferBase;
 
-   if ((CurCps > 0) && (FTotalSize > Processed))
 
-   {
 
-     return TDateTime((double)((double)(FTotalSize - Processed) / CurCps) / SecsPerDay);
 
-   }
 
-   else
 
-   {
 
-     return 0;
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- __int64 __fastcall TFileOperationProgressType::GetTotalTransferred()
 
- {
 
-   TGuard Guard(FSection);
 
-   return FPersistence.TotalTransferred;
 
- }
 
- //---------------------------------------------------------------------------
 
- __int64 __fastcall TFileOperationProgressType::GetOperationTransferred() const
 
- {
 
-   TGuard Guard(FSection);
 
-   return FPersistence.TotalTransferred - FTotalTransferBase + FTotalSkipped;
 
- }
 
- //---------------------------------------------------------------------------
 
- __int64 __fastcall TFileOperationProgressType::GetTotalSize()
 
- {
 
-   TGuard Guard(FSection);
 
-   return FTotalSize;
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::LockUserSelections()
 
- {
 
-   if (FParent != NULL)
 
-   {
 
-     FParent->LockUserSelections();
 
-   }
 
-   else
 
-   {
 
-     FUserSelectionsSection->Enter();
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- void __fastcall TFileOperationProgressType::UnlockUserSelections()
 
- {
 
-   if (FParent != NULL)
 
-   {
 
-     FParent->UnlockUserSelections();
 
-   }
 
-   else
 
-   {
 
-     FUserSelectionsSection->Leave();
 
-   }
 
- }
 
- //---------------------------------------------------------------------------
 
- UnicodeString __fastcall TFileOperationProgressType::GetLogStr(bool Done)
 
- {
 
-   UnicodeString Transferred = FormatSize(TotalTransferred);
 
-   TDateTime Time;
 
-   UnicodeString TimeLabel;
 
-   if (!Done && TotalSizeSet)
 
-   {
 
-     Time = TotalTimeLeft();
 
-     TimeLabel = L"Left";
 
-   }
 
-   else
 
-   {
 
-     Time = TimeElapsed();
 
-     TimeLabel = L"Elapsed";
 
-   }
 
-   UnicodeString TimeStr = FormatDateTimeSpan(Time);
 
-   unsigned int ACPS;
 
-   if (!Done)
 
-   {
 
-     ACPS = CPS();
 
-   }
 
-   else
 
-   {
 
-     unsigned int Elapsed = TimeToMSec(TimeElapsed());
 
-     ACPS = CalculateCPS(TotalTransferred, Elapsed);
 
-   }
 
-   UnicodeString CPSStr = FormatSize(ACPS);
 
-   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;
 
- }
 
- //---------------------------------------------------------------------------
 
- bool TFileOperationProgressType::IsIndeterminate() const
 
- {
 
-   return
 
-     IsIndeterminateOperation(FOperation) ||
 
-     (!TotalSizeSet && (FCount == 1));
 
- }
 
- //---------------------------------------------------------------------------
 
- bool TFileOperationProgressType::IsTransfer() const
 
- {
 
-   return IsTransferOperation(Operation);
 
- }
 
 
  |