From 1c07f8ddda94254ab4f0e985ffb3e5fdea2da921 Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Thu, 19 Dec 2019 23:30:00 -0500 Subject: refactoring: whitespace, newlines, auto, removed commented out code --- src/shared/directoryentry.cpp | 491 +++++++++++++++++++++++------------------- 1 file changed, 275 insertions(+), 216 deletions(-) (limited to 'src') diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index a3a1459c..3b98b7ff 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -34,21 +34,43 @@ along with Mod Organizer. If not, see . #include #include +namespace MOShared +{ -namespace MOShared { +using namespace MOBase; +static const int MAXPATH_UNICODE = 32767; -namespace log = MOBase::log; +static std::wstring tail(const std::wstring &source, const size_t count) +{ + if (count >= source.length()) { + return source; + } -static const int MAXPATH_UNICODE = 32767; + return source.substr(source.length() - count); +} -class OriginConnection { +static bool SupportOptimizedFind() +{ + // large fetch and basic info for FindFirstFileEx is supported on win server 2008 r2, win 7 and newer -public: + OSVERSIONINFOEX versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + versionInfo.dwMajorVersion = 6; + versionInfo.dwMinorVersion = 1; - typedef int Index; - static const int INVALID_INDEX = INT_MIN; + ULONGLONG mask = ::VerSetConditionMask( + ::VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, VER_GREATER_EQUAL); + + return (::VerifyVersionInfo(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, mask) == TRUE); +} + +class OriginConnection +{ public: + typedef int Index; + static const int INVALID_INDEX = INT_MIN; OriginConnection() : m_NextID(0) @@ -61,25 +83,34 @@ public: LEAK_UNTRACE; } - FilesOrigin& createOrigin(const std::wstring &originName, const std::wstring &directory, int priority, - boost::shared_ptr fileRegister, boost::shared_ptr originConnection) { + FilesOrigin& createOrigin( + const std::wstring &originName, const std::wstring &directory, int priority, + boost::shared_ptr fileRegister, + boost::shared_ptr originConnection) + { int newID = createID(); + m_Origins[newID] = FilesOrigin(newID, originName, directory, priority, fileRegister, originConnection); m_OriginsNameMap[originName] = newID; m_OriginsPriorityMap[priority] = newID; + return m_Origins[newID]; } - bool exists(const std::wstring &name) { + bool exists(const std::wstring &name) + { return m_OriginsNameMap.find(name) != m_OriginsNameMap.end(); } - FilesOrigin &getByID(Index ID) { + FilesOrigin &getByID(Index ID) + { return m_Origins[ID]; } - FilesOrigin &getByName(const std::wstring &name) { + FilesOrigin &getByName(const std::wstring &name) + { std::map::iterator iter = m_OriginsNameMap.find(name); + if (iter != m_OriginsNameMap.end()) { return m_Origins[iter->second]; } else { @@ -92,6 +123,7 @@ public: void changePriorityLookup(int oldPriority, int newPriority) { auto iter = m_OriginsPriorityMap.find(oldPriority); + if (iter != m_OriginsPriorityMap.end()) { Index idx = iter->second; m_OriginsPriorityMap.erase(iter); @@ -102,6 +134,7 @@ public: void changeNameLookup(const std::wstring &oldName, const std::wstring &newName) { auto iter = m_OriginsNameMap.find(oldName); + if (iter != m_OriginsNameMap.end()) { Index idx = iter->second; m_OriginsNameMap.erase(iter); @@ -112,56 +145,16 @@ public: } private: - - Index createID() { - return m_NextID++; - } - -private: - Index m_NextID; - std::map m_Origins; std::map m_OriginsNameMap; std::map m_OriginsPriorityMap; -}; - - -// -// FilesOrigin -// - - -void FilesOrigin::enable(bool enabled, time_t notAfter) -{ - if (!enabled) { - std::set copy = m_Files; - m_FileRegister.lock()->removeOriginMulti(copy, m_ID, notAfter); - m_Files.clear(); - } - m_Disabled = !enabled; -} - - -void FilesOrigin::removeFile(FileEntry::Index index) -{ - auto iter = m_Files.find(index); - if (iter != m_Files.end()) { - m_Files.erase(iter); - } -} - - - -static std::wstring tail(const std::wstring &source, const size_t count) -{ - if (count >= source.length()) { - return source; + Index createID() + { + return m_NextID++; } - - return source.substr(source.length() - count); -} +}; FilesOrigin::FilesOrigin() @@ -183,9 +176,13 @@ FilesOrigin::FilesOrigin(const FilesOrigin &reference) } -FilesOrigin::FilesOrigin(int ID, const std::wstring &name, const std::wstring &path, int priority, boost::shared_ptr fileRegister, boost::shared_ptr originConnection) - : m_ID(ID), m_Disabled(false), m_Name(name), m_Path(path), m_Priority(priority), - m_FileRegister(fileRegister), m_OriginConnection(originConnection) +FilesOrigin::FilesOrigin( + int ID, const std::wstring &name, const std::wstring &path, int priority, + boost::shared_ptr fileRegister, + boost::shared_ptr originConnection) : + m_ID(ID), m_Disabled(false), m_Name(name), m_Path(path), + m_Priority(priority), m_FileRegister(fileRegister), + m_OriginConnection(originConnection) { LEAK_TRACE; } @@ -195,7 +192,6 @@ FilesOrigin::~FilesOrigin() LEAK_UNTRACE; } - void FilesOrigin::setPriority(int priority) { m_OriginConnection.lock()->changePriorityLookup(m_Priority, priority); @@ -203,23 +199,27 @@ void FilesOrigin::setPriority(int priority) m_Priority = priority; } - void FilesOrigin::setName(const std::wstring &name) { m_OriginConnection.lock()->changeNameLookup(m_Name, name); + // change path too if (tail(m_Path, m_Name.length()) == m_Name) { m_Path = m_Path.substr(0, m_Path.length() - m_Name.length()).append(name); } + m_Name = name; } std::vector FilesOrigin::getFiles() const { std::vector result; - for (FileEntry::Index fileIdx : m_Files) - if (FileEntry::Ptr p = m_FileRegister.lock()->getFile(fileIdx)) + + for (FileEntry::Index fileIdx : m_Files) { + if (FileEntry::Ptr p = m_FileRegister.lock()->getFile(fileIdx)) { result.push_back(p); + } + } return result; } @@ -229,67 +229,101 @@ FileEntry::Ptr FilesOrigin::findFile(FileEntry::Index index) const return m_FileRegister.lock()->getFile(index); } +void FilesOrigin::enable(bool enabled, time_t notAfter) +{ + if (!enabled) { + std::set copy = m_Files; + m_FileRegister.lock()->removeOriginMulti(copy, m_ID, notAfter); + m_Files.clear(); + } + + m_Disabled = !enabled; +} + +void FilesOrigin::removeFile(FileEntry::Index index) +{ + auto iter = m_Files.find(index); + + if (iter != m_Files.end()) { + m_Files.erase(iter); + } +} + bool FilesOrigin::containsArchive(std::wstring archiveName) { - for (FileEntry::Index fileIdx : m_Files) - if (FileEntry::Ptr p = m_FileRegister.lock()->getFile(fileIdx)) - if (p->isFromArchive(archiveName)) return true; + for (FileEntry::Index fileIdx : m_Files) { + if (FileEntry::Ptr p = m_FileRegister.lock()->getFile(fileIdx)) { + if (p->isFromArchive(archiveName)) { + return true; + } + } + } + return false; } -// -// FileEntry -// -void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &archive, int order) +void FileEntry::addOrigin( + int origin, FILETIME fileTime, const std::wstring &archive, int order) { m_LastAccessed = time(nullptr); if (m_Parent != nullptr) { m_Parent->propagateOrigin(origin); } - // If this file has no previous origin, this mod is now the origin with no alternatives if (m_Origin == -1) { + // If this file has no previous origin, this mod is now the origin with no + // alternatives m_Origin = origin; m_FileTime = fileTime; m_Archive = std::pair(archive, order); } - - // If this mod has a higher priority than the origin mod OR - // this mod has a loose file and the origin mod has an archived file, - // this mod is now the origin and the previous origin is the first alternative - else if ((m_Parent != nullptr) - && ((m_Parent->getOriginByID(origin).getPriority() > m_Parent->getOriginByID(m_Origin).getPriority()) - || (archive.size() == 0 && m_Archive.first.size() > 0 ))) { - if (std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair> &i) -> bool { return i.first == m_Origin; }) == m_Alternatives.end()) { - m_Alternatives.push_back(std::pair>(m_Origin, m_Archive)); + else if ( + (m_Parent != nullptr) && ( + (m_Parent->getOriginByID(origin).getPriority() > m_Parent->getOriginByID(m_Origin).getPriority()) || + (archive.size() == 0 && m_Archive.first.size() > 0 )) + ) { + // If this mod has a higher priority than the origin mod OR + // this mod has a loose file and the origin mod has an archived file, + // this mod is now the origin and the previous origin is the first alternative + + auto itor = std::find_if( + m_Alternatives.begin(), m_Alternatives.end(), + [&](auto&& i) { return i.first == m_Origin; }); + + if (itor == m_Alternatives.end()) { + m_Alternatives.push_back({m_Origin, m_Archive}); } + m_Origin = origin; m_FileTime = fileTime; m_Archive = std::pair(archive, order); } - - // This mod is just an alternative else { + // This mod is just an alternative bool found = false; + if (m_Origin == origin) { // already an origin return; } - for (std::vector>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { + + for (auto iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { if (iter->first == origin) { // already an origin return; } - if ((m_Parent != nullptr) - && (m_Parent->getOriginByID(iter->first).getPriority() < m_Parent->getOriginByID(origin).getPriority())) { - m_Alternatives.insert(iter, std::pair>(origin, std::pair(archive, order))); + + if ((m_Parent != nullptr) && + (m_Parent->getOriginByID(iter->first).getPriority() < m_Parent->getOriginByID(origin).getPriority())) { + m_Alternatives.insert(iter, {origin, {archive, order}}); found = true; break; } } + if (!found) { - m_Alternatives.push_back(std::pair>(origin, std::pair(archive, order))); + m_Alternatives.push_back({origin, {archive, order}}); } } } @@ -299,10 +333,9 @@ bool FileEntry::removeOrigin(int origin) if (m_Origin == origin) { if (!m_Alternatives.empty()) { // find alternative with the highest priority - std::vector>>::iterator currentIter = m_Alternatives.begin(); - for (std::vector>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { + auto currentIter = m_Alternatives.begin(); + for (auto iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) { if (iter->first != origin) { - //Both files are not from archives. if (!iter->second.first.size() && !currentIter->second.first.size()) { if ((m_Parent->getOriginByID(iter->first).getPriority() > m_Parent->getOriginByID(currentIter->first).getPriority())) { @@ -325,35 +358,25 @@ bool FileEntry::removeOrigin(int origin) } } } + int currentID = currentIter->first; m_Archive = currentIter->second; m_Alternatives.erase(currentIter); m_Origin = currentID; - - // now we need to update the file time... - //std::wstring filePath = getFullPath(); - //HANDLE file = ::CreateFile(filePath.c_str(), GENERIC_READ | GENERIC_WRITE, - // 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); - //if (!::GetFileTime(file, nullptr, nullptr, &m_FileTime)) { - // maybe this file is in a bsa, but there is no easy way to find out which. User should refresh - // the view to find out - //m_Archive = std::pair(L"bsa?", -1); - //} else { - //m_Archive = std::pair(L"", -1); - //} - - //::CloseHandle(file); - } else { m_Origin = -1; m_Archive = std::pair(L"", -1); return true; } } else { - auto newEnd = std::remove_if(m_Alternatives.begin(), m_Alternatives.end(), [&](auto &i) -> bool { return i.first == origin; }); - if (newEnd != m_Alternatives.end()) + auto newEnd = std::remove_if( + m_Alternatives.begin(), m_Alternatives.end(), + [&](auto &i) { return i.first == origin; }); + + if (newEnd != m_Alternatives.end()) { m_Alternatives.erase(newEnd, m_Alternatives.end()); + } } return false; } @@ -379,11 +402,19 @@ FileEntry::~FileEntry() void FileEntry::sortOrigins() { - m_Alternatives.push_back(std::pair>(m_Origin, m_Archive)); - std::sort(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair> &LHS, const std::pair> &RHS) -> bool { + m_Alternatives.push_back({m_Origin, m_Archive}); + + std::sort(m_Alternatives.begin(), m_Alternatives.end(), [&](auto&& LHS, auto&& RHS) { if (!LHS.second.first.size() && !RHS.second.first.size()) { - int l = m_Parent->getOriginByID(LHS.first).getPriority(); if (l < 0) l = INT_MAX; - int r = m_Parent->getOriginByID(RHS.first).getPriority(); if (r < 0) r = INT_MAX; + int l = m_Parent->getOriginByID(LHS.first).getPriority(); + if (l < 0) { + l = INT_MAX; + } + + int r = m_Parent->getOriginByID(RHS.first).getPriority(); + if (r < 0) { + r = INT_MAX; + } return l < r; } @@ -395,9 +426,13 @@ void FileEntry::sortOrigins() return l < r; } - if (RHS.second.first.size()) return false; + if (RHS.second.first.size()) { + return false; + } + return true; }); + if (!m_Alternatives.empty()) { m_Origin = m_Alternatives.back().first; m_Archive = m_Alternatives.back().second; @@ -405,7 +440,6 @@ void FileEntry::sortOrigins() } } - bool FileEntry::recurseParents(std::wstring &path, const DirectoryEntry *parent) const { if (parent == nullptr) { @@ -415,42 +449,57 @@ bool FileEntry::recurseParents(std::wstring &path, const DirectoryEntry *parent) if (recurseParents(path, parent->getParent())) { path.append(L"\\").append(parent->getName()); } + return true; } } std::wstring FileEntry::getFullPath() const { - std::wstring result; bool ignore = false; - result = m_Parent->getOriginByID(getOrigin(ignore)).getPath(); //base directory for origin - recurseParents(result, m_Parent); // all intermediate directories + + // base directory for origin + std::wstring result = m_Parent->getOriginByID(getOrigin(ignore)).getPath(); + + // all intermediate directories + recurseParents(result, m_Parent); + return result + L"\\" + m_Name; } std::wstring FileEntry::getRelativePath() const { std::wstring result; - recurseParents(result, m_Parent); // all intermediate directories + + // all intermediate directories + recurseParents(result, m_Parent); + return result + L"\\" + m_Name; } bool FileEntry::isFromArchive(std::wstring archiveName) const { - if (archiveName.length() == 0) return m_Archive.first.length() != 0; - if (m_Archive.first.compare(archiveName) == 0) return true; + if (archiveName.length() == 0) { + return m_Archive.first.length() != 0; + } + + if (m_Archive.first.compare(archiveName) == 0) { + return true; + } + for (auto alternative : m_Alternatives) { - if (alternative.second.first.compare(archiveName) == 0) return true; + if (alternative.second.first.compare(archiveName) == 0) { + return true; + } } + return false; } -// -// DirectoryEntry -// -DirectoryEntry::DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, int originID) - : m_OriginConnection(new OriginConnection), +DirectoryEntry::DirectoryEntry( + const std::wstring &name, DirectoryEntry *parent, int originID) : + m_OriginConnection(new OriginConnection), m_Name(name), m_Parent(parent), m_Populated(false), m_TopLevel(true) { m_FileRegister.reset(new FileRegister(m_OriginConnection)); @@ -458,29 +507,28 @@ DirectoryEntry::DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, LEAK_TRACE; } -DirectoryEntry::DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, int originID, - boost::shared_ptr fileRegister, boost::shared_ptr originConnection) - : m_FileRegister(fileRegister), m_OriginConnection(originConnection), +DirectoryEntry::DirectoryEntry( + const std::wstring &name, DirectoryEntry *parent, int originID, + boost::shared_ptr fileRegister, + boost::shared_ptr originConnection) : + m_FileRegister(fileRegister), m_OriginConnection(originConnection), m_Name(name), m_Parent(parent), m_Populated(false), m_TopLevel(false) { LEAK_TRACE; m_Origins.insert(originID); } - DirectoryEntry::~DirectoryEntry() { LEAK_UNTRACE; clear(); } - const std::wstring &DirectoryEntry::getName() const { return m_Name; } - void DirectoryEntry::clear() { m_Files.clear(); @@ -494,22 +542,24 @@ void DirectoryEntry::clear() m_SubDirectoriesMap.clear(); } - -FilesOrigin &DirectoryEntry::createOrigin(const std::wstring &originName, const std::wstring &directory, int priority) +FilesOrigin &DirectoryEntry::createOrigin( + const std::wstring &originName, const std::wstring &directory, int priority) { if (m_OriginConnection->exists(originName)) { FilesOrigin &origin = m_OriginConnection->getByName(originName); origin.enable(true); return origin; } else { - return m_OriginConnection->createOrigin(originName, directory, priority, m_FileRegister, m_OriginConnection); + return m_OriginConnection->createOrigin( + originName, directory, priority, m_FileRegister, m_OriginConnection); } } - -void DirectoryEntry::addFromOrigin(const std::wstring &originName, const std::wstring &directory, int priority) +void DirectoryEntry::addFromOrigin( + const std::wstring &originName, const std::wstring &directory, int priority) { FilesOrigin &origin = createOrigin(originName, directory, priority); + if (directory.length() != 0) { boost::scoped_array buffer(new wchar_t[MAXPATH_UNICODE + 1]); memset(buffer.get(), L'\0', MAXPATH_UNICODE + 1); @@ -517,11 +567,13 @@ void DirectoryEntry::addFromOrigin(const std::wstring &originName, const std::ws buffer.get()[offset] = L'\0'; addFiles(origin, buffer.get(), offset); } + m_Populated = true; } - -void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &directory, const std::wstring &fileName, int priority, int order) +void DirectoryEntry::addFromBSA( + const std::wstring &originName, std::wstring &directory, + const std::wstring &fileName, int priority, int order) { FilesOrigin &origin = createOrigin(originName, directory, priority); @@ -529,6 +581,7 @@ void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &di if (::GetFileAttributesExW(fileName.c_str(), GetFileExInfoStandard, &fileData) == 0) { throw windows_error(QObject::tr("failed to determine file time").toStdString()); } + FILETIME now; ::GetSystemTimeAsFileTime(&now); @@ -547,9 +600,14 @@ void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &di if (!containsArchive(fileName.substr(namePos)) || ::CompareFileTime(&fileData.ftLastWriteTime, &now) > 0) { BSA::Archive archive; BSA::EErrorCode res = archive.read(ToString(fileName, false).c_str(), false); + if ((res != BSA::ERROR_NONE) && (res != BSA::ERROR_INVALIDHASHES)) { std::ostringstream stream; - stream << QObject::tr("invalid bsa file: ").toStdString() << ToString(fileName, false) << " errorcode " << res << " - " << ::GetLastError(); + + stream + << QObject::tr("invalid bsa file: ").toStdString() + << ToString(fileName, false) + << " errorcode " << res << " - " << ::GetLastError(); throw std::runtime_error(stream.str()); } @@ -561,29 +619,13 @@ void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &di void DirectoryEntry::propagateOrigin(int origin) { m_Origins.insert(origin); + if (m_Parent != nullptr) { m_Parent->propagateOrigin(origin); } } -static bool SupportOptimizedFind() -{ - // large fetch and basic info for FindFirstFileEx is supported on win server 2008 r2, win 7 and newer - - OSVERSIONINFOEX versionInfo; - versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - versionInfo.dwMajorVersion = 6; - versionInfo.dwMinorVersion = 1; - ULONGLONG mask = ::VerSetConditionMask( - ::VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), - VER_MINORVERSION, VER_GREATER_EQUAL); - - bool res = ::VerifyVersionInfo(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, mask) == TRUE; - return res; -} - - static bool DirCompareByName(const DirectoryEntry *lhs, const DirectoryEntry *rhs) { return _wcsicmp(lhs->getName().c_str(), rhs->getName().c_str()) < 0; @@ -599,14 +641,17 @@ void DirectoryEntry::addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOf HANDLE searchHandle = nullptr; if (SupportOptimizedFind()) { - searchHandle = ::FindFirstFileExW(buffer, FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, - FIND_FIRST_EX_LARGE_FETCH); + searchHandle = ::FindFirstFileExW( + buffer, FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, + FIND_FIRST_EX_LARGE_FETCH); } else { - searchHandle = ::FindFirstFileExW(buffer, FindExInfoStandard, &findData, FindExSearchNameMatch, nullptr, 0); + searchHandle = ::FindFirstFileExW( + buffer, FindExInfoStandard, &findData, FindExSearchNameMatch, nullptr, 0); } if (searchHandle != INVALID_HANDLE_VALUE) { BOOL result = true; + while (result) { if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if ((wcscmp(findData.cFileName, L".") != 0) && @@ -618,15 +663,18 @@ void DirectoryEntry::addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOf } else { insert(findData.cFileName, origin, findData.ftLastWriteTime, L"", -1); } + result = ::FindNextFileW(searchHandle, &findData); } } + std::sort(m_SubDirectories.begin(), m_SubDirectories.end(), &DirCompareByName); ::FindClose(searchHandle); } - -void DirectoryEntry::addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime, const std::wstring &archiveName, int order) +void DirectoryEntry::addFiles( + FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime, + const std::wstring &archiveName, int order) { // add files for (unsigned int fileIdx = 0; fileIdx < archiveFolder->getNumFiles(); ++fileIdx) { @@ -643,21 +691,22 @@ void DirectoryEntry::addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolde } } - bool DirectoryEntry::removeFile(const std::wstring &filePath, int *origin) { size_t pos = filePath.find_first_of(L"\\/"); + if (pos == std::string::npos) { return this->remove(filePath, origin); + } + + std::wstring dirName = filePath.substr(0, pos); + std::wstring rest = filePath.substr(pos + 1); + DirectoryEntry *entry = getSubDirectoryRecursive(dirName, false); + + if (entry != nullptr) { + return entry->removeFile(rest, origin); } else { - std::wstring dirName = filePath.substr(0, pos); - std::wstring rest = filePath.substr(pos + 1); - DirectoryEntry *entry = getSubDirectoryRecursive(dirName, false); - if (entry != nullptr) { - return entry->removeFile(rest, origin); - } else { - return false; - } + return false; } } @@ -681,9 +730,11 @@ void DirectoryEntry::removeDirRecursive() void DirectoryEntry::removeDir(const std::wstring &path) { size_t pos = path.find_first_of(L"\\/"); + if (pos == std::string::npos) { for (auto iter = m_SubDirectories.begin(); iter != m_SubDirectories.end(); ++iter) { DirectoryEntry *entry = *iter; + if (CaseInsensitiveEqual(entry->getName(), path)) { entry->removeDirRecursive(); @@ -709,6 +760,7 @@ void DirectoryEntry::removeDir(const std::wstring &path) std::wstring dirName = path.substr(0, pos); std::wstring rest = path.substr(pos + 1); DirectoryEntry *entry = getSubDirectoryRecursive(dirName, false); + if (entry != nullptr) { entry->removeDir(rest); } @@ -770,9 +822,11 @@ bool DirectoryEntry::hasContentsFromOrigin(int originID) const return m_Origins.find(originID) != m_Origins.end(); } -void DirectoryEntry::insertFile(const std::wstring &filePath, FilesOrigin &origin, FILETIME fileTime) +void DirectoryEntry::insertFile( + const std::wstring &filePath, FilesOrigin &origin, FILETIME fileTime) { size_t pos = filePath.find_first_of(L"\\/"); + if (pos == std::string::npos) { this->insert(filePath, origin, fileTime, std::wstring(), -1); } else { @@ -851,14 +905,18 @@ bool DirectoryEntry::containsArchive(std::wstring archiveName) { for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) { FileEntry::Ptr entry = m_FileRegister->getFile(iter->second); - if (entry->isFromArchive(archiveName)) return true; + if (entry->isFromArchive(archiveName)) { + return true; + } } + return false; } int DirectoryEntry::anyOrigin() const { bool ignore; + for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) { FileEntry::Ptr entry = m_FileRegister->getFile(iter->second); if ((entry.get() != nullptr) && !entry->isFromArchive()) { @@ -874,53 +932,36 @@ int DirectoryEntry::anyOrigin() const return res; } } + return *(m_Origins.begin()); } - bool DirectoryEntry::originExists(const std::wstring &name) const { return m_OriginConnection->exists(name); } - FilesOrigin &DirectoryEntry::getOriginByID(int ID) const { return m_OriginConnection->getByID(ID); } - FilesOrigin &DirectoryEntry::getOriginByName(const std::wstring &name) const { return m_OriginConnection->getByName(name); } -/* -int DirectoryEntry::getOrigin(const std::wstring &path, bool &archive) -{ - const DirectoryEntry *directory = nullptr; - const FileEntry::Ptr file = searchFile(path, &directory); - if (file.get() != nullptr) { - return file->getOrigin(archive); - } else { - if (directory != nullptr) { - return directory->anyOrigin(); - } else { - return -1; - } - } -}*/ - std::vector DirectoryEntry::getFiles() const { std::vector result; + for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) { result.push_back(m_FileRegister->getFile(iter->second)); } + return result; } - const FileEntry::Ptr DirectoryEntry::searchFile(const std::wstring &path, const DirectoryEntry **directory) const { if (directory != nullptr) { @@ -932,14 +973,16 @@ const FileEntry::Ptr DirectoryEntry::searchFile(const std::wstring &path, const if (directory != nullptr) { *directory = this; } + return FileEntry::Ptr(); } - size_t len = path.find_first_of(L"\\/"); + const size_t len = path.find_first_of(L"\\/"); if (len == std::string::npos) { // no more path components auto iter = m_Files.find(ToLowerCopy(path)); + if (iter != m_Files.end()) { return m_FileRegister->getFile(iter->second); } else if (directory != nullptr) { @@ -949,21 +992,23 @@ const FileEntry::Ptr DirectoryEntry::searchFile(const std::wstring &path, const } } } else { - // file is in in a subdirectory, recurse into the matching subdirectory + // file is in a subdirectory, recurse into the matching subdirectory std::wstring pathComponent = path.substr(0, len); DirectoryEntry *temp = findSubDirectory(pathComponent); + if (temp != nullptr) { if (len >= path.size()) { log::error(QObject::tr("unexpected end of path").toStdString()); return FileEntry::Ptr(); } + return temp->searchFile(path.substr(len + 1), directory); } } + return FileEntry::Ptr(); } - DirectoryEntry *DirectoryEntry::findSubDirectory( const std::wstring &name, bool alreadyLowerCase) const { @@ -982,13 +1027,11 @@ DirectoryEntry *DirectoryEntry::findSubDirectory( return itor->second; } - DirectoryEntry *DirectoryEntry::findSubDirectoryRecursive(const std::wstring &path) { return getSubDirectoryRecursive(path, false, -1); } - const FileEntry::Ptr DirectoryEntry::findFile( const std::wstring &name, bool alreadyLowerCase) const { @@ -1023,13 +1066,15 @@ bool DirectoryEntry::hasFile(const std::wstring& name) const return m_Files.contains(ToLowerCopy(name)); } -DirectoryEntry *DirectoryEntry::getSubDirectory(const std::wstring &name, bool create, int originID) +DirectoryEntry *DirectoryEntry::getSubDirectory( + const std::wstring &name, bool create, int originID) { for (DirectoryEntry *entry : m_SubDirectories) { if (CaseInsensitiveEqual(entry->getName(), name)) { return entry; } } + if (create) { auto* entry = new DirectoryEntry( name, this, originID, m_FileRegister, m_OriginConnection); @@ -1043,19 +1088,21 @@ DirectoryEntry *DirectoryEntry::getSubDirectory(const std::wstring &name, bool c } } - -DirectoryEntry *DirectoryEntry::getSubDirectoryRecursive(const std::wstring &path, bool create, int originID) +DirectoryEntry *DirectoryEntry::getSubDirectoryRecursive( + const std::wstring &path, bool create, int originID) { if (path.length() == 0) { // path ended with a backslash? return this; } - size_t pos = path.find_first_of(L"\\/"); + const size_t pos = path.find_first_of(L"\\/"); + if (pos == std::wstring::npos) { return getSubDirectory(path, create); } else { DirectoryEntry *nextChild = getSubDirectory(path.substr(0, pos), create, originID); + if (nextChild == nullptr) { return nullptr; } else { @@ -1065,7 +1112,6 @@ DirectoryEntry *DirectoryEntry::getSubDirectoryRecursive(const std::wstring &pat } - FileRegister::FileRegister(boost::shared_ptr originConnection) : m_OriginConnection(originConnection) { @@ -1078,7 +1124,6 @@ FileRegister::~FileRegister() m_Files.clear(); } - FileEntry::Index FileRegister::generateIndex() { static std::atomic sIndex(0); @@ -1087,20 +1132,21 @@ FileEntry::Index FileRegister::generateIndex() bool FileRegister::indexValid(FileEntry::Index index) const { - return m_Files.find(index) != m_Files.end(); + return (m_Files.find(index) != m_Files.end()); } FileEntry::Ptr FileRegister::createFile(const std::wstring &name, DirectoryEntry *parent) { FileEntry::Index index = generateIndex(); m_Files[index] = FileEntry::Ptr(new FileEntry(index, name, parent)); + return m_Files[index]; } - FileEntry::Ptr FileRegister::getFile(FileEntry::Index index) const { auto iter = m_Files.find(index); + if (iter != m_Files.end()) { return iter->second; } else { @@ -1111,10 +1157,12 @@ FileEntry::Ptr FileRegister::getFile(FileEntry::Index index) const void FileRegister::unregisterFile(FileEntry::Ptr file) { bool ignore; + // unregister from origin int originID = file->getOrigin(ignore); m_OriginConnection->getByID(originID).removeFile(file->getIndex()); - const std::vector>> &alternatives = file->getAlternatives(); + const auto& alternatives = file->getAlternatives(); + for (auto iter = alternatives.begin(); iter != alternatives.end(); ++iter) { m_OriginConnection->getByID(iter->first).removeFile(file->getIndex()); } @@ -1125,10 +1173,10 @@ void FileRegister::unregisterFile(FileEntry::Ptr file) } } - bool FileRegister::removeFile(FileEntry::Index index) { auto iter = m_Files.find(index); + if (iter != m_Files.end()) { unregisterFile(iter->second); m_Files.erase(index); @@ -1142,6 +1190,7 @@ bool FileRegister::removeFile(FileEntry::Index index) void FileRegister::removeOrigin(FileEntry::Index index, int originID) { auto iter = m_Files.find(index); + if (iter != m_Files.end()) { if (iter->second->removeOrigin(originID)) { unregisterFile(iter->second); @@ -1152,11 +1201,14 @@ void FileRegister::removeOrigin(FileEntry::Index index, int originID) } } -void FileRegister::removeOriginMulti(std::set indices, int originID, time_t notAfter) +void FileRegister::removeOriginMulti( + std::set indices, int originID, time_t notAfter) { std::vector removedFiles; - for (auto iter = indices.begin(); iter != indices.end();) { + + for (auto iter = indices.begin(); iter != indices.end(); ) { auto pos = m_Files.find(*iter); + if (pos != m_Files.end() && (pos->second->lastAccessed() < notAfter) && pos->second->removeOrigin(originID)) { @@ -1168,20 +1220,27 @@ void FileRegister::removeOriginMulti(std::set indices, int ori } } - // optimization: this is only called when disabling an origin and in this case we don't have - // to remove the file from the origin + // optimization: this is only called when disabling an origin and in this case + // we don't have to remove the file from the origin + + // need to remove files from their parent directories. multiple ways to go + // about this: + // a) for each file, search its parents file-list (preferably by name) and + // remove what is found + // b) gather the parent directories, go through the file list for each once + // and remove all files that have been removed + // + // the latter should be faster when there are many files in few directories. + // since this is called only when disabling an origin that is probably + // frequently the case - // need to remove files from their parent directories. multiple ways to go about this: - // a) for each file, search its parents file-list (preferably by name) and remove what is found - // b) gather the parent directories, go through the file list for each once and remove all files that have been removed - // the latter should be faster when there are many files in few directories. since this is called - // only when disabling an origin that is probably frequently the case std::set parents; for (const FileEntry::Ptr &file : removedFiles) { if (file->getParent() != nullptr) { parents.insert(file->getParent()); } } + for (DirectoryEntry *parent : parents) { parent->removeFiles(indices); } -- cgit v1.3.1