Index: src/libchcore/TLocalFilesystem.cpp =================================================================== diff -u -N -r2fe97a93f21771d75901d4b6559057d1ea055104 -r16df8fcf9d5b3317338aece64762771419beaf4a --- src/libchcore/TLocalFilesystem.cpp (.../TLocalFilesystem.cpp) (revision 2fe97a93f21771d75901d4b6559057d1ea055104) +++ src/libchcore/TLocalFilesystem.cpp (.../TLocalFilesystem.cpp) (revision 16df8fcf9d5b3317338aece64762771419beaf4a) @@ -459,4 +459,21 @@ m_hFile = INVALID_HANDLE_VALUE; } +unsigned long long TLocalFilesystemFile::GetFileSize() const +{ + if(!IsOpen()) + return 0; + + BY_HANDLE_FILE_INFORMATION bhfi; + + if(!::GetFileInformationByHandle(m_hFile, &bhfi)) + return 0; + + ULARGE_INTEGER uli; + uli.HighPart = bhfi.nFileSizeHigh; + uli.LowPart = bhfi.nFileSizeLow; + + return uli.QuadPart; +} + END_CHCORE_NAMESPACE Index: src/libchcore/TLocalFilesystem.h =================================================================== diff -u -N -ra5aa3c3cb78f3767641de2627d1a49a1dc35b429 -r16df8fcf9d5b3317338aece64762771419beaf4a --- src/libchcore/TLocalFilesystem.h (.../TLocalFilesystem.h) (revision a5aa3c3cb78f3767641de2627d1a49a1dc35b429) +++ src/libchcore/TLocalFilesystem.h (.../TLocalFilesystem.h) (revision 16df8fcf9d5b3317338aece64762771419beaf4a) @@ -121,6 +121,7 @@ bool WriteFile(TSimpleDataBuffer& rBuffer, DWORD dwToWrite, DWORD& rdwBytesWritten); bool IsOpen() const { return m_hFile != INVALID_HANDLE_VALUE; } + unsigned long long GetFileSize() const; void Close(); Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -N -rd76d3ce6c8c55fa23009dbb03b8bc06f482c5b72 -r16df8fcf9d5b3317338aece64762771419beaf4a --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision d76d3ce6c8c55fa23009dbb03b8bc06f482c5b72) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 16df8fcf9d5b3317338aece64762771419beaf4a) @@ -378,13 +378,34 @@ listEmptyBuffers.push_back(spBuffer); + unsigned long long ullCITotalSize = m_tSubTaskStats.GetCurrentItemTotalSize(); + unsigned long long ullCIProcessedSize = m_tSubTaskStats.GetCurrentItemProcessedSize(); + + if(ullCIProcessedSize + ulWritten > ullCITotalSize) + { + // total size changed + pData->spSrcFile->SetLength64(ullCIProcessedSize + ulWritten); + m_tSubTaskStats.IncreaseCurrentItemTotalSize(ullCIProcessedSize + ulWritten - ullCITotalSize); + m_tSubTaskStats.IncreaseTotalSize(ullCIProcessedSize + ulWritten - ullCITotalSize); + } + // new stats m_tSubTaskStats.IncreaseProcessedSize(ulWritten); m_tSubTaskStats.IncreaseCurrentItemProcessedSize(ulWritten); } } while(!bLastPart); + // fix the stats for files shorter than expected + unsigned long long ullCITotalSize = m_tSubTaskStats.GetCurrentItemTotalSize(); + unsigned long long ullCIProcessedSize = m_tSubTaskStats.GetCurrentItemProcessedSize(); + if(ullCIProcessedSize < ullCITotalSize) + { + pData->spSrcFile->SetLength64(ullCIProcessedSize); + m_tSubTaskStats.DecreaseCurrentItemTotalSize(ullCITotalSize - ullCIProcessedSize); + m_tSubTaskStats.DecreaseTotalSize(ullCITotalSize - ullCIProcessedSize); + } + pData->bProcessed = true; m_tSubTaskStats.SetCurrentItemProcessedSize(0); @@ -414,6 +435,29 @@ return TSubTaskBase::eSubResult_Continue; } + // update the source file size (it might differ from the time this file was originally scanned). + // NOTE: this kind of update could be also done when copying chunks of data beyond the original end-of-file, + // but it would require frequent total size updates and thus - serializations). + // NOTE2: the by-chunk corrections of stats are still applied when copying to ensure even further size + // matching; this update however still allows for better serialization management. + unsigned long long ullNewSize = fileSrc.GetFileSize(); + unsigned long long ullOldSize = pData->spSrcFile->GetLength64(); + if(ullNewSize != ullOldSize) + { + if(ullNewSize > ullOldSize) + { + m_tSubTaskStats.IncreaseTotalSize(ullNewSize - ullOldSize); + m_tSubTaskStats.IncreaseCurrentItemTotalSize(ullNewSize - ullOldSize); + } + else + { + m_tSubTaskStats.DecreaseTotalSize(ullOldSize - ullNewSize); + m_tSubTaskStats.DecreaseCurrentItemTotalSize(ullOldSize - ullNewSize); + } + + pData->spSrcFile->SetLength64(ullNewSize); + } + // change attributes of a dest file // NOTE: probably should be removed from here and report problems with read-only files // directly to the user (as feedback request) Index: src/libchcore/TSubTaskStatsInfo.cpp =================================================================== diff -u -N -rd76d3ce6c8c55fa23009dbb03b8bc06f482c5b72 -r16df8fcf9d5b3317338aece64762771419beaf4a --- src/libchcore/TSubTaskStatsInfo.cpp (.../TSubTaskStatsInfo.cpp) (revision d76d3ce6c8c55fa23009dbb03b8bc06f482c5b72) +++ src/libchcore/TSubTaskStatsInfo.cpp (.../TSubTaskStatsInfo.cpp) (revision 16df8fcf9d5b3317338aece64762771419beaf4a) @@ -449,4 +449,28 @@ return m_setModifications[eMod_Added]; } +void TSubTaskStatsInfo::IncreaseTotalSize(unsigned long long ullIncreaseBy) +{ + boost::unique_lock lock(m_lock); + m_ullTotalSize = m_ullTotalSize + ullIncreaseBy; +} + +void TSubTaskStatsInfo::DecreaseTotalSize(unsigned long long ullDecreaseBy) +{ + boost::unique_lock lock(m_lock); + m_ullTotalSize = m_ullTotalSize - ullDecreaseBy; +} + +void TSubTaskStatsInfo::IncreaseCurrentItemTotalSize(unsigned long long ullIncreaseBy) +{ + boost::unique_lock lock(m_lock); + m_ullCurrentItemTotalSize = m_ullCurrentItemTotalSize + ullIncreaseBy; +} + +void TSubTaskStatsInfo::DecreaseCurrentItemTotalSize(unsigned long long ullDecreaseBy) +{ + boost::unique_lock lock(m_lock); + m_ullCurrentItemTotalSize = m_ullCurrentItemTotalSize - ullDecreaseBy; +} + END_CHCORE_NAMESPACE Index: src/libchcore/TSubTaskStatsInfo.h =================================================================== diff -u -N -rd76d3ce6c8c55fa23009dbb03b8bc06f482c5b72 -r16df8fcf9d5b3317338aece64762771419beaf4a --- src/libchcore/TSubTaskStatsInfo.h (.../TSubTaskStatsInfo.h) (revision d76d3ce6c8c55fa23009dbb03b8bc06f482c5b72) +++ src/libchcore/TSubTaskStatsInfo.h (.../TSubTaskStatsInfo.h) (revision 16df8fcf9d5b3317338aece64762771419beaf4a) @@ -82,13 +82,17 @@ void DecreaseProcessedSize(unsigned long long ullDecreaseBy); void SetProcessedSize(unsigned long long ullProcessedSize); + void IncreaseTotalSize(unsigned long long ullIncreaseBy); + void DecreaseTotalSize(unsigned long long ullDecreaseBy); void SetTotalSize(unsigned long long ullTotalSize); // current item void IncreaseCurrentItemProcessedSize(unsigned long long ullIncreaseBy); void DecreaseCurrentItemProcessedSize(unsigned long long ullDecreaseBy); void SetCurrentItemProcessedSize(unsigned long long ullProcessedSize); + void IncreaseCurrentItemTotalSize(unsigned long long ullIncreaseBy); + void DecreaseCurrentItemTotalSize(unsigned long long ullDecreaseBy); void SetCurrentItemTotalSize(unsigned long long ullTotalSize); unsigned long long GetCurrentItemProcessedSize() const;