Index: src/ch/Device IO.h =================================================================== diff -u -N -rc435ab507c8b8280264188b49e9ada56d46c0261 -r16a61d123d45e60dea731a6620f6f47acccd8c43 --- src/ch/Device IO.h (.../Device IO.h) (revision c435ab507c8b8280264188b49e9ada56d46c0261) +++ src/ch/Device IO.h (.../Device IO.h) (revision 16a61d123d45e60dea731a6620f6f47acccd8c43) @@ -20,7 +20,7 @@ #define __DEVICEIO_H__ // only NT -bool GetSignature(LPCTSTR lpszDrive, LPTSTR lpszBuffer, int iSize) +static bool GetSignature(LPCTSTR lpszDrive, LPTSTR lpszBuffer, int iSize) { std::auto_ptr szMapping(new TCHAR[1024]); std::auto_ptr szQuery(new TCHAR[16384]); @@ -88,8 +88,7 @@ return false; } -// at 9x function checks int13h devices and at NT within symbolic links -bool IsSamePhysicalDisk(int iDrvNum1, int iDrvNum2) +static bool IsSamePhysicalDisk(int iDrvNum1, int iDrvNum2) { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); Index: src/ch/FileInfo.cpp =================================================================== diff -u -N -r69b48f0b4d7fad78f95854e95fca166014311474 -r16a61d123d45e60dea731a6620f6f47acccd8c43 --- src/ch/FileInfo.cpp (.../FileInfo.cpp) (revision 69b48f0b4d7fad78f95854e95fca166014311474) +++ src/ch/FileInfo.cpp (.../FileInfo.cpp) (revision 16a61d123d45e60dea731a6620f6f47acccd8c43) @@ -79,197 +79,12 @@ } } -////////////////////////////////////////////////////////////////////////////// -// CClipboardEntry - -CClipboardEntry::CClipboardEntry() : - m_bMove(true), - m_iDriveNumber(-2), - m_iBufferIndex(-1) -{ -} - -CClipboardEntry::CClipboardEntry(const CClipboardEntry& rEntry) : - m_path(rEntry.m_path), - m_bMove(rEntry.m_bMove), - m_iDriveNumber(rEntry.m_iDriveNumber), - m_pathDst(rEntry.m_pathDst) -{ -} - -void CClipboardEntry::SetPath(const chcore::TSmartPath& tPath) -{ - m_path = tPath; // guaranteed without ending '\\' - m_path.CutIfExists(_T("\\"), false); -} - -chcore::TSmartPath CClipboardEntry::GetFileName() const -{ - TCHAR szName[_MAX_FNAME]; - TCHAR szExt[_MAX_EXT]; - _tsplitpath(m_path.ToString(), NULL, NULL, szName, szExt); - return chcore::PathFromString(CString(szName) + szExt); -} - -int CClipboardEntry::GetDriveNumber() -{ - if(m_iDriveNumber == -2) - GetDriveData(m_path, &m_iDriveNumber, NULL); - - return m_iDriveNumber; -} - -int CClipboardEntry::GetBufferIndex(const chcore::TSmartPath& dpDestPath) -{ - if(m_iBufferIndex == -1) - { - int iDriveNumber = 0; - UINT uiDriveType = 0; - int iDstDriveNumber = 0; - UINT uiDstDriveType = 0; - GetDriveData(m_path, &iDriveNumber, &uiDriveType); - GetDriveData(dpDestPath, &iDstDriveNumber, &uiDstDriveType); - - // what kind of buffer - if(uiDriveType == DRIVE_REMOTE || uiDstDriveType == DRIVE_REMOTE) - m_iBufferIndex = BI_LAN; - else if(uiDriveType == DRIVE_CDROM || uiDstDriveType == DRIVE_CDROM) - m_iBufferIndex = BI_CD; - else if(uiDriveType == DRIVE_FIXED && uiDstDriveType == DRIVE_FIXED) - { - // two hdd's - is this the same physical disk ? - if(iDriveNumber == iDstDriveNumber || IsSamePhysicalDisk(iDriveNumber, iDstDriveNumber)) - m_iBufferIndex = BI_ONEDISK; - else - m_iBufferIndex = BI_TWODISKS; - } - else - m_iBufferIndex = BI_DEFAULT; - } - - return m_iBufferIndex; -} - -void CClipboardEntry::SetDestinationPath(const chcore::TSmartPath& tPath) -{ - m_pathDst = tPath; -} - -chcore::TSmartPath CClipboardEntry::GetDestinationPath() const -{ - return m_pathDst; -} - -////////////////////////////////////////////////////////////////////////////// -// CClipboardArray - -CClipboardArray::CClipboardArray() -{ -} - -CClipboardArray::~CClipboardArray() -{ - RemoveAll(); -} - -CClipboardArray::CClipboardArray(const CClipboardArray& rSrc) : - m_vEntries(rSrc.m_vEntries) -{ -} - -CClipboardArray& CClipboardArray::operator=(const CClipboardArray& rSrc) -{ - if(this != &rSrc) - { - m_vEntries = rSrc.m_vEntries; - } - - return *this; -} - -CClipboardEntryPtr CClipboardArray::GetAt(size_t stPos) const -{ - boost::shared_lock lock(m_lock); - - if(stPos >= m_vEntries.size()) - THROW(_T("Out of range"), 0, 0, 0); - - return m_vEntries.at(stPos); -} - -void CClipboardArray::SetAt(size_t stIndex, const CClipboardEntryPtr& spEntry) -{ - if(!spEntry) - THROW(_T("Invalid argument"), 0, 0, 0); - - boost::unique_lock lock(m_lock); - - if(stIndex >= m_vEntries.size()) - THROW(_T("Out of range"), 0, 0, 0); - - m_vEntries[stIndex] = spEntry; -} - -void CClipboardArray::Add(const CClipboardEntryPtr& spEntry) -{ - boost::unique_lock lock(m_lock); - m_vEntries.push_back(spEntry); -} - -void CClipboardArray::RemoveAt(size_t nIndex, size_t nCount) -{ - boost::unique_lock lock(m_lock); - m_vEntries.erase(m_vEntries.begin() + nIndex, m_vEntries.begin() + nIndex + nCount); -} - -void CClipboardArray::RemoveAll() -{ - boost::unique_lock lock(m_lock); - m_vEntries.clear(); -} - -size_t CClipboardArray::GetSize() const -{ - boost::shared_lock lock(m_lock); - return m_vEntries.size(); -} - -int CClipboardArray::ReplacePathsPrefix(CString strOld, CString strNew) -{ - // small chars to make comparing case insensitive - strOld.MakeLower(); - - CString strText; - int iOffset = 0; - int iCount = 0; - - boost::unique_lock lock(m_lock); - - BOOST_FOREACH(CClipboardEntryPtr& spEntry, m_vEntries) - { - strText = spEntry->GetPath().ToString(); - strText.MakeLower(); - iOffset = strText.Find(strOld, 0); - if(iOffset != -1) - { - // found - strText = spEntry->GetPath().ToString(); - strText = strText.Left(iOffset) + strNew + strText.Mid(iOffset + strOld.GetLength()); - spEntry->SetPath(chcore::PathFromString(strText)); - - ++iCount; - } - } - - return iCount; -} - ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CFileInfo::CFileInfo() : - m_pClipboard(NULL), + m_pBasePaths(NULL), m_pathFile(), m_stSrcIndex(std::numeric_limits::max()), m_dwAttributes(0), @@ -290,7 +105,7 @@ m_ftLastAccess(finf.m_ftLastAccess), m_ftLastWrite(finf.m_ftLastWrite), m_uiFlags(finf.m_uiFlags), - m_pClipboard(finf.m_pClipboard) + m_pBasePaths(finf.m_pBasePaths) { } @@ -324,16 +139,16 @@ void CFileInfo::Create(const WIN32_FIND_DATA* pwfd, const chcore::TSmartPath& pathFile, size_t stSrcIndex) { - BOOST_ASSERT(stSrcIndex == std::numeric_limits::max() || m_pClipboard); - if(stSrcIndex != std::numeric_limits::max() && !m_pClipboard) + BOOST_ASSERT(stSrcIndex == std::numeric_limits::max() || m_pBasePaths); + if(stSrcIndex != std::numeric_limits::max() && !m_pBasePaths) THROW(_t("Internal error: pointer not initialized."), 0, 0, 0); // copy data from W32_F_D m_pathFile = pathFile + chcore::PathFromString(pwfd->cFileName); // if proper index has been passed - reduce the path - if(m_pClipboard && stSrcIndex >= 0) - m_pathFile.MakeRelativePath(m_pClipboard->GetAt(stSrcIndex)->GetPath()); // cut path from clipboard + if(m_pBasePaths && stSrcIndex >= 0) + m_pathFile.MakeRelativePath(m_pBasePaths->GetAt(stSrcIndex)); // cut path from clipboard m_stSrcIndex = stSrcIndex; m_dwAttributes = pwfd->dwFileAttributes; @@ -375,44 +190,24 @@ chcore::TSmartPath CFileInfo::GetFileDrive() const { - BOOST_ASSERT(m_pClipboard); - if(!m_pClipboard) + BOOST_ASSERT(m_pBasePaths); + if(!m_pBasePaths) THROW(_T("Invalid pointer"), 0, 0, 0); - chcore::TSmartPath pathCombined = (m_stSrcIndex != std::numeric_limits::max()) ? m_pClipboard->GetAt(m_stSrcIndex)->GetPath() + m_pathFile : m_pathFile; + chcore::TSmartPath pathCombined = (m_stSrcIndex != std::numeric_limits::max()) ? m_pBasePaths->GetAt(m_stSrcIndex) + m_pathFile : m_pathFile; TCHAR szDrive[_MAX_DRIVE]; _tsplitpath(pathCombined.ToString(), szDrive, NULL, NULL, NULL); return chcore::PathFromString(szDrive); } -int CFileInfo::GetDriveNumber() -{ - BOOST_ASSERT(m_pClipboard); - if(!m_pClipboard) - THROW(_T("Invalid pointer"), 0, 0, 0); - - if(m_stSrcIndex != std::numeric_limits::max()) - { - // read data stored in CClipboardEntry - return m_pClipboard->GetAt(m_stSrcIndex)->GetDriveNumber(); - } - else - { - // manually - int iNum = 0; - GetDriveData(m_pathFile, &iNum, NULL); - return iNum; - } -} - chcore::TSmartPath CFileInfo::GetFileDir() const { - BOOST_ASSERT(m_pClipboard); - if(!m_pClipboard) + BOOST_ASSERT(m_pBasePaths); + if(!m_pBasePaths) THROW(_T("Invalid pointer"), 0, 0, 0); - chcore::TSmartPath pathCombined = (m_stSrcIndex != std::numeric_limits::max()) ? m_pClipboard->GetAt(m_stSrcIndex)->GetPath() + m_pathFile : m_pathFile; + chcore::TSmartPath pathCombined = (m_stSrcIndex != std::numeric_limits::max()) ? m_pBasePaths->GetAt(m_stSrcIndex) + m_pathFile : m_pathFile; TCHAR szDir[_MAX_DIR]; _tsplitpath(pathCombined.ToString(), NULL, szDir, NULL, NULL); @@ -421,37 +216,37 @@ chcore::TSmartPath CFileInfo::GetFileTitle() const { - BOOST_ASSERT(m_pClipboard); - if(!m_pClipboard) + BOOST_ASSERT(m_pBasePaths); + if(!m_pBasePaths) THROW(_T("Invalid pointer"), 0, 0, 0); - chcore::TSmartPath pathCombined = (m_stSrcIndex != std::numeric_limits::max()) ? m_pClipboard->GetAt(m_stSrcIndex)->GetPath()+m_pathFile : m_pathFile; + chcore::TSmartPath pathCombined = (m_stSrcIndex != std::numeric_limits::max()) ? m_pBasePaths->GetAt(m_stSrcIndex) + m_pathFile : m_pathFile; TCHAR szName[_MAX_FNAME]; _tsplitpath(pathCombined.ToString(), NULL, NULL, szName, NULL); return chcore::PathFromString(szName); } chcore::TSmartPath CFileInfo::GetFileExt() const { - ASSERT(m_pClipboard); - BOOST_ASSERT(m_pClipboard); - if(!m_pClipboard) + ASSERT(m_pBasePaths); + BOOST_ASSERT(m_pBasePaths); + if(!m_pBasePaths) THROW(_T("Invalid pointer"), 0, 0, 0); - chcore::TSmartPath pathCombined = (m_stSrcIndex != std::numeric_limits::max()) ? m_pClipboard->GetAt(m_stSrcIndex)->GetPath()+m_pathFile : m_pathFile; + chcore::TSmartPath pathCombined = (m_stSrcIndex != std::numeric_limits::max()) ? m_pBasePaths->GetAt(m_stSrcIndex) + m_pathFile : m_pathFile; TCHAR szExt[_MAX_EXT]; _tsplitpath(pathCombined.ToString(), NULL, NULL, NULL, szExt); return chcore::PathFromString(szExt); } chcore::TSmartPath CFileInfo::GetFileRoot() const { - ASSERT(m_pClipboard); - BOOST_ASSERT(m_pClipboard); - if(!m_pClipboard) + ASSERT(m_pBasePaths); + BOOST_ASSERT(m_pBasePaths); + if(!m_pBasePaths) THROW(_T("Invalid pointer"), 0, 0, 0); - chcore::TSmartPath pathCombined = (m_stSrcIndex != std::numeric_limits::max()) ? m_pClipboard->GetAt(m_stSrcIndex)->GetPath() + m_pathFile : m_pathFile; + chcore::TSmartPath pathCombined = (m_stSrcIndex != std::numeric_limits::max()) ? m_pBasePaths->GetAt(m_stSrcIndex) + m_pathFile : m_pathFile; TCHAR szDrive[_MAX_DRIVE]; TCHAR szDir[_MAX_DIR]; @@ -461,13 +256,13 @@ chcore::TSmartPath CFileInfo::GetFileName() const { - BOOST_ASSERT(m_pClipboard); - if(!m_pClipboard) + BOOST_ASSERT(m_pBasePaths); + if(!m_pBasePaths) THROW(_T("Invalid pointer"), 0, 0, 0); chcore::TSmartPath pathCombined; - if(m_pClipboard && m_stSrcIndex != std::numeric_limits::max()) - pathCombined = m_pClipboard->GetAt(m_stSrcIndex)->GetPath() + m_pathFile; + if(m_pBasePaths && m_stSrcIndex != std::numeric_limits::max()) + pathCombined = m_pBasePaths->GetAt(m_stSrcIndex) + m_pathFile; else { ASSERT(m_stSrcIndex == std::numeric_limits::max()); @@ -490,30 +285,22 @@ { if(m_stSrcIndex != std::numeric_limits::max()) { - BOOST_ASSERT(m_pClipboard); - if(!m_pClipboard) + BOOST_ASSERT(m_pBasePaths); + if(!m_pBasePaths) THROW(_T("Invalid pointer"), 0, 0, 0); - chcore::TSmartPath pathCombined = m_pClipboard->GetAt(m_stSrcIndex)->GetPath(); + chcore::TSmartPath pathCombined = m_pBasePaths->GetAt(m_stSrcIndex); pathCombined += m_pathFile; return pathCombined; } else return m_pathFile; } -int CFileInfo::GetBufferIndex(const chcore::TSmartPath& dpDestPath) const -{ - if(m_stSrcIndex != std::numeric_limits::max()) - return m_pClipboard->GetAt(m_stSrcIndex)->GetBufferIndex(dpDestPath); - else - return BI_DEFAULT; -} - /////////////////////////////////////////////////////////////////////// // Array -CFileInfoArray::CFileInfoArray(const CClipboardArray& rClipboardArray) : - m_rClipboard(rClipboardArray) +CFileInfoArray::CFileInfoArray(const chcore::TPathContainer& rBasePaths) : + m_rBasePaths(rBasePaths) { } @@ -575,21 +362,6 @@ return ullSize; } -int CFileInfoArray::GetBufferIndexAt(size_t stIndex, const chcore::TSmartPath& dpDestPath) const -{ - boost::shared_lock lock(m_lock); - if(stIndex >= m_vFiles.size()) - return 0; - else - { - const CFileInfoPtr& spFileInfo = m_vFiles[stIndex]; - if(!spFileInfo) - THROW(_T("Invalid pointer"), 0, 0, 0); - - return spFileInfo->GetBufferIndex(dpDestPath); - } -} - unsigned long long CFileInfoArray::CalculatePartialSize(size_t stCount) { unsigned long long ullSize = 0; Index: src/ch/FileInfo.h =================================================================== diff -u -N -r69b48f0b4d7fad78f95854e95fca166014311474 -r16a61d123d45e60dea731a6620f6f47acccd8c43 --- src/ch/FileInfo.h (.../FileInfo.h) (revision 69b48f0b4d7fad78f95854e95fca166014311474) +++ src/ch/FileInfo.h (.../FileInfo.h) (revision 16a61d123d45e60dea731a6620f6f47acccd8c43) @@ -31,126 +31,7 @@ #define FIF_PROCESSED 0x00000001 class CFiltersArray; -///////////////////////////////////////////////////////////////////////////// -// CClipboardEntry -class CClipboardEntry -{ -public: - CClipboardEntry(); - CClipboardEntry(const CClipboardEntry& rEntry); - void SetPath(const chcore::TSmartPath& strPath); - chcore::TSmartPath GetPath() const { return m_path; } - chcore::TSmartPath GetFileName() const; - - void SetMove(bool bValue) { m_bMove=bValue; } - bool GetMove() const { return m_bMove; } - - int GetDriveNumber(); - - int GetBufferIndex(const chcore::TSmartPath& dpDestPath); - - template - void Serialize(Archive& ar, unsigned int /*uiVersion*/, bool bData) - { - if(bData) - { - ar & m_path; - ar & m_bMove; - } - else - ar & m_pathDst; - } - - void SetDestinationPath(const chcore::TSmartPath& strPath); - chcore::TSmartPath GetDestinationPath() const; - bool IsDestinationPathSet() const { return !m_pathDst.IsEmpty(); } - -private: - chcore::TSmartPath m_path; // path (ie. c:\\windows\\) - always with ending '\\' - bool m_bMove; // specifies if we can use MoveFile (if will be moved) - - int m_iDriveNumber; // disk number (-1 - none) - - int m_iBufferIndex; // buffer number, with which we'll copy this data - - chcore::TSmartPath m_pathDst; // dest path -}; - -typedef boost::shared_ptr CClipboardEntryPtr; - -////////////////////////////////////////////////////////////////////////// -// CClipboardArray - -class CClipboardArray -{ -public: - CClipboardArray(); - CClipboardArray(const CClipboardArray& rSrc); - ~CClipboardArray(); - - CClipboardArray& operator=(const CClipboardArray& rSrc); - - template - void Store(Archive& ar, unsigned int /*uiVersion*/, bool bData) const - { - boost::shared_lock lock(m_lock); - // write data - size_t stCount = m_vEntries.size(); - ar << stCount; - - BOOST_FOREACH(const CClipboardEntryPtr& spEntry, m_vEntries) - { - spEntry->Serialize(ar, 0, bData); - } - } - - template - void Load(Archive& ar, unsigned int /*uiVersion*/, bool bData) - { - size_t stCount; - ar >> stCount; - - boost::unique_lock lock(m_lock); - - if(!bData && m_vEntries.size() != stCount) - THROW(_T("Count of entries with data differs from the count of state entries"), 0, 0, 0); - - if(bData) - { - m_vEntries.clear(); - m_vEntries.reserve(stCount); - } - - CClipboardEntryPtr spEntry; - for(size_t stIndex = 0; stIndex < stCount; ++stIndex) - { - if(bData) - spEntry.reset(new CClipboardEntry); - else - spEntry = m_vEntries.at(stIndex); - spEntry->Serialize(ar, 0, bData); - - if(bData) - m_vEntries.push_back(spEntry); - } - } - - CClipboardEntryPtr GetAt(size_t iPos) const; - - size_t GetSize() const; - void Add(const CClipboardEntryPtr& pEntry); - void SetAt(size_t nIndex, const CClipboardEntryPtr& pEntry); - void RemoveAt(size_t nIndex, size_t nCount = 1); - void RemoveAll(); - - int ReplacePathsPrefix(CString strOld, CString strNew); - -protected: - std::vector m_vEntries; - mutable boost::shared_mutex m_lock; -}; - class CFileInfo { public: @@ -167,9 +48,7 @@ ULONGLONG GetLength64() const { return m_uhFileSize; } void SetLength64(ULONGLONG uhSize) { m_uhFileSize=uhSize; } - // disk - path and disk number (-1 if none - ie. net disk) chcore::TSmartPath GetFileDrive() const; // returns string with src disk - int GetDriveNumber(); // disk number A - 0, b-1, c-2, ... chcore::TSmartPath GetFileDir() const; // @rdesc Returns \WINDOWS\ for C:\WINDOWS\WIN.INI chcore::TSmartPath GetFileTitle() const; // @cmember returns WIN for C:\WINDOWS\WIN.INI @@ -201,15 +80,11 @@ void SetFlags(uint_t uiFlags, uint_t uiMask = 0xffffffff) { m_uiFlags = (m_uiFlags & ~(uiFlags & uiMask)) | (uiFlags & uiMask); } // operations - void SetClipboard(const CClipboardArray *pClipboard) { m_pClipboard = pClipboard; }; + void SetClipboard(const chcore::TPathContainer* pBasePaths) { m_pBasePaths = pBasePaths; } void SetSrcIndex(size_t stIndex) { m_stSrcIndex = stIndex; }; size_t GetSrcIndex() const { return m_stSrcIndex; }; - bool GetMove() const { if (m_stSrcIndex != std::numeric_limits::max()) return m_pClipboard->GetAt(m_stSrcIndex)->GetMove(); else return true; }; - - int GetBufferIndex(const chcore::TSmartPath& dpDestPath) const; - // operators bool operator==(const CFileInfo& rInfo); @@ -231,7 +106,9 @@ private: chcore::TSmartPath m_pathFile; // contains relative path (first path is in CClipboardArray) + size_t m_stSrcIndex; // index in CClipboardArray table (which contains the first part of the path) + const chcore::TPathContainer* m_pBasePaths; DWORD m_dwAttributes; // attributes ULONGLONG m_uhFileSize; @@ -240,17 +117,14 @@ FILETIME m_ftLastWrite; uint_t m_uiFlags; - - // ptrs to elements providing data - const CClipboardArray* m_pClipboard; }; typedef boost::shared_ptr CFileInfoPtr; class CFileInfoArray { public: - CFileInfoArray(const CClipboardArray& rClipboardArray); + CFileInfoArray(const chcore::TPathContainer& rBasePaths); ~CFileInfoArray(); // Adds a new object info to this container @@ -275,9 +149,6 @@ /// Calculates the size of all file info objects inside this object unsigned long long CalculateTotalSize(); - /// Retrieves buffer index for an item at a specified index - int GetBufferIndexAt(size_t stIndex, const chcore::TSmartPath& dpDestPath) const; - /// Stores infos about elements in the archive template void Store(Archive& ar, unsigned int /*uiVersion*/, bool bOnlyFlags) const; @@ -287,8 +158,9 @@ void Load(Archive& ar, unsigned int /*uiVersion*/, bool bOnlyFlags); protected: - const CClipboardArray& m_rClipboard; + const chcore::TPathContainer& m_rBasePaths; std::vector m_vFiles; + mutable boost::shared_mutex m_lock; }; @@ -337,7 +209,7 @@ else { spFileInfo.reset(new CFileInfo); - spFileInfo->SetClipboard(&m_rClipboard); + spFileInfo->SetClipboard(&m_rBasePaths); ar >> *spFileInfo; m_vFiles.push_back(spFileInfo); } Index: src/ch/TBasePathData.cpp =================================================================== diff -u -N --- src/ch/TBasePathData.cpp (revision 0) +++ src/ch/TBasePathData.cpp (revision 16a61d123d45e60dea731a6620f6f47acccd8c43) @@ -0,0 +1,126 @@ +// ============================================================================ +// Copyright (C) 2001-2010 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. +// ============================================================================ +/// @file TBasePathData.cpp +/// @date 2010/10/13 +/// @brief Contains implementations of classes related to keeping path data. +// ============================================================================ +#include "stdafx.h" +#include "TBasePathData.h" + +////////////////////////////////////////////////////////////////////////////// +// TBasePathData + +TBasePathData::TBasePathData() : + m_bMove(true), + m_iDriveNumber(-2), + m_iBufferIndex(-1) +{ +} + +TBasePathData::TBasePathData(const TBasePathData& rEntry) : + m_bMove(rEntry.m_bMove), + m_iDriveNumber(rEntry.m_iDriveNumber), + m_iBufferIndex(rEntry.m_iBufferIndex), + m_pathDst(rEntry.m_pathDst) +{ +} + +void TBasePathData::SetDestinationPath(const chcore::TSmartPath& tPath) +{ + m_pathDst = tPath; +} + +chcore::TSmartPath TBasePathData::GetDestinationPath() const +{ + return m_pathDst; +} + +////////////////////////////////////////////////////////////////////////////// +// TBasePathDataContainer + +TBasePathDataContainer::TBasePathDataContainer(const chcore::TPathContainer& tBasePaths) : + m_tBasePaths(tBasePaths) +{ +} + +TBasePathDataContainer::~TBasePathDataContainer() +{ + Clear(); +} + +TBasePathDataPtr TBasePathDataContainer::GetAt(size_t stPos) const +{ + boost::shared_lock lock(m_lock); + + if(stPos >= m_vEntries.size()) + THROW(_T("Out of range"), 0, 0, 0); + + return m_vEntries.at(stPos); +} + +void TBasePathDataContainer::SetAt(size_t stIndex, const TBasePathDataPtr& spEntry) +{ + if(!spEntry) + THROW(_T("Invalid argument"), 0, 0, 0); + + boost::unique_lock lock(m_lock); + + if(stIndex >= m_vEntries.size()) + THROW(_T("Out of range"), 0, 0, 0); + + m_vEntries[stIndex] = spEntry; +} + +void TBasePathDataContainer::Add(const TBasePathDataPtr& spEntry) +{ + boost::unique_lock lock(m_lock); + m_vEntries.push_back(spEntry); +} + +void TBasePathDataContainer::RemoveAt(size_t nIndex, size_t nCount) +{ + boost::unique_lock lock(m_lock); + m_vEntries.erase(m_vEntries.begin() + nIndex, m_vEntries.begin() + nIndex + nCount); +} + +void TBasePathDataContainer::Clear() +{ + boost::unique_lock lock(m_lock); + m_vEntries.clear(); +} + +void TBasePathDataContainer::SetCount(size_t stCount) +{ + boost::unique_lock lock(m_lock); + if(stCount > m_vEntries.size()) + { + size_t stCountToAdd = stCount - m_vEntries.size(); + while(stCountToAdd--) + { + TBasePathDataPtr spData(new TBasePathData); + m_vEntries.push_back(spData); + } + } +} + +size_t TBasePathDataContainer::GetCount() const +{ + boost::shared_lock lock(m_lock); + return m_vEntries.size(); +} Index: src/ch/TBasePathData.h =================================================================== diff -u -N --- src/ch/TBasePathData.h (revision 0) +++ src/ch/TBasePathData.h (revision 16a61d123d45e60dea731a6620f6f47acccd8c43) @@ -0,0 +1,154 @@ +// ============================================================================ +// Copyright (C) 2001-2010 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. +// ============================================================================ +/// @file TBasePathData.h +/// @date 2010/10/13 +/// @brief Contains declarations of classes related to keeping additional path data. +// ============================================================================ +#ifndef __TBASEPATHDATA_H__ +#define __TBASEPATHDATA_H__ + +#include "../libchcore/TPath.h" + +///////////////////////////////////////////////////////////////////////////// +// TBasePathData +class TBasePathData +{ +public: + TBasePathData(); + TBasePathData(const TBasePathData& rEntry); + + void SetMove(bool bValue) { m_bMove=bValue; } + bool GetMove() const { return m_bMove; } + + int GetDriveNumber() { return m_iDriveNumber; } + void SetDriveNumber(int iDriveNumber) { m_iDriveNumber = iDriveNumber; } + bool IsDriveNumberSet() const { return m_iDriveNumber != -2; } + + int GetBufferIndex() { return m_iBufferIndex; } + void SetBufferIndex(int iBufferIndex) { m_iBufferIndex = iBufferIndex; } + bool IsBufferIndexSet() const { return m_iBufferIndex != -1; } + + void SetDestinationPath(const chcore::TSmartPath& strPath); + chcore::TSmartPath GetDestinationPath() const; + bool IsDestinationPathSet() const { return !m_pathDst.IsEmpty(); } + + template + void Serialize(Archive& ar, unsigned int /*uiVersion*/, bool bData) + { + if(bData) + ar & m_bMove; + else + ar & m_pathDst; + } + +private: + bool m_bMove; // specifies if we can use MoveFile (if will be moved) + + int m_iDriveNumber; // disk number (default -1 - none) + int m_iBufferIndex; // buffer number, with which we'll copy this data (default 0) + + chcore::TSmartPath m_pathDst; // dest path +}; + +typedef boost::shared_ptr TBasePathDataPtr; + +////////////////////////////////////////////////////////////////////////// +// TBasePathDataContainer + +class TBasePathDataContainer +{ +public: + // constructors/destructor + TBasePathDataContainer(const chcore::TPathContainer& tBasePaths); + ~TBasePathDataContainer(); + + // standard access to data + TBasePathDataPtr GetAt(size_t iPos) const; + + void SetCount(size_t stCount); + size_t GetCount() const; + void Add(const TBasePathDataPtr& pEntry); + void SetAt(size_t nIndex, const TBasePathDataPtr& pEntry); + void RemoveAt(size_t nIndex, size_t nCount = 1); + void Clear(); + + // serialization + template + void Store(Archive& ar, unsigned int /*uiVersion*/, bool bData) const; + + template + void Load(Archive& ar, unsigned int /*uiVersion*/, bool bData); + +private: + TBasePathDataContainer(const TBasePathDataContainer& rSrc); + TBasePathDataContainer& operator=(const TBasePathDataContainer& rSrc); + +protected: + std::vector m_vEntries; + const chcore::TPathContainer& m_tBasePaths; + + mutable boost::shared_mutex m_lock; +}; + +template +void TBasePathDataContainer::Store(Archive& ar, unsigned int /*uiVersion*/, bool bData) const +{ + boost::shared_lock lock(m_lock); + // write data + size_t stCount = m_vEntries.size(); + ar << stCount; + + BOOST_FOREACH(const TBasePathDataPtr& spEntry, m_vEntries) + { + spEntry->Serialize(ar, 0, bData); + } +} + +template +void TBasePathDataContainer::Load(Archive& ar, unsigned int /*uiVersion*/, bool bData) +{ + size_t stCount; + ar >> stCount; + + boost::unique_lock lock(m_lock); + + if(!bData && m_vEntries.size() != stCount) + THROW(_T("Count of entries with data differs from the count of state entries"), 0, 0, 0); + + if(bData) + { + m_vEntries.clear(); + m_vEntries.reserve(stCount); + } + + TBasePathDataPtr spEntry; + for(size_t stIndex = 0; stIndex < stCount; ++stIndex) + { + if(bData) + spEntry.reset(new TBasePathData); + else + spEntry = m_vEntries.at(stIndex); + spEntry->Serialize(ar, 0, bData); + + if(bData) + m_vEntries.push_back(spEntry); + } +} + +#endif // __TBASEPATHDATA_H__ Index: src/ch/ch.vc90.vcproj =================================================================== diff -u -N -r3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529 -r16a61d123d45e60dea731a6620f6f47acccd8c43 --- src/ch/ch.vc90.vcproj (.../ch.vc90.vcproj) (revision 3f72015a9db19bd1b0a5e20e0f1aa0ec00bda529) +++ src/ch/ch.vc90.vcproj (.../ch.vc90.vcproj) (revision 16a61d123d45e60dea731a6620f6f47acccd8c43) @@ -1,7 +1,7 @@ + + + + Index: src/ch/task.cpp =================================================================== diff -u -N -r69b48f0b4d7fad78f95854e95fca166014311474 -r16a61d123d45e60dea731a6620f6f47acccd8c43 --- src/ch/task.cpp (.../task.cpp) (revision 69b48f0b4d7fad78f95854e95fca166014311474) +++ src/ch/task.cpp (.../task.cpp) (revision 16a61d123d45e60dea731a6620f6f47acccd8c43) @@ -31,6 +31,8 @@ #include "TTaskConfiguration.h" #include "TSubTaskContext.h" +#include "Device IO.h" + // assume max sectors of 4kB (for rounding) #define MAXSECTORSIZE 4096 @@ -417,7 +419,8 @@ CTask::CTask(chcore::IFeedbackHandler* piFeedbackHandler, size_t stSessionUniqueID) : m_log(), m_piFeedbackHandler(piFeedbackHandler), - m_files(m_arrSourcePaths), + m_arrSourcePathsInfo(m_tTaskDefinition.GetSourcePaths()), + m_files(m_tTaskDefinition.GetSourcePaths()), m_bForce(false), m_bContinue(false), m_bRareStateModified(false), @@ -440,16 +443,8 @@ { m_tTaskDefinition = rTaskDefinition; - m_arrSourcePaths.RemoveAll(); + m_arrSourcePathsInfo.SetCount(m_tTaskDefinition.GetSourcePathCount()); m_files.Clear(); - - for(size_t stIndex = 0; stIndex < m_tTaskDefinition.GetSourcePaths().GetCount(); ++stIndex) - { - CClipboardEntryPtr spEntry(new CClipboardEntry); - spEntry->SetPath(m_tTaskDefinition.GetSourcePaths().GetAt(stIndex)); - - m_arrSourcePaths.Add(spEntry); - } } void CTask::OnRegisterTask(TTasksGlobalStats& rtGlobalStats) @@ -482,7 +477,7 @@ if(!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { CFileInfoPtr spFileInfo(boost::make_shared()); - spFileInfo->SetClipboard(&m_arrSourcePaths); // this is the link table (CClipboardArray) + spFileInfo->SetClipboard(&m_tTaskDefinition.GetSourcePaths()); // this is the link table (CClipboardArray) spFileInfo->Create(&wfd, pathDirName, stSrcIndex); if(m_afFilters.Match(spFileInfo)) @@ -493,7 +488,7 @@ if(bIncludeDirs) { CFileInfoPtr spFileInfo(boost::make_shared()); - spFileInfo->SetClipboard(&m_arrSourcePaths); // this is the link table (CClipboardArray) + spFileInfo->SetClipboard(&m_tTaskDefinition.GetSourcePaths()); // this is the link table (CClipboardArray) // Add directory itself spFileInfo->Create(&wfd, pathDirName, stSrcIndex); @@ -555,7 +550,7 @@ int CTask::GetCurrentBufferIndex() { - return m_files.GetBufferIndexAt(m_tTaskBasicProgressInfo.GetCurrentIndex(), m_tTaskDefinition.GetDestinationPath()); + return GetBufferIndex(m_files.GetAt(m_tTaskBasicProgressInfo.GetCurrentIndex())); } // thread @@ -598,13 +593,16 @@ m_tTaskDefinition.Load(strPath); m_strFilePath = strPath; + // make sure to resize paths info array size to match source paths count + m_arrSourcePathsInfo.SetCount(m_tTaskDefinition.GetSourcePathCount()); + //////////////////////////////// // now rarely changing task progress data CString strRarelyChangingPath = GetRelatedPathNL(ePathType_TaskRarelyChangingState); std::ifstream ifs(strRarelyChangingPath, ios_base::in | ios_base::binary); boost::archive::binary_iarchive ar(ifs); - m_arrSourcePaths.Load(ar, 0, true); + m_arrSourcePathsInfo.Load(ar, 0, true); m_files.Load(ar, 0, false); CalculateTotalSizeNL(); @@ -640,7 +638,7 @@ ar2 >> timeElapsed; m_localStats.SetTimeElapsed(timeElapsed); - m_arrSourcePaths.Load(ar2, 0, false); + m_arrSourcePathsInfo.Load(ar2, 0, false); m_files.Load(ar2, 0, true); } @@ -668,7 +666,7 @@ std::ofstream ofs(GetRelatedPathNL(ePathType_TaskRarelyChangingState), ios_base::out | ios_base::binary); boost::archive::binary_oarchive ar(ofs); - m_arrSourcePaths.Store(ar, 0, true); + m_arrSourcePathsInfo.Store(ar, 0, true); m_files.Store(ar, 0, false); ar << m_afFilters; @@ -691,7 +689,7 @@ time_t timeElapsed = m_localStats.GetTimeElapsed(); ar << timeElapsed; - m_arrSourcePaths.Store(ar, 0, false); + m_arrSourcePathsInfo.Store(ar, 0, false); ESubOperationType eSubOperation = m_tTaskDefinition.GetOperationPlan().GetSubOperationAt(m_tTaskBasicProgressInfo.GetSubOperationIndex()); if(eSubOperation != eSubOperation_Scanning) @@ -788,7 +786,7 @@ else { if(m_tTaskDefinition.GetSourcePathCount() > 0) - pData->m_strPath = m_arrSourcePaths.GetAt(0)->GetFileName().ToString(); + pData->m_strPath = m_tTaskDefinition.GetSourcePathAt(0).GetLastComponent().ToString(); else pData->m_strPath.Empty(); } @@ -821,8 +819,8 @@ { if(m_tTaskDefinition.GetSourcePathCount() > 0) { - pData->m_strFullFilePath = m_arrSourcePaths.GetAt(0)->GetPath().ToString(); - pData->m_strFileName = m_arrSourcePaths.GetAt(0)->GetFileName().ToString(); + pData->m_strFullFilePath = m_tTaskDefinition.GetSourcePathAt(0).ToString(); + pData->m_strFileName = m_tTaskDefinition.GetSourcePathAt(0).GetLastComponent().ToString(); } else { @@ -848,9 +846,9 @@ pData->m_bCreateEmptyFiles = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()); if(m_files.GetSize() > 0) - pData->m_iCurrentBufferIndex = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()) ? 0 : m_files.GetAt((stCurrentIndex < m_files.GetSize()) ? stCurrentIndex : 0)->GetBufferIndex(m_tTaskDefinition.GetDestinationPath()); + pData->m_iCurrentBufferIndex = GetTaskPropValue(m_tTaskDefinition.GetConfiguration()) ? BI_DEFAULT : GetBufferIndex(m_files.GetAt((stCurrentIndex < m_files.GetSize()) ? stCurrentIndex : 0)); else - pData->m_iCurrentBufferIndex = 0; + pData->m_iCurrentBufferIndex = BI_DEFAULT; switch(pData->m_iCurrentBufferIndex) { @@ -1071,18 +1069,18 @@ bSkipInputPath = false; spFileInfo.reset(new CFileInfo()); - spFileInfo->SetClipboard(&m_arrSourcePaths); + spFileInfo->SetClipboard(&m_tTaskDefinition.GetSourcePaths()); // 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 = spFileInfo->Create(m_arrSourcePaths.GetAt(stIndex)->GetPath(), stIndex); + bool bExists = spFileInfo->Create(m_tTaskDefinition.GetSourcePathAt(stIndex), stIndex); if(!bExists) { - CString strSrcFile = m_arrSourcePaths.GetAt(stIndex)->GetPath().ToString(); + CString strSrcFile = m_tTaskDefinition.GetSourcePathAt(stIndex).ToString(); FEEDBACK_FILEERROR ferr = { (PCTSTR)strSrcFile, NULL, eFastMoveError, ERROR_FILE_NOT_FOUND }; CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)m_piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileError, &ferr); switch(frResult) @@ -1117,20 +1115,20 @@ // log fmt.SetFormat(_T("Adding file/folder (clipboard) : %path ...")); - fmt.SetParam(_t("%path"), m_arrSourcePaths.GetAt(stIndex)->GetPath().ToString()); + fmt.SetParam(_t("%path"), m_tTaskDefinition.GetSourcePathAt(stIndex).ToString()); m_log.logi(fmt); // found file/folder - check if the dest name has been generated - if(!m_arrSourcePaths.GetAt(stIndex)->IsDestinationPathSet()) + if(!m_arrSourcePathsInfo.GetAt(stIndex)->IsDestinationPathSet()) { // generate something - if dest folder == src folder - search for copy if(m_tTaskDefinition.GetDestinationPath() == spFileInfo->GetFileRoot()) { chcore::TSmartPath pathSubst = FindFreeSubstituteName(spFileInfo->GetFullFilePath(), m_tTaskDefinition.GetDestinationPath()); - m_arrSourcePaths.GetAt(stIndex)->SetDestinationPath(pathSubst); + m_arrSourcePathsInfo.GetAt(stIndex)->SetDestinationPath(pathSubst); } else - m_arrSourcePaths.GetAt(stIndex)->SetDestinationPath(spFileInfo->GetFileName()); + m_arrSourcePathsInfo.GetAt(stIndex)->SetDestinationPath(spFileInfo->GetFileName()); } // add if needed @@ -1149,7 +1147,7 @@ } // don't add folder contents when moving inside one disk boundary - if(bIgnoreDirs || !bMove || iDestDrvNumber == -1 || iDestDrvNumber != spFileInfo->GetDriveNumber() || + if(bIgnoreDirs || !bMove || iDestDrvNumber == -1 || iDestDrvNumber != GetDriveNumber(spFileInfo) || CFileInfo::Exist(GetDestinationPath(spFileInfo, m_tTaskDefinition.GetDestinationPath(), ((int)bForceDirectories) << 1)) ) { // log @@ -1158,7 +1156,7 @@ m_log.logi(fmt); // no movefile possibility - use CustomCopyFileFB - m_arrSourcePaths.GetAt(stIndex)->SetMove(false); + m_arrSourcePathsInfo.GetAt(stIndex)->SetMove(false); ScanDirectory(spFileInfo->GetFullFilePath(), stIndex, true, !bIgnoreDirs || bForceDirectories); } @@ -1174,15 +1172,15 @@ } else { - if(bMove && iDestDrvNumber != -1 && iDestDrvNumber == spFileInfo->GetDriveNumber() && + if(bMove && iDestDrvNumber != -1 && iDestDrvNumber == GetDriveNumber(spFileInfo) && !CFileInfo::Exist(GetDestinationPath(spFileInfo, m_tTaskDefinition.GetDestinationPath(), ((int)bForceDirectories) << 1)) ) { // if moving within one partition boundary set the file size to 0 so the overall size will // be ok spFileInfo->SetLength64(0); } else - m_arrSourcePaths.GetAt(stIndex)->SetMove(false); // no MoveFile + m_arrSourcePathsInfo.GetAt(stIndex)->SetMove(false); // no MoveFile // add file info if passes filters if(m_afFilters.Match(spFileInfo)) @@ -1928,7 +1926,7 @@ if(GetTaskPropValue(m_tTaskDefinition.GetConfiguration())) iBufferIndex = BI_DEFAULT; else - iBufferIndex = pData->spSrcFile->GetBufferIndex(m_tTaskDefinition.GetDestinationPath()); + iBufferIndex = GetBufferIndex(pData->spSrcFile); ulToRead = bNoBuffer ? ROUNDUP(pData->dbBuffer.GetSizes()->m_auiSizes[iBufferIndex], MAXSECTORSIZE) : pData->dbBuffer.GetSizes()->m_auiSizes[iBufferIndex]; @@ -2118,7 +2116,7 @@ bool bMove = m_tTaskDefinition.GetOperationType() == eOperation_Move; if(bMove) GetDriveData(m_tTaskDefinition.GetDestinationPath(), &iDstDriveNumber, NULL); - if(bMove && iDstDriveNumber != -1 && iDstDriveNumber == spFileInfo->GetDriveNumber() && spFileInfo->GetMove()) + if(bMove && iDstDriveNumber != -1 && iDstDriveNumber == GetDriveNumber(spFileInfo) && GetMove(spFileInfo)) { bool bRetry = true; if(bRetry && !MoveFile(spFileInfo->GetFullFilePath().ToString(), ccp.pathDstFile.ToString())) @@ -2292,7 +2290,7 @@ if(m_tTaskDefinition.GetSourcePathCount() > 0) { - FEEDBACK_NOTENOUGHSPACE feedStruct = { ullNeededSize, m_arrSourcePaths.GetAt(0)->GetPath().ToString(), m_tTaskDefinition.GetDestinationPath().ToString() }; + FEEDBACK_NOTENOUGHSPACE feedStruct = { ullNeededSize, m_tTaskDefinition.GetSourcePathAt(0).ToString(), m_tTaskDefinition.GetDestinationPath().ToString() }; CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)m_piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_NotEnoughSpace, &feedStruct); // default @@ -2646,19 +2644,106 @@ if (!(iFlags & 0x01) && stSrcIndex != std::numeric_limits::max()) { // generate new dest name - if(!m_arrSourcePaths.GetAt(stSrcIndex)->IsDestinationPathSet()) + if(!m_arrSourcePathsInfo.GetAt(stSrcIndex)->IsDestinationPathSet()) { chcore::TSmartPath pathSubst = FindFreeSubstituteName(spFileInfo->GetFullFilePath(), pathDst); - m_arrSourcePaths.GetAt(stSrcIndex)->SetDestinationPath(pathSubst); + m_arrSourcePathsInfo.GetAt(stSrcIndex)->SetDestinationPath(pathSubst); } - return pathDst + m_arrSourcePaths.GetAt(stSrcIndex)->GetDestinationPath() + spFileInfo->GetFilePath(); + return pathDst + m_arrSourcePathsInfo.GetAt(stSrcIndex)->GetDestinationPath() + spFileInfo->GetFilePath(); } else return pathDst + spFileInfo->GetFileName(); } } +int CTask::GetBufferIndex(const CFileInfoPtr& spFileInfo) +{ + if(!spFileInfo) + THROW(_T("Invalid pointer"), 0, 0, 0); + if(spFileInfo->GetSrcIndex() == std::numeric_limits::max()) + THROW(_T("Received non-relative (standalone) path info"), 0, 0, 0); + + // check if this information has already been stored + size_t stBaseIndex = spFileInfo->GetSrcIndex(); + if(stBaseIndex >= m_arrSourcePathsInfo.GetCount()) + THROW(_T("Index out of bounds"), 0, 0, 0); + + TBasePathDataPtr spPathData = m_arrSourcePathsInfo.GetAt(stBaseIndex); + if(spPathData->IsBufferIndexSet()) + return spPathData->GetBufferIndex(); + + // buffer index wasn't cached previously - read it now + int iDriveNumber = 0; + UINT uiDriveType = 0; + int iDstDriveNumber = 0; + UINT uiDstDriveType = 0; + GetDriveData(m_tTaskDefinition.GetSourcePathAt(stBaseIndex), &iDriveNumber, &uiDriveType); + GetDriveData(m_tTaskDefinition.GetDestinationPath(), &iDstDriveNumber, &uiDstDriveType); + + // what kind of buffer + int iBufferIndex = BI_DEFAULT; + if(uiDriveType == DRIVE_REMOTE || uiDstDriveType == DRIVE_REMOTE) + iBufferIndex = BI_LAN; + else if(uiDriveType == DRIVE_CDROM || uiDstDriveType == DRIVE_CDROM) + iBufferIndex = BI_CD; + else if(uiDriveType == DRIVE_FIXED && uiDstDriveType == DRIVE_FIXED) + { + // two hdd's - is this the same physical disk ? + if(iDriveNumber == iDstDriveNumber || IsSamePhysicalDisk(iDriveNumber, iDstDriveNumber)) + iBufferIndex = BI_ONEDISK; + else + iBufferIndex = BI_TWODISKS; + } + else + iBufferIndex = BI_DEFAULT; + + spPathData->SetBufferIndex(iBufferIndex); + + return iBufferIndex; +} + +int CTask::GetDriveNumber(const CFileInfoPtr& spFileInfo) +{ + if(!spFileInfo) + THROW(_T("Invalid pointer"), 0, 0, 0); + if(spFileInfo->GetSrcIndex() == std::numeric_limits::max()) + THROW(_T("Received non-relative (standalone) path info"), 0, 0, 0); + + // check if this information has already been stored + size_t stBaseIndex = spFileInfo->GetSrcIndex(); + if(stBaseIndex >= m_arrSourcePathsInfo.GetCount()) + THROW(_T("Index out of bounds"), 0, 0, 0); + + TBasePathDataPtr spPathData = m_arrSourcePathsInfo.GetAt(stBaseIndex); + if(spPathData->IsDriveNumberSet()) + return spPathData->GetDriveNumber(); + + // buffer index wasn't cached previously - read it now + int iDriveNumber = 0; + GetDriveData(m_tTaskDefinition.GetSourcePathAt(stBaseIndex), &iDriveNumber, NULL); + + spPathData->SetDriveNumber(iDriveNumber); + + return iDriveNumber; +} + +bool CTask::GetMove(const CFileInfoPtr& spFileInfo) +{ + if(!spFileInfo) + THROW(_T("Invalid pointer"), 0, 0, 0); + if(spFileInfo->GetSrcIndex() == std::numeric_limits::max()) + THROW(_T("Received non-relative (standalone) path info"), 0, 0, 0); + + // check if this information has already been stored + size_t stBaseIndex = spFileInfo->GetSrcIndex(); + if(stBaseIndex >= m_arrSourcePathsInfo.GetCount()) + THROW(_T("Index out of bounds"), 0, 0, 0); + + TBasePathDataPtr spPathData = m_arrSourcePathsInfo.GetAt(stBaseIndex); + return spPathData->GetMove(); +} + //////////////////////////////////////////////////////////////////////////////// // CTaskArray members CTaskArray::CTaskArray() : Index: src/ch/task.h =================================================================== diff -u -N -r69b48f0b4d7fad78f95854e95fca166014311474 -r16a61d123d45e60dea731a6620f6f47acccd8c43 --- src/ch/task.h (.../task.h) (revision 69b48f0b4d7fad78f95854e95fca166014311474) +++ src/ch/task.h (.../task.h) (revision 16a61d123d45e60dea731a6620f6f47acccd8c43) @@ -27,6 +27,7 @@ #include "FileFilter.h" #include "TTaskDefinition.h" #include "TTaskConfigTracker.h" +#include "TBasePathData.h" // enum representing current processing state of the task enum ETaskCurrentState @@ -396,13 +397,17 @@ chcore::TSmartPath FindFreeSubstituteName(chcore::TSmartPath pathSrcPath, chcore::TSmartPath pathDstPath) const; chcore::TSmartPath GetDestinationPath(const CFileInfoPtr& spFileInfo, chcore::TSmartPath strPath, int iFlags) const; + int GetBufferIndex(const CFileInfoPtr& spFileInfo); + int GetDriveNumber(const CFileInfoPtr& spFileInfo); + bool GetMove(const CFileInfoPtr& spFileInfo); + private: // task initial information (needed to start a task); might be a bit processed. TTaskDefinition m_tTaskDefinition; TTaskConfigTracker m_cfgTracker; - CClipboardArray m_arrSourcePaths; + TBasePathDataContainer m_arrSourcePathsInfo; // task settings CFiltersArray m_afFilters; // filtering settings for files (will be filtered according to the rules inside when searching for files)