diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-12-19 23:30:00 -0500 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2020-02-04 03:33:19 -0500 |
| commit | 1c07f8ddda94254ab4f0e985ffb3e5fdea2da921 (patch) | |
| tree | 2418d3d0b0470f87aca28c5b05d23c9b1fea5c74 | |
| parent | 6da813a6330b576bcf565ff397ee6eaae1aaaac4 (diff) | |
refactoring: whitespace, newlines, auto, removed commented out code
| -rw-r--r-- | src/shared/directoryentry.cpp | 489 |
1 files changed, 274 insertions, 215 deletions
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 <http://www.gnu.org/licenses/>. #include <atomic>
#include <QObject>
+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> fileRegister, boost::shared_ptr<OriginConnection> originConnection) {
+ FilesOrigin& createOrigin(
+ const std::wstring &originName, const std::wstring &directory, int priority,
+ boost::shared_ptr<FileRegister> fileRegister,
+ boost::shared_ptr<OriginConnection> 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<std::wstring, int>::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<Index, FilesOrigin> m_Origins;
std::map<std::wstring, Index> m_OriginsNameMap;
std::map<int, Index> m_OriginsPriorityMap;
-};
-
-
-//
-// FilesOrigin
-//
-
-
-void FilesOrigin::enable(bool enabled, time_t notAfter)
-{
- if (!enabled) {
- std::set<FileEntry::Index> 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<MOShared::FileRegister> fileRegister, boost::shared_ptr<MOShared::OriginConnection> 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<MOShared::FileRegister> fileRegister,
+ boost::shared_ptr<MOShared::OriginConnection> 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<FileEntry::Ptr> FilesOrigin::getFiles() const
{
std::vector<FileEntry::Ptr> 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<FileEntry::Index> 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<std::wstring, int>(archive, order);
}
+ 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 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<int, std::pair<std::wstring, int>> &i) -> bool { return i.first == m_Origin; }) == m_Alternatives.end()) {
- m_Alternatives.push_back(std::pair<int, std::pair<std::wstring, int>>(m_Origin, m_Archive));
+ if (itor == m_Alternatives.end()) {
+ m_Alternatives.push_back({m_Origin, m_Archive});
}
+
m_Origin = origin;
m_FileTime = fileTime;
m_Archive = std::pair<std::wstring, int>(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<std::pair<int, std::pair<std::wstring, int>>>::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<int, std::pair<std::wstring, int>>(origin, std::pair<std::wstring, int>(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<int, std::pair<std::wstring, int>>(origin, std::pair<std::wstring, int>(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<std::pair<int, std::pair<std::wstring, int>>>::iterator currentIter = m_Alternatives.begin();
- for (std::vector<std::pair<int, std::pair<std::wstring, int>>>::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<std::wstring, int>(L"bsa?", -1);
- //} else {
- //m_Archive = std::pair<std::wstring, int>(L"", -1);
- //}
-
- //::CloseHandle(file);
-
} else {
m_Origin = -1;
m_Archive = std::pair<std::wstring, int>(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<int, std::pair<std::wstring, int>>(m_Origin, m_Archive));
- std::sort(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair<int, std::pair<std::wstring, int>> &LHS, const std::pair<int, std::pair<std::wstring, int>> &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> fileRegister, boost::shared_ptr<OriginConnection> originConnection)
- : m_FileRegister(fileRegister), m_OriginConnection(originConnection),
+DirectoryEntry::DirectoryEntry(
+ const std::wstring &name, DirectoryEntry *parent, int originID,
+ boost::shared_ptr<FileRegister> fileRegister,
+ boost::shared_ptr<OriginConnection> 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<wchar_t> 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<FileEntry::Ptr> DirectoryEntry::getFiles() const
{
std::vector<FileEntry::Ptr> 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> originConnection)
: m_OriginConnection(originConnection)
{
@@ -1078,7 +1124,6 @@ FileRegister::~FileRegister() m_Files.clear();
}
-
FileEntry::Index FileRegister::generateIndex()
{
static std::atomic<FileEntry::Index> 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<std::pair<int, std::pair<std::wstring, int>>> &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<FileEntry::Index> indices, int originID, time_t notAfter)
+void FileRegister::removeOriginMulti(
+ std::set<FileEntry::Index> indices, int originID, time_t notAfter)
{
std::vector<FileEntry::Ptr> 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<FileEntry::Index> 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<DirectoryEntry*> parents;
for (const FileEntry::Ptr &file : removedFiles) {
if (file->getParent() != nullptr) {
parents.insert(file->getParent());
}
}
+
for (DirectoryEntry *parent : parents) {
parent->removeFiles(indices);
}
|
