Index: src/libchcore/TDestinationPathProvider.cpp =================================================================== diff -u --- src/libchcore/TDestinationPathProvider.cpp (revision 0) +++ src/libchcore/TDestinationPathProvider.cpp (revision 7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d) @@ -0,0 +1,100 @@ +#include "stdafx.h" +#include "TDestinationPathProvider.h" +#include "TCoreException.h" +#include "ErrorCodes.h" +#include + +namespace chcore +{ + TDestinationPathProvider::TDestinationPathProvider(const IFilesystemPtr& spFilesystem, + const TSmartPath& pathDestinationBase, + bool bIgnoreFolders, + bool bForceDirectories, + const TString& strFirstAltName, + const TString& strNextAltName) : + + m_spFilesystem(spFilesystem), + m_pathDestinationBase(pathDestinationBase), + m_bForceDirectories(bForceDirectories), + m_bIgnoreFolders(bIgnoreFolders), + m_strFirstAltName(strFirstAltName), + m_strNextAltName(strNextAltName) + { + if(!spFilesystem) + throw TCoreException(eErr_InvalidArgument, L"spFilesystem", LOCATION); + } + + + TSmartPath TDestinationPathProvider::CalculateDestinationPath(const TFileInfoPtr& spFileInfo) + { + if(!spFileInfo) + throw TCoreException(eErr_InvalidArgument, L"spFileInfo", LOCATION); + + if(m_bForceDirectories) + { + // force create directories + TSmartPath pathCombined = m_pathDestinationBase + spFileInfo->GetFullFilePath().GetFileDir(); + + // force create directory + m_spFilesystem->CreateDirectory(pathCombined, true); + + return pathCombined + spFileInfo->GetFullFilePath().GetFileName(); + } + else + { + TBasePathDataPtr spPathData = spFileInfo->GetBasePathData(); + + if(!m_bIgnoreFolders && spPathData) + { + // generate new dest name + if(!spPathData->IsDestinationPathSet()) + { + // generate something - if dest folder == src folder - search for copy + if(m_pathDestinationBase == spFileInfo->GetFullFilePath().GetFileRoot()) + { + TSmartPath pathSubst = FindFreeSubstituteName(spFileInfo->GetFullFilePath()); + spPathData->SetDestinationPath(pathSubst); + } + else + { + TSmartPath pathFilename = spFileInfo->GetFullFilePath().GetFileName(); + pathFilename.StripPath(L":"); + spPathData->SetDestinationPath(pathFilename); + } + } + + return m_pathDestinationBase + spPathData->GetDestinationPath() + spFileInfo->GetFilePath(); + } + else + return m_pathDestinationBase + spFileInfo->GetFilePath(); + } + } + + // finds another name for a copy of src file(folder) in dest location + TSmartPath TDestinationPathProvider::FindFreeSubstituteName(TSmartPath pathSrcPath) const + { + // get the name from src path + pathSrcPath.StripSeparatorAtEnd(); + + TSmartPath pathFilename = pathSrcPath.GetFileName(); + pathFilename.StripPath(L":"); + + // set the dest path + TString strCheckPath = m_strFirstAltName; + strCheckPath.Replace(_T("%name"), pathFilename.ToString()); + TSmartPath pathCheckPath(PathFromWString(strCheckPath)); + + // when adding to strDstPath check if the path already exists - if so - try again + int iCounter = 1; + TString strFmt = m_strNextAltName; + while(m_spFilesystem->PathExist(m_pathDestinationBase + pathCheckPath)) + { + strCheckPath = strFmt; + strCheckPath.Replace(_T("%name"), pathFilename.ToString()); + strCheckPath.Replace(_T("%count"), boost::lexical_cast(++iCounter).c_str()); + pathCheckPath.FromString(strCheckPath); + } + + return pathCheckPath; + } +} Index: src/libchcore/TDestinationPathProvider.h =================================================================== diff -u --- src/libchcore/TDestinationPathProvider.h (revision 0) +++ src/libchcore/TDestinationPathProvider.h (revision 7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d) @@ -0,0 +1,49 @@ +// ============================================================================ +// Copyright (C) 2001-2009 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TDESTINATIONPATHPROVIDER_H__ +#define __TDESTINATIONPATHPROVIDER_H__ + +#include "TPath.h" +#include "TFileInfo.h" +#include "IFilesystem.h" + +namespace chcore +{ + class TDestinationPathProvider + { + public: + TDestinationPathProvider(const IFilesystemPtr& spFilesystem, const TSmartPath& pathDestinationBase, bool bIgnoreFolders, bool bForceDirectories, + const TString& strFirstAltName, const TString& strNextAltName); + + TSmartPath CalculateDestinationPath(const TFileInfoPtr& spFileInfo); + + private: + TSmartPath FindFreeSubstituteName(TSmartPath pathSrcPath) const; + + private: + IFilesystemPtr m_spFilesystem; + TSmartPath m_pathDestinationBase; + bool m_bIgnoreFolders; + bool m_bForceDirectories; + TString m_strFirstAltName; + TString m_strNextAltName; + }; +} + +#endif Index: src/libchcore/TSubTaskBase.cpp =================================================================== diff -u -rf866db90e4b058a4f2e13cc6cf076d1e0bf2d956 -r7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d --- src/libchcore/TSubTaskBase.cpp (.../TSubTaskBase.cpp) (revision f866db90e4b058a4f2e13cc6cf076d1e0bf2d956) +++ src/libchcore/TSubTaskBase.cpp (.../TSubTaskBase.cpp) (revision 7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d) @@ -43,83 +43,4 @@ TSubTaskBase::~TSubTaskBase() { } - - TSmartPath TSubTaskBase::CalculateDestinationPath(const TFileInfoPtr& spFileInfo, TSmartPath pathDst, int iFlags) - { - IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); - - if (!spFileInfo) - throw TCoreException(eErr_InvalidArgument, L"spFileInfo", LOCATION); - - // iFlags: bit 0-ignore folders; bit 1-force creating directories - if (iFlags & 0x02) - { - // force create directories - TSmartPath pathCombined = pathDst + spFileInfo->GetFullFilePath().GetFileDir(); - - // force create directory - spFilesystem->CreateDirectory(pathCombined, true); - - return pathCombined + spFileInfo->GetFullFilePath().GetFileName(); - } - else - { - TBasePathDataPtr spPathData = spFileInfo->GetBasePathData(); - - if (!(iFlags & 0x01) && spPathData) - { - // generate new dest name - if (!spPathData->IsDestinationPathSet()) - { - // generate something - if dest folder == src folder - search for copy - if (pathDst == spFileInfo->GetFullFilePath().GetFileRoot()) - { - TSmartPath pathSubst = FindFreeSubstituteName(spFileInfo->GetFullFilePath(), pathDst); - spPathData->SetDestinationPath(pathSubst); - } - else - { - TSmartPath pathFilename = spFileInfo->GetFullFilePath().GetFileName(); - pathFilename.StripPath(L":"); - spPathData->SetDestinationPath(pathFilename); - } - } - - return pathDst + spPathData->GetDestinationPath() + spFileInfo->GetFilePath(); - } - else - return pathDst + spFileInfo->GetFilePath(); - } - } - - // finds another name for a copy of src file(folder) in dest location - TSmartPath TSubTaskBase::FindFreeSubstituteName(TSmartPath pathSrcPath, TSmartPath pathDstPath) const - { - const TConfig& rConfig = GetContext().GetConfig(); - IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); - - // get the name from src path - pathSrcPath.StripSeparatorAtEnd(); - - TSmartPath pathFilename = pathSrcPath.GetFileName(); - pathFilename.StripPath(L":"); - - // set the dest path - TString strCheckPath = GetTaskPropValue(rConfig); - strCheckPath.Replace(_T("%name"), pathFilename.ToString()); - TSmartPath pathCheckPath(PathFromWString(strCheckPath)); - - // when adding to strDstPath check if the path already exists - if so - try again - int iCounter = 1; - TString strFmt = GetTaskPropValue(rConfig); - while (spFilesystem->PathExist(pathDstPath + pathCheckPath)) - { - strCheckPath = strFmt; - strCheckPath.Replace(_T("%name"), pathFilename.ToString()); - strCheckPath.Replace(_T("%count"), boost::lexical_cast(++iCounter).c_str()); - pathCheckPath.FromString(strCheckPath); - } - - return pathCheckPath; - } } Index: src/libchcore/TSubTaskBase.h =================================================================== diff -u -rcb4e9d4b60d62b25ae2cf556c0642601af56c787 -r7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d --- src/libchcore/TSubTaskBase.h (.../TSubTaskBase.h) (revision cb4e9d4b60d62b25ae2cf556c0642601af56c787) +++ src/libchcore/TSubTaskBase.h (.../TSubTaskBase.h) (revision 7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d) @@ -74,9 +74,6 @@ TSubTaskContext& GetContext() { return m_rContext; } const TSubTaskContext& GetContext() const { return m_rContext; } - TSmartPath CalculateDestinationPath(const TFileInfoPtr& spFileInfo, TSmartPath pathDst, int iFlags); - TSmartPath FindFreeSubstituteName(TSmartPath pathSrcPath, TSmartPath pathDstPath) const; - private: TSubTaskBase(const TSubTaskBase&); TSubTaskBase& operator=(const TSubTaskBase&); Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -r0380c176d1cfcdfd1cd2adfe01d9c1c5c38df9f1 -r7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 0380c176d1cfcdfd1cd2adfe01d9c1c5c38df9f1) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d) @@ -48,6 +48,7 @@ #include "TFilesystemFeedbackWrapper.h" #include "TFilesystemFileFeedbackWrapper.h" #include "log.h" +#include "TDestinationPathProvider.h" namespace chcore { @@ -138,9 +139,6 @@ unsigned long long ullCurrentItemProcessedSize = m_tSubTaskStats.GetCurrentItemProcessedSize(); bool bCurrentFileSilentResume = m_tSubTaskStats.CanCurrentItemSilentResume(); - bool bIgnoreFolders = GetTaskPropValue(rConfig); - bool bForceDirectories = GetTaskPropValue(rConfig); - // create a buffer of size m_nBufferSize CUSTOM_COPY_PARAMS ccp; ccp.bProcessed = false; @@ -151,6 +149,14 @@ AdjustBufferIfNeeded(ccp.dbBuffer, ccp.tBufferSizes, true); + bool bIgnoreFolders = GetTaskPropValue(rConfig); + bool bForceDirectories = GetTaskPropValue(rConfig); + + TDestinationPathProvider tDstPathProvider(spFilesystem, pathDestination, + bIgnoreFolders, bForceDirectories, + GetTaskPropValue(GetContext().GetConfig()), + GetTaskPropValue(GetContext().GetConfig())); + // log TString strFormat; strFormat = _T("Processing files/folders (ProcessFiles):\r\n\tOnlyCreate: %create\r\n\tFiles/folders count: %filecount\r\n\tIgnore Folders: %ignorefolders\r\n\tDest path: %dstpath\r\n\tCurrent index (0-based): %currindex"); @@ -194,7 +200,7 @@ } // set dest path with filename - ccp.pathDstFile = CalculateDestinationPath(spFileInfo, pathDestination, ((int)bForceDirectories) << 1 | (int)bIgnoreFolders); + ccp.pathDstFile = tDstPathProvider.CalculateDestinationPath(spFileInfo); // are the files/folders lie on the same partition ? bool bMove = GetContext().GetOperationType() == eOperation_Move; @@ -263,7 +269,7 @@ TFileInfoPtr spFileInfo = rFilesCache.GetAt(fcAttrIndex - 1); if(spFileInfo->IsDirectory()) { - TSmartPath pathDstDir = CalculateDestinationPath(spFileInfo, pathDestination, ((int)bForceDirectories) << 1 | (int)bIgnoreFolders); + TSmartPath pathDstDir = tDstPathProvider.CalculateDestinationPath(spFileInfo); spFilesystem->SetFileDirectoryTime(pathDstDir, spFileInfo->GetCreationTime(), spFileInfo->GetLastAccessTime(), spFileInfo->GetLastWriteTime()); } Index: src/libchcore/TSubTaskFastMove.cpp =================================================================== diff -u -rfb881f503caba7b2ade610ba7fc1a36a5aea5d01 -r7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d --- src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision fb881f503caba7b2ade610ba7fc1a36a5aea5d01) +++ src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision 7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d) @@ -40,6 +40,7 @@ #include "TFileException.h" #include "TFilesystemFeedbackWrapper.h" #include "log.h" +#include "TDestinationPathProvider.h" namespace chcore { @@ -111,6 +112,11 @@ if (bIgnoreDirs || bForceDirectories) return eSubResult_Continue; + TDestinationPathProvider tDstPathProvider(spFilesystem, pathDestination, + bIgnoreDirs, bForceDirectories, + GetTaskPropValue(GetContext().GetConfig()), + GetTaskPropValue(GetContext().GetConfig())); + // add everything TString strFormat; @@ -153,7 +159,7 @@ } // try to fast move - eResult = tFilesystemFBWrapper.FastMoveFB(spFileInfo, CalculateDestinationPath(spFileInfo, pathDestination, 0), spBasePath, bSkip); + eResult = tFilesystemFBWrapper.FastMoveFB(spFileInfo, tDstPathProvider.CalculateDestinationPath(spFileInfo), spBasePath, bSkip); if (eResult != TSubTaskBase::eSubResult_Continue) return eResult; //else if (bSkip) Index: src/libchcore/libchcore.vc140.vcxproj =================================================================== diff -u -rc4b596d905262841724ae7b091c11a8c9d5b4a5f -r7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d --- src/libchcore/libchcore.vc140.vcxproj (.../libchcore.vc140.vcxproj) (revision c4b596d905262841724ae7b091c11a8c9d5b4a5f) +++ src/libchcore/libchcore.vc140.vcxproj (.../libchcore.vc140.vcxproj) (revision 7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d) @@ -484,6 +484,7 @@ + @@ -615,6 +616,7 @@ + true true Index: src/libchcore/libchcore.vc140.vcxproj.filters =================================================================== diff -u -r5446395d3925e49d3e4cba82044bdfd4dffb6ee9 -r7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d --- src/libchcore/libchcore.vc140.vcxproj.filters (.../libchcore.vc140.vcxproj.filters) (revision 5446395d3925e49d3e4cba82044bdfd4dffb6ee9) +++ src/libchcore/libchcore.vc140.vcxproj.filters (.../libchcore.vc140.vcxproj.filters) (revision 7ba9f25ab2c2a42bac9f5455ecb98aaf6e29f02d) @@ -464,6 +464,9 @@ Source Files\Tools\Logging + + Source Files\SubTasks + @@ -847,5 +850,8 @@ Source Files\Tools\Logging + + Source Files\SubTasks + \ No newline at end of file