Index: src/libchcore/TFilesystemFeedbackWrapper.cpp =================================================================== diff -u -r09d769045d1d5c45d8df16d209c754b872348c26 -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193 --- src/libchcore/TFilesystemFeedbackWrapper.cpp (.../TFilesystemFeedbackWrapper.cpp) (revision 09d769045d1d5c45d8df16d209c754b872348c26) +++ src/libchcore/TFilesystemFeedbackWrapper.cpp (.../TFilesystemFeedbackWrapper.cpp) (revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193) @@ -23,15 +23,16 @@ namespace chcore { - TFilesystemFeedbackWrapper::TFilesystemFeedbackWrapper(const IFilesystemPtr& spFilesystem, icpf::log_file& rLog) : + TFilesystemFeedbackWrapper::TFilesystemFeedbackWrapper(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemPtr& spFilesystem, icpf::log_file& rLog) : + m_spFeedbackHandler(spFeedbackHandler), m_spFilesystem(spFilesystem), m_rLog(rLog) { if (!spFilesystem) THROW_CORE_EXCEPTION_MSG(eErr_InvalidArgument, L"Filesystem not provided"); } - TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::CreateDirectoryFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathDirectory) + TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::CreateDirectoryFB(const TSmartPath& pathDirectory) { bool bRetry = false; do @@ -59,7 +60,7 @@ strFormat.Replace(_T("%path"), pathDirectory.ToString()); m_rLog.loge(strFormat.c_str()); - EFeedbackResult frResult = spFeedbackHandler->FileError(pathDirectory.ToWString(), TString(), EFileError::eCreateError, dwLastError); + EFeedbackResult frResult = m_spFeedbackHandler->FileError(pathDirectory.ToWString(), TString(), EFileError::eCreateError, dwLastError); switch (frResult) { case EFeedbackResult::eResult_Cancel: @@ -85,7 +86,7 @@ return TSubTaskBase::eSubResult_Continue; } - TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::CheckForFreeSpaceFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathFirstSrc, const TSmartPath& pathDestination, unsigned long long ullNeededSize) + TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::CheckForFreeSpaceFB(const TSmartPath& pathFirstSrc, const TSmartPath& pathDestination, unsigned long long ullNeededSize) { unsigned long long ullAvailableSize = 0; bool bRetry = false; @@ -117,7 +118,7 @@ strFormat.Replace(_T("%path"), pathDestination.ToString()); m_rLog.loge(strFormat.c_str()); - EFeedbackResult frResult = spFeedbackHandler->FileError(pathDestination.ToWString(), TString(), EFileError::eCheckForFreeSpace, dwLastError); + EFeedbackResult frResult = m_spFeedbackHandler->FileError(pathDestination.ToWString(), TString(), EFileError::eCheckForFreeSpace, dwLastError); switch (frResult) { case EFeedbackResult::eResult_Cancel: @@ -146,7 +147,7 @@ strFormat.Replace(_t("%availablesize"), boost::lexical_cast(ullAvailableSize).c_str()); m_rLog.logw(strFormat.c_str()); - EFeedbackResult frResult = spFeedbackHandler->NotEnoughSpace(pathFirstSrc.ToWString(), pathDestination.ToWString(), ullNeededSize); + EFeedbackResult frResult = m_spFeedbackHandler->NotEnoughSpace(pathFirstSrc.ToWString(), pathDestination.ToWString(), ullNeededSize); switch (frResult) { case EFeedbackResult::eResult_Cancel: @@ -172,4 +173,240 @@ return TSubTaskBase::eSubResult_Continue; } + TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::RemoveDirectoryFB(const TFileInfoPtr& spFileInfo, bool bProtectReadOnlyFiles) + { + bool bRetry = false; + do + { + bRetry = false; + + // #bug - changing read-only attribute should only be done when user explicitly requests it (via feedback response) + // for now it is ignored + try + { + if (!bProtectReadOnlyFiles) + m_spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY); + } + catch (const TFileException&) + { + } + + DWORD dwLastError = ERROR_SUCCESS; + try + { + m_spFilesystem->RemoveDirectory(spFileInfo->GetFullFilePath()); + return TSubTaskBase::eSubResult_Continue; + } + catch (const TFileException& e) + { + dwLastError = e.GetNativeError(); + } + + if (dwLastError == ERROR_PATH_NOT_FOUND || dwLastError == ERROR_FILE_NOT_FOUND) + return TSubTaskBase::eSubResult_Continue; + + // log + TString strFormat = _T("Error #%errno while deleting file/folder %path"); + strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); + strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString()); + m_rLog.loge(strFormat.c_str()); + + EFeedbackResult frResult = m_spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError); + switch (frResult) + { + case EFeedbackResult::eResult_Cancel: + m_rLog.logi(_T("Cancel request while deleting file.")); + return TSubTaskBase::eSubResult_CancelRequest; + + case EFeedbackResult::eResult_Retry: + bRetry = true; + continue; // no fcIndex bump, since we are trying again + + case EFeedbackResult::eResult_Pause: + return TSubTaskBase::eSubResult_PauseRequest; + + case EFeedbackResult::eResult_Skip: + break; // just do nothing + + default: + BOOST_ASSERT(FALSE); // unknown result + THROW_CORE_EXCEPTION(eErr_UnhandledCase); + } + } while (bRetry); + + return TSubTaskBase::eSubResult_Continue; + } + + TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::DeleteFileFB(const TFileInfoPtr& spFileInfo, bool bProtectReadOnlyFiles) + { + bool bRetry = false; + do + { + bRetry = false; + + // #bug - changing read-only attribute should only be done when user explicitly requests it (via feedback response) + // for now it is ignored + try + { + if (!bProtectReadOnlyFiles) + m_spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY); + } + catch (const TFileException&) + { + } + + DWORD dwLastError = ERROR_SUCCESS; + try + { + m_spFilesystem->DeleteFile(spFileInfo->GetFullFilePath()); + return TSubTaskBase::eSubResult_Continue; + } + catch (const TFileException& e) + { + dwLastError = e.GetNativeError(); + } + + if (dwLastError == ERROR_PATH_NOT_FOUND || dwLastError == ERROR_FILE_NOT_FOUND) + return TSubTaskBase::eSubResult_Continue; + + // log + TString strFormat = _T("Error #%errno while deleting file/folder %path"); + strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); + strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString()); + m_rLog.loge(strFormat.c_str()); + + EFeedbackResult frResult = m_spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError); + switch (frResult) + { + case EFeedbackResult::eResult_Cancel: + m_rLog.logi(_T("Cancel request while deleting file.")); + return TSubTaskBase::eSubResult_CancelRequest; + + case EFeedbackResult::eResult_Retry: + bRetry = true; + continue; // no fcIndex bump, since we are trying again + + case EFeedbackResult::eResult_Pause: + return TSubTaskBase::eSubResult_PauseRequest; + + case EFeedbackResult::eResult_Skip: + break; // just do nothing + + default: + BOOST_ASSERT(FALSE); // unknown result + THROW_CORE_EXCEPTION(eErr_UnhandledCase); + } + } while (bRetry); + + return TSubTaskBase::eSubResult_Continue; + } + + TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::FastMoveFB(const TFileInfoPtr& spFileInfo, const TSmartPath& pathDestination, const TBasePathDataPtr& spBasePath, bool& bSkip) + { + bool bRetry = false; + do + { + bRetry = false; + + TSmartPath pathSrc = spBasePath->GetSrcPath(); + + DWORD dwLastError = ERROR_SUCCESS; + try + { + m_spFilesystem->FastMove(pathSrc, pathDestination); + spBasePath->SetSkipFurtherProcessing(true); // mark that this path should not be processed any further + return TSubTaskBase::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 || dwLastError == ERROR_NOT_SAME_DEVICE) + { + 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()); + m_rLog.loge(strFormat.c_str()); + + EFeedbackResult frResult = m_spFeedbackHandler->FileError(pathSrc.ToWString(), pathDestination.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 TSubTaskBase::eSubResult_Continue; + } + + TSubTaskBase::ESubOperationResult TFilesystemFeedbackWrapper::GetFileInfoFB(const TSmartPath& pathCurrent, TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath, bool& bSkip) + { + bool bRetry = false; + do + { + bRetry = false; + + // read attributes of src file/folder + DWORD dwLastError = ERROR_SUCCESS; + try + { + m_spFilesystem->GetFileInfo(pathCurrent, spFileInfo, spBasePath); + return TSubTaskBase::eSubResult_Continue; + } + catch (const TFileException& e) + { + dwLastError = e.GetNativeError(); + } + + EFeedbackResult frResult = m_spFeedbackHandler->FileError(pathCurrent.ToWString(), TString(), 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 TSubTaskBase::eSubResult_Continue; + } + } Index: src/libchcore/TFilesystemFeedbackWrapper.h =================================================================== diff -u -r09d769045d1d5c45d8df16d209c754b872348c26 -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193 --- src/libchcore/TFilesystemFeedbackWrapper.h (.../TFilesystemFeedbackWrapper.h) (revision 09d769045d1d5c45d8df16d209c754b872348c26) +++ src/libchcore/TFilesystemFeedbackWrapper.h (.../TFilesystemFeedbackWrapper.h) (revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193) @@ -29,12 +29,22 @@ class TFilesystemFeedbackWrapper { public: - TFilesystemFeedbackWrapper(const IFilesystemPtr& spFilesystem, icpf::log_file& rLog); + TFilesystemFeedbackWrapper(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemPtr& spFilesystem, icpf::log_file& rLog); - TSubTaskBase::ESubOperationResult CreateDirectoryFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathDirectory); - TSubTaskBase::ESubOperationResult CheckForFreeSpaceFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathFirstSrc, const TSmartPath& pathDestination, unsigned long long ullNeededSize); + TSubTaskBase::ESubOperationResult CreateDirectoryFB(const TSmartPath& pathDirectory); + TSubTaskBase::ESubOperationResult CheckForFreeSpaceFB(const TSmartPath& pathFirstSrc, const TSmartPath& pathDestination, unsigned long long ullNeededSize); + TSubTaskBase::ESubOperationResult RemoveDirectoryFB(const TFileInfoPtr& spFileInfo, bool bProtectReadOnlyFiles); + TSubTaskBase::ESubOperationResult DeleteFileFB(const TFileInfoPtr& spFileInfo, bool bProtectReadOnlyFiles); + + TSubTaskBase::ESubOperationResult FastMoveFB(const TFileInfoPtr& spFileInfo, const TSmartPath& pathDestination, + const TBasePathDataPtr& spBasePath, bool& bSkip); + + TSubTaskBase::ESubOperationResult GetFileInfoFB(const TSmartPath& pathCurrent, + TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath, bool& bSkip); + private: + IFeedbackHandlerPtr m_spFeedbackHandler; IFilesystemPtr m_spFilesystem; icpf::log_file& m_rLog; }; Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -r6eefe6212611518e13af7771d406612c0a7a2bed -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193 --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 6eefe6212611518e13af7771d406612c0a7a2bed) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193) @@ -91,7 +91,7 @@ IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); TBasePathDataContainerPtr spSrcPaths = GetContext().GetBasePaths(); - TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFilesystem, rLog); + TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackHandler, spFilesystem, rLog); // log rLog.logi(_T("Processing files/folders (ProcessFiles)")); @@ -110,7 +110,7 @@ // now it's time to check if there is enough space on destination device unsigned long long ullNeededSize = rFilesCache.CalculateTotalSize() - rFilesCache.CalculatePartialSize(m_tSubTaskStats.GetCurrentIndex()); TSmartPath pathSingleSrc = spSrcPaths->GetAt(0)->GetSrcPath(); - TSubTaskBase::ESubOperationResult eResult = tFilesystemFBWrapper.CheckForFreeSpaceFB(spFeedbackHandler, pathSingleSrc, pathDestination, ullNeededSize); + TSubTaskBase::ESubOperationResult eResult = tFilesystemFBWrapper.CheckForFreeSpaceFB(pathSingleSrc, pathDestination, ullNeededSize); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; @@ -176,7 +176,7 @@ // if folder - create it if(spFileInfo->IsDirectory()) { - eResult = tFilesystemFBWrapper.CreateDirectoryFB(spFeedbackHandler, ccp.pathDstFile); + eResult = tFilesystemFBWrapper.CreateDirectoryFB(ccp.pathDstFile); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; Index: src/libchcore/TSubTaskDelete.cpp =================================================================== diff -u -rd468098a278a0d16c5b700236ea276b9c9677c9f -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193 --- src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision d468098a278a0d16c5b700236ea276b9c9677c9f) +++ src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193) @@ -39,6 +39,7 @@ #include #include "TBufferSizes.h" #include "TFileException.h" +#include "TFilesystemFeedbackWrapper.h" namespace chcore { @@ -67,6 +68,8 @@ TWorkerThreadController& rThreadController = GetContext().GetThreadController(); IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); + TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackHandler, spFilesystem, rLog); + // log rLog.logi(_T("Deleting files (DeleteFiles)...")); @@ -111,10 +114,11 @@ ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue; // delete data + bool bProtectReadOnlyFiles = GetTaskPropValue(GetContext().GetConfig()); if (spFileInfo->IsDirectory()) - eResult = RemoveDirectoryFB(spFeedbackHandler, spFileInfo); + eResult = tFilesystemFBWrapper.RemoveDirectoryFB(spFileInfo, bProtectReadOnlyFiles); else - eResult = DeleteFileFB(spFeedbackHandler, spFileInfo); + eResult = tFilesystemFBWrapper.DeleteFileFB(spFileInfo, bProtectReadOnlyFiles); ++fcIndex; } @@ -129,144 +133,6 @@ return TSubTaskBase::eSubResult_Continue; } - TSubTaskBase::ESubOperationResult TSubTaskDelete::RemoveDirectoryFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo) - { - const TConfig& rConfig = GetContext().GetConfig(); - IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); - icpf::log_file& rLog = GetContext().GetLog(); - - bool bRetry = false; - do - { - bRetry = false; - - // #bug - changing read-only attribute should only be done when user explicitly requests it (via feedback response) - // for now it is ignored - try - { - if (!GetTaskPropValue(rConfig)) - spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY); - } - catch (const TFileException&) - { - } - - DWORD dwLastError = ERROR_SUCCESS; - try - { - spFilesystem->RemoveDirectory(spFileInfo->GetFullFilePath()); - return TSubTaskBase::eSubResult_Continue; - } - catch (const TFileException& e) - { - dwLastError = e.GetNativeError(); - } - - if (dwLastError == ERROR_PATH_NOT_FOUND || dwLastError == ERROR_FILE_NOT_FOUND) - return TSubTaskBase::eSubResult_Continue; - - // log - TString strFormat = _T("Error #%errno while deleting file/folder %path"); - strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); - strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString()); - rLog.loge(strFormat.c_str()); - - EFeedbackResult frResult = spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError); - switch (frResult) - { - case EFeedbackResult::eResult_Cancel: - rLog.logi(_T("Cancel request while deleting file.")); - return TSubTaskBase::eSubResult_CancelRequest; - - case EFeedbackResult::eResult_Retry: - bRetry = true; - continue; // no fcIndex bump, since we are trying again - - case EFeedbackResult::eResult_Pause: - return TSubTaskBase::eSubResult_PauseRequest; - - case EFeedbackResult::eResult_Skip: - break; // just do nothing - - default: - BOOST_ASSERT(FALSE); // unknown result - THROW_CORE_EXCEPTION(eErr_UnhandledCase); - } - } - while (bRetry); - - return TSubTaskBase::eSubResult_Continue; - } - - TSubTaskBase::ESubOperationResult TSubTaskDelete::DeleteFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo) - { - const TConfig& rConfig = GetContext().GetConfig(); - IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); - icpf::log_file& rLog = GetContext().GetLog(); - - bool bRetry = false; - do - { - bRetry = false; - - // #bug - changing read-only attribute should only be done when user explicitly requests it (via feedback response) - // for now it is ignored - try - { - if (!GetTaskPropValue(rConfig)) - spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY); - } - catch (const TFileException&) - { - } - - DWORD dwLastError = ERROR_SUCCESS; - try - { - spFilesystem->DeleteFile(spFileInfo->GetFullFilePath()); - return TSubTaskBase::eSubResult_Continue; - } - catch (const TFileException& e) - { - dwLastError = e.GetNativeError(); - } - - if (dwLastError == ERROR_PATH_NOT_FOUND || dwLastError == ERROR_FILE_NOT_FOUND) - return TSubTaskBase::eSubResult_Continue; - - // log - TString strFormat = _T("Error #%errno while deleting file/folder %path"); - strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); - strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString()); - rLog.loge(strFormat.c_str()); - - EFeedbackResult frResult = spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError); - switch (frResult) - { - case EFeedbackResult::eResult_Cancel: - rLog.logi(_T("Cancel request while deleting file.")); - return TSubTaskBase::eSubResult_CancelRequest; - - case EFeedbackResult::eResult_Retry: - bRetry = true; - continue; // no fcIndex bump, since we are trying again - - case EFeedbackResult::eResult_Pause: - return TSubTaskBase::eSubResult_PauseRequest; - - case EFeedbackResult::eResult_Skip: - break; // just do nothing - - default: - BOOST_ASSERT(FALSE); // unknown result - THROW_CORE_EXCEPTION(eErr_UnhandledCase); - } - } - while (bRetry); - - return TSubTaskBase::eSubResult_Continue; - } - void TSubTaskDelete::GetStatsSnapshot(TSubTaskStatsSnapshotPtr& spStats) const { m_tSubTaskStats.GetSnapshot(spStats); Index: src/libchcore/TSubTaskDelete.h =================================================================== diff -u -rd468098a278a0d16c5b700236ea276b9c9677c9f -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193 --- src/libchcore/TSubTaskDelete.h (.../TSubTaskDelete.h) (revision d468098a278a0d16c5b700236ea276b9c9677c9f) +++ src/libchcore/TSubTaskDelete.h (.../TSubTaskDelete.h) (revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193) @@ -49,10 +49,6 @@ virtual void GetStatsSnapshot(TSubTaskStatsSnapshotPtr& spStats) const; private: - TSubTaskBase::ESubOperationResult RemoveDirectoryFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo); - TSubTaskBase::ESubOperationResult DeleteFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo); - - private: #pragma warning(push) #pragma warning(disable: 4251) TSubTaskStatsInfo m_tSubTaskStats; Index: src/libchcore/TSubTaskFastMove.cpp =================================================================== diff -u -rcde3645c5041aedd6703b81b6fed42134c615917 -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193 --- src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision cde3645c5041aedd6703b81b6fed42134c615917) +++ src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193) @@ -40,6 +40,7 @@ #include "TFeedbackHandlerWrapper.h" #include "TBufferSizes.h" #include "TFileException.h" +#include "TFilesystemFeedbackWrapper.h" namespace chcore { @@ -72,6 +73,8 @@ const TFileFiltersArray& rafFilters = GetContext().GetFilters(); IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); + TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackHandler, spFilesystem, rLog); + rLog.logi(_T("Performing initial fast-move operation...")); // new stats @@ -115,7 +118,7 @@ TFileInfoPtr spFileInfo(boost::make_shared()); bool bSkip = false; - ESubOperationResult eResult = GetFileInfoFB(spFeedbackHandler, pathCurrent, spFileInfo, spBasePath, bSkip); + ESubOperationResult eResult = tFilesystemFBWrapper.GetFileInfoFB(pathCurrent, spFileInfo, spBasePath, bSkip); if (eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if (bSkip) @@ -129,7 +132,7 @@ } // try to fast move - eResult = FastMoveFB(spFeedbackHandler, spFileInfo, pathDestination, spBasePath, bSkip); + eResult = tFilesystemFBWrapper.FastMoveFB(spFileInfo, CalculateDestinationPath(spFileInfo, pathDestination, 0), spBasePath, bSkip); if (eResult != TSubTaskBase::eSubResult_Continue) return eResult; //else if (bSkip) @@ -154,124 +157,6 @@ 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 || dwLastError == ERROR_NOT_SAME_DEVICE) - { - 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); Index: src/libchcore/TSubTaskFastMove.h =================================================================== diff -u -rd468098a278a0d16c5b700236ea276b9c9677c9f -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193 --- src/libchcore/TSubTaskFastMove.h (.../TSubTaskFastMove.h) (revision d468098a278a0d16c5b700236ea276b9c9677c9f) +++ src/libchcore/TSubTaskFastMove.h (.../TSubTaskFastMove.h) (revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193) @@ -55,8 +55,6 @@ private: int ScanDirectory(TSmartPath pathDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs, TFileFiltersArray& afFilters); - TSubTaskBase::ESubOperationResult GetFileInfoFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathCurrent, TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath, bool& bSkip); - TSubTaskBase::ESubOperationResult FastMoveFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo, const TSmartPath& pathDestination, const TBasePathDataPtr& spBasePath, bool& bSkip); private: #pragma warning(push) Index: src/libchcore/TSubTaskScanDirectory.cpp =================================================================== diff -u -rd468098a278a0d16c5b700236ea276b9c9677c9f -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193 --- src/libchcore/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision d468098a278a0d16c5b700236ea276b9c9677c9f) +++ src/libchcore/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193) @@ -39,6 +39,7 @@ #include "TFeedbackHandlerWrapper.h" #include "TBufferSizes.h" #include "TFileException.h" +#include "TFilesystemFeedbackWrapper.h" namespace chcore { @@ -71,7 +72,10 @@ TBasePathDataContainerPtr spBasePaths = GetContext().GetBasePaths(); const TConfig& rConfig = GetContext().GetConfig(); const TFileFiltersArray& rafFilters = GetContext().GetFilters(); + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); + TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackHandler, spFilesystem, rLog); + rLog.logi(_T("Searching for files...")); // reset progress @@ -116,7 +120,7 @@ // try to get some info about the input path; let user know if the path does not exist. bool bSkip = false; - ESubOperationResult eResult = GetFileInfoFB(spFeedbackHandler, pathCurrent, spFileInfo, spBasePath, bSkip); + ESubOperationResult eResult = tFilesystemFBWrapper.GetFileInfoFB(pathCurrent, spFileInfo, spBasePath, bSkip); if (eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if (bSkip) @@ -185,57 +189,6 @@ return eSubResult_Continue; } - TSubTaskBase::ESubOperationResult TSubTaskScanDirectories::GetFileInfoFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathCurrent, TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath, bool& bSkip) - { - TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); - 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: - rFilesCache.Clear(); - return eSubResult_CancelRequest; - - case EFeedbackResult::eResult_Retry: - bRetry = true; - break; - - case EFeedbackResult::eResult_Pause: - rFilesCache.Clear(); - 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 TSubTaskScanDirectories::GetStatsSnapshot(TSubTaskStatsSnapshotPtr& spStats) const { m_tSubTaskStats.GetSnapshot(spStats); Index: src/libchcore/TSubTaskScanDirectory.h =================================================================== diff -u -rd468098a278a0d16c5b700236ea276b9c9677c9f -r25722a1d39e5d4bb49c5a60cbee3dda6c02cb193 --- src/libchcore/TSubTaskScanDirectory.h (.../TSubTaskScanDirectory.h) (revision d468098a278a0d16c5b700236ea276b9c9677c9f) +++ src/libchcore/TSubTaskScanDirectory.h (.../TSubTaskScanDirectory.h) (revision 25722a1d39e5d4bb49c5a60cbee3dda6c02cb193) @@ -56,8 +56,6 @@ int ScanDirectory(TSmartPath pathDirName, const TBasePathDataPtr& spBasePathData, bool bRecurse, bool bIncludeDirs, const TFileFiltersArray& afFilters); - ESubOperationResult GetFileInfoFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathCurrent, TFileInfoPtr& spFileInfo, const TBasePathDataPtr& spBasePath, bool& bSkip); - private: #pragma warning(push) #pragma warning(disable: 4251)