FileOperationProgress.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "Common.h"
  5. #include "FileOperationProgress.h"
  6. //---------------------------------------------------------------------------
  7. #define TRANSFER_BUF_SIZE 4096
  8. //---------------------------------------------------------------------------
  9. __fastcall TFileOperationProgressType::TFileOperationProgressType()
  10. {
  11. FOnProgress = NULL;
  12. FOnFinished = NULL;
  13. Clear();
  14. }
  15. //---------------------------------------------------------------------------
  16. __fastcall TFileOperationProgressType::TFileOperationProgressType(
  17. TFileOperationProgressEvent AOnProgress, TFileOperationFinished AOnFinished)
  18. {
  19. FOnProgress = AOnProgress;
  20. FOnFinished = AOnFinished;
  21. Clear();
  22. }
  23. //---------------------------------------------------------------------------
  24. __fastcall TFileOperationProgressType::~TFileOperationProgressType()
  25. {
  26. assert(!InProgress && !Suspended);
  27. }
  28. //---------------------------------------------------------------------------
  29. void __fastcall TFileOperationProgressType::Clear()
  30. {
  31. FileName = "";
  32. AsciiTransfer = false;
  33. ResumeStatus = rsNotAvailable;
  34. Count = 0;
  35. FFilesFinished = 0;
  36. StartTime = Now();
  37. FStopped = 0;
  38. Suspended = false;
  39. FSuspendTime = 0;
  40. InProgress = false;
  41. TotalTransfered = 0;
  42. TotalSkipped = 0;
  43. TotalSize = 0;
  44. TotalSizeSet = false;
  45. Operation = foNone;
  46. Temp = false;
  47. YesToAll = false;
  48. YesToNewer = false;
  49. NoToAll = false;
  50. SkipToAll = false;
  51. AlternateResumeAlways = false;
  52. // to bypass check in ClearTransfer()
  53. TransferSize = 0;
  54. ClearTransfer();
  55. }
  56. //---------------------------------------------------------------------------
  57. void __fastcall TFileOperationProgressType::ClearTransfer()
  58. {
  59. if ((TransferSize > 0) && (TransferedSize < TransferSize))
  60. {
  61. __int64 RemainingSide = (TransferSize - TransferedSize);
  62. TotalSkipped += RemainingSide;
  63. }
  64. LocalSize = 0;
  65. TransferSize = 0;
  66. LocalyUsed = 0;
  67. TransferedSize = 0;
  68. TransferingFile = false;
  69. FFileStopped = 0;
  70. }
  71. //---------------------------------------------------------------------------
  72. void __fastcall TFileOperationProgressType::Start(TFileOperation AOperation,
  73. TOperationSide ASide, int ACount, bool ATemp,
  74. const AnsiString ADirectory)
  75. {
  76. Clear();
  77. Operation = AOperation;
  78. Side = ASide;
  79. Count = ACount;
  80. InProgress = true;
  81. Cancel = csContinue;
  82. Directory = ADirectory;
  83. Temp = ATemp;
  84. DoProgress();
  85. }
  86. //---------------------------------------------------------------------------
  87. void __fastcall TFileOperationProgressType::Reset()
  88. {
  89. InProgress = false;
  90. Suspended = false;
  91. }
  92. //---------------------------------------------------------------------------
  93. void __fastcall TFileOperationProgressType::Stop()
  94. {
  95. // added to include remaining bytes to TotalSkipped, in case
  96. // the progress happes to update before closing
  97. ClearTransfer();
  98. InProgress = false;
  99. DoProgress();
  100. }
  101. //---------------------------------------------------------------------------
  102. void __fastcall TFileOperationProgressType::Suspend()
  103. {
  104. assert(!Suspended);
  105. Suspended = true;
  106. FSuspendTime = Now();
  107. DoProgress();
  108. }
  109. //---------------------------------------------------------------------------
  110. void __fastcall TFileOperationProgressType::Resume()
  111. {
  112. assert(Suspended);
  113. Suspended = false;
  114. TDateTime TimeSuspended = (Now() - FSuspendTime);
  115. // see CPS()
  116. FStopped += TimeSuspended;
  117. FFileStopped += TimeSuspended;
  118. DoProgress();
  119. }
  120. //---------------------------------------------------------------------------
  121. int __fastcall TFileOperationProgressType::OperationProgress()
  122. {
  123. assert(Count);
  124. return (FFilesFinished * 100)/Count;
  125. }
  126. //---------------------------------------------------------------------------
  127. int __fastcall TFileOperationProgressType::TransferProgress()
  128. {
  129. if (TransferSize) return (int)((TransferedSize * 100)/TransferSize);
  130. else return 0;
  131. }
  132. //---------------------------------------------------------------------------
  133. int __fastcall TFileOperationProgressType::TotalTransferProgress()
  134. {
  135. assert(TotalSizeSet);
  136. int Result = TotalSize > 0 ? (int)(((TotalTransfered + TotalSkipped) * 100)/TotalSize) : 0;
  137. return Result < 100 ? Result : 100;
  138. }
  139. //---------------------------------------------------------------------------
  140. int __fastcall TFileOperationProgressType::OverallProgress()
  141. {
  142. if (TotalSizeSet)
  143. {
  144. assert((Operation == foCopy) || (Operation == foMove));
  145. return TotalTransferProgress();
  146. }
  147. else
  148. {
  149. return OperationProgress();
  150. }
  151. }
  152. //---------------------------------------------------------------------------
  153. void __fastcall TFileOperationProgressType::DoProgress()
  154. {
  155. if (FOnProgress) FOnProgress(*this, Cancel);
  156. }
  157. //---------------------------------------------------------------------------
  158. void __fastcall TFileOperationProgressType::Finish(AnsiString FileName,
  159. bool Success, bool & DisconnectWhenComplete)
  160. {
  161. assert(InProgress);
  162. if (FOnFinished)
  163. {
  164. FOnFinished(Operation, Side, Temp, FileName,
  165. /* TODO : There wasn't 'Success' condition, was it by mistake or by purpose? */
  166. Success && (Cancel == csContinue), DisconnectWhenComplete);
  167. }
  168. FFilesFinished++;
  169. DoProgress();
  170. }
  171. //---------------------------------------------------------------------------
  172. void __fastcall TFileOperationProgressType::SetFile(AnsiString AFileName)
  173. {
  174. FileName = AFileName;
  175. ClearTransfer();
  176. FFileStartTime = Now();
  177. DoProgress();
  178. }
  179. //---------------------------------------------------------------------------
  180. void __fastcall TFileOperationProgressType::SetLocalSize(__int64 ASize)
  181. {
  182. LocalSize = ASize;
  183. DoProgress();
  184. }
  185. //---------------------------------------------------------------------------
  186. void __fastcall TFileOperationProgressType::AddLocalyUsed(__int64 ASize)
  187. {
  188. LocalyUsed += ASize;
  189. if (LocalyUsed > LocalSize)
  190. {
  191. LocalSize = LocalyUsed;
  192. }
  193. DoProgress();
  194. }
  195. //---------------------------------------------------------------------------
  196. bool __fastcall TFileOperationProgressType::IsLocalyDone()
  197. {
  198. assert(LocalyUsed <= LocalSize);
  199. return (LocalyUsed == LocalSize);
  200. }
  201. //---------------------------------------------------------------------------
  202. unsigned long __fastcall TFileOperationProgressType::LocalBlockSize()
  203. {
  204. unsigned long Result = TRANSFER_BUF_SIZE;
  205. if (LocalyUsed + Result > LocalSize) Result = (unsigned long)(LocalSize - LocalyUsed);
  206. return Result;
  207. }
  208. //---------------------------------------------------------------------------
  209. void __fastcall TFileOperationProgressType::SetTotalSize(__int64 ASize)
  210. {
  211. TotalSize = ASize;
  212. TotalSizeSet = true;
  213. DoProgress();
  214. }
  215. //---------------------------------------------------------------------------
  216. void __fastcall TFileOperationProgressType::SetTransferSize(__int64 ASize)
  217. {
  218. TransferSize = ASize;
  219. DoProgress();
  220. }
  221. //---------------------------------------------------------------------------
  222. void __fastcall TFileOperationProgressType::ChangeTransferSize(__int64 ASize)
  223. {
  224. // reflect change on file size (due to text transfer mode conversion particulary)
  225. // on total transfer size
  226. if (TotalSizeSet)
  227. {
  228. TotalSize += (ASize - TransferSize);
  229. }
  230. TransferSize = ASize;
  231. DoProgress();
  232. }
  233. //---------------------------------------------------------------------------
  234. void __fastcall TFileOperationProgressType::AddTransfered(__int64 ASize,
  235. bool AddToTotals)
  236. {
  237. TransferedSize += ASize;
  238. if (TransferedSize > TransferSize)
  239. {
  240. // this can happen with SFTP when downloading file that
  241. // grows while being downloaded
  242. if (TotalSizeSet)
  243. {
  244. TotalSize += (TransferedSize - TransferSize);
  245. }
  246. TransferSize = TransferedSize;
  247. }
  248. if (AddToTotals)
  249. {
  250. TotalTransfered += ASize;
  251. }
  252. DoProgress();
  253. }
  254. //---------------------------------------------------------------------------
  255. void __fastcall TFileOperationProgressType::AddResumed(__int64 ASize)
  256. {
  257. TotalSkipped += ASize;
  258. AddTransfered(ASize, false);
  259. AddLocalyUsed(ASize);
  260. }
  261. //---------------------------------------------------------------------------
  262. unsigned long __fastcall TFileOperationProgressType::TransferBlockSize()
  263. {
  264. unsigned long Result = TRANSFER_BUF_SIZE;
  265. if (TransferedSize + Result > TransferSize) Result = (unsigned long)(TransferSize - TransferedSize);
  266. return Result;
  267. }
  268. //---------------------------------------------------------------------------
  269. unsigned long __fastcall TFileOperationProgressType::StaticBlockSize()
  270. {
  271. return TRANSFER_BUF_SIZE;
  272. }
  273. //---------------------------------------------------------------------------
  274. bool __fastcall TFileOperationProgressType::IsTransferDone()
  275. {
  276. assert(TransferedSize <= TransferSize);
  277. return (TransferedSize == TransferSize);
  278. }
  279. //---------------------------------------------------------------------------
  280. void __fastcall TFileOperationProgressType::SetAsciiTransfer(bool AAsciiTransfer)
  281. {
  282. AsciiTransfer = AAsciiTransfer;
  283. DoProgress();
  284. }
  285. //---------------------------------------------------------------------------
  286. void __fastcall TFileOperationProgressType::SetResumeStatus(TResumeStatus AResumeStatus)
  287. {
  288. ResumeStatus = AResumeStatus;
  289. DoProgress();
  290. }
  291. //---------------------------------------------------------------------------
  292. TDateTime __fastcall TFileOperationProgressType::TimeElapsed()
  293. {
  294. return Now() - StartTime;
  295. }
  296. //---------------------------------------------------------------------------
  297. unsigned int __fastcall TFileOperationProgressType::CPS()
  298. {
  299. TDateTime CurTime = Suspended ? FSuspendTime : Now();
  300. TDateTime RealTime = (CurTime - StartTime) - FStopped;
  301. if ((double)RealTime > 0)
  302. {
  303. return TotalTransfered / ((double)RealTime * (24 * 60 * 60));
  304. }
  305. else
  306. {
  307. return 0;
  308. }
  309. }
  310. //---------------------------------------------------------------------------
  311. TDateTime __fastcall TFileOperationProgressType::TimeExpected()
  312. {
  313. unsigned int CurCps = CPS();
  314. if (CurCps) return TDateTime((double)(((double)(TransferSize - TransferedSize)) / CurCps) / (24 * 60 * 60));
  315. else return 0;
  316. }
  317. //---------------------------------------------------------------------------
  318. TDateTime __fastcall TFileOperationProgressType::TotalTimeExpected()
  319. {
  320. assert(TotalSizeSet);
  321. unsigned int CurCps = CPS();
  322. // sanity check
  323. if ((CurCps > 0) && (TotalSize > TotalSkipped))
  324. {
  325. return TDateTime((double)((double)(TotalSize - TotalSkipped) / CurCps) /
  326. (24 * 60 * 60));
  327. }
  328. else
  329. {
  330. return 0;
  331. }
  332. }
  333. //---------------------------------------------------------------------------
  334. TDateTime __fastcall TFileOperationProgressType::TotalTimeLeft()
  335. {
  336. assert(TotalSizeSet);
  337. unsigned int CurCps = CPS();
  338. // sanity check
  339. if ((CurCps > 0) && (TotalSize > TotalSkipped + TotalTransfered))
  340. {
  341. return TDateTime((double)((double)(TotalSize - TotalSkipped - TotalTransfered) / CurCps) /
  342. (24 * 60 * 60));
  343. }
  344. else
  345. {
  346. return 0;
  347. }
  348. }