Index: src/libchcore/TSubTaskFastMove.cpp =================================================================== diff -u -N -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rd468098a278a0d16c5b700236ea276b9c9677c9f --- src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3) +++ src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision d468098a278a0d16c5b700236ea276b9c9677c9f) @@ -39,6 +39,7 @@ #include "TScopedRunningTimeTracker.h" #include "TFeedbackHandlerWrapper.h" #include "TBufferSizes.h" +#include "TFileException.h" namespace chcore { @@ -91,8 +92,6 @@ // add everything TString strFormat; - bool bRetry = true; - bool bSkipInputPath = false; file_count_t fcSize = spBasePaths->GetCount(); file_count_t fcIndex = m_tSubTaskStats.GetCurrentIndex(); @@ -114,42 +113,12 @@ continue; TFileInfoPtr spFileInfo(boost::make_shared()); - bSkipInputPath = false; - // try to get some info about the input path; let user know if the path does not exist. - do - { - bRetry = false; - // read attributes of src file/folder - bool bExists = spFilesystem->GetFileInfo(pathCurrent, spFileInfo, spBasePath); - if (!bExists) - { - EFeedbackResult frResult = spFeedbackHandler->FileError(pathCurrent.ToWString(), TString(), EFileError::eFastMoveError, ERROR_FILE_NOT_FOUND); - switch (frResult) - { - case EFeedbackResult::eResult_Cancel: - return eSubResult_CancelRequest; - - case EFeedbackResult::eResult_Retry: - bRetry = true; - break; - - case EFeedbackResult::eResult_Pause: - return eSubResult_PauseRequest; - - case EFeedbackResult::eResult_Skip: - bSkipInputPath = true; - break; // just do nothing - - default: - BOOST_ASSERT(FALSE); // unknown result - THROW_CORE_EXCEPTION(eErr_UnhandledCase); - } - } - } while (bRetry); - - // if we have chosen to skip the input path then there's nothing to do - if (bSkipInputPath) + bool bSkip = false; + ESubOperationResult eResult = GetFileInfoFB(spFeedbackHandler, pathCurrent, spFileInfo, spBasePath, bSkip); + if (eResult != TSubTaskBase::eSubResult_Continue) + return eResult; + else if (bSkip) continue; // does it match the input filter? @@ -160,64 +129,17 @@ } // try to fast move - bRetry = true; - bool bResult = true; - do - { - TSmartPath pathDestinationPath = CalculateDestinationPath(spFileInfo, pathDestination, 0); - TSmartPath pathSrc = spBasePath->GetSrcPath(); - bResult = spFilesystem->FastMove(pathSrc, pathDestinationPath); - if (!bResult) - { - DWORD dwLastError = GetLastError(); + eResult = FastMoveFB(spFeedbackHandler, spFileInfo, pathDestination, spBasePath, bSkip); + if (eResult != TSubTaskBase::eSubResult_Continue) + return eResult; + //else if (bSkip) + // continue; - // check if this is one of the errors, that will just cause fast move to skip - if (dwLastError == ERROR_ACCESS_DENIED || dwLastError == ERROR_ALREADY_EXISTS) - { - bRetry = false; - bResult = true; - } - else - { - //log - strFormat = _T("Error %errno while calling fast move %srcpath -> %dstpath (TSubTaskFastMove)"); - strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); - strFormat.Replace(_T("%srcpath"), spFileInfo->GetFullFilePath().ToString()); - strFormat.Replace(_T("%dstpath"), pathDestination.ToString()); - rLog.loge(strFormat.c_str()); - - EFeedbackResult frResult = spFeedbackHandler->FileError(pathSrc.ToWString(), pathDestinationPath.ToWString(), EFileError::eFastMoveError, dwLastError); - switch (frResult) - { - case EFeedbackResult::eResult_Cancel: - return TSubTaskBase::eSubResult_CancelRequest; - - case EFeedbackResult::eResult_Retry: - continue; - - case EFeedbackResult::eResult_Pause: - return TSubTaskBase::eSubResult_PauseRequest; - - case EFeedbackResult::eResult_Skip: - //bSkipInputPath = true; // not needed, since we will break the loop anyway and there is no other processing for this path either - bRetry = false; - break; // just do nothing - - default: - BOOST_ASSERT(FALSE); // unknown result - THROW_CORE_EXCEPTION(eErr_UnhandledCase); - } - } - } - else - spBasePath->SetSkipFurtherProcessing(true); // mark that this path should not be processed any further - } while (!bResult && bRetry); - // check for kill need if (rThreadController.KillRequested()) { // log - rLog.logi(_T("Kill request while adding data to files array (RecurseDirectories)")); + rLog.logi(_T("Kill request while fast moving items")); return eSubResult_KillRequest; } } @@ -232,6 +154,124 @@ return eSubResult_Continue; } + TSubTaskBase::ESubOperationResult TSubTaskFastMove::FastMoveFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo, const TSmartPath& pathDestination, + const TBasePathDataPtr& spBasePath, bool& bSkip) + { + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); + icpf::log_file& rLog = GetContext().GetLog(); + + bool bRetry = false; + do + { + bRetry = false; + + TSmartPath pathDestinationPath = CalculateDestinationPath(spFileInfo, pathDestination, 0); + TSmartPath pathSrc = spBasePath->GetSrcPath(); + + DWORD dwLastError = ERROR_SUCCESS; + try + { + spFilesystem->FastMove(pathSrc, pathDestinationPath); + spBasePath->SetSkipFurtherProcessing(true); // mark that this path should not be processed any further + return eSubResult_Continue; + } + catch (const TFileException& e) + { + dwLastError = e.GetNativeError(); + } + + // check if this is one of the errors, that will just cause fast move to skip + if (dwLastError == ERROR_ACCESS_DENIED || dwLastError == ERROR_ALREADY_EXISTS) + { + bSkip = true; + break; + } + else + { + //log + TString strFormat = _T("Error %errno while calling fast move %srcpath -> %dstpath (TSubTaskFastMove)"); + strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); + strFormat.Replace(_T("%srcpath"), spFileInfo->GetFullFilePath().ToString()); + strFormat.Replace(_T("%dstpath"), pathDestination.ToString()); + rLog.loge(strFormat.c_str()); + + EFeedbackResult frResult = spFeedbackHandler->FileError(pathSrc.ToWString(), pathDestinationPath.ToWString(), EFileError::eFastMoveError, dwLastError); + switch (frResult) + { + case EFeedbackResult::eResult_Cancel: + return TSubTaskBase::eSubResult_CancelRequest; + + case EFeedbackResult::eResult_Retry: + bRetry = true; + break; + + case EFeedbackResult::eResult_Pause: + return TSubTaskBase::eSubResult_PauseRequest; + + case EFeedbackResult::eResult_Skip: + bSkip = true; + break; // just do nothing + + default: + BOOST_ASSERT(FALSE); // unknown result + THROW_CORE_EXCEPTION(eErr_UnhandledCase); + } + } + } + while (bRetry); + + return eSubResult_Continue; + } + + TSubTaskBase::ESubOperationResult TSubTaskFastMove::GetFileInfoFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathCurrent, + TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath, bool& bSkip) + { + const IFilesystemPtr& spFilesystem = GetContext().GetLocalFilesystem(); + + bool bRetry = false; + do + { + bRetry = false; + + // read attributes of src file/folder + DWORD dwLastError = ERROR_SUCCESS; + try + { + spFilesystem->GetFileInfo(pathCurrent, spFileInfo, spBasePath); + return eSubResult_Continue; + } + catch (const TFileException& e) + { + dwLastError = e.GetNativeError(); + } + + EFeedbackResult frResult = spFeedbackHandler->FileError(pathCurrent.ToWString(), TString(), EFileError::eFastMoveError, dwLastError); + switch (frResult) + { + case EFeedbackResult::eResult_Cancel: + return eSubResult_CancelRequest; + + case EFeedbackResult::eResult_Retry: + bRetry = true; + break; + + case EFeedbackResult::eResult_Pause: + return eSubResult_PauseRequest; + + case EFeedbackResult::eResult_Skip: + bSkip = true; + break; // just do nothing + + default: + BOOST_ASSERT(FALSE); // unknown result + THROW_CORE_EXCEPTION(eErr_UnhandledCase); + } + } + while (bRetry); + + return eSubResult_Continue; + } + void TSubTaskFastMove::GetStatsSnapshot(TSubTaskStatsSnapshotPtr& spStats) const { m_tSubTaskStats.GetSnapshot(spStats);