diff options
| author | Brian Munro <brian.alexander.munro@gmail.com> | 2018-02-22 18:02:02 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-02-22 18:02:02 +0200 |
| commit | 28714f0eb800f2170acbf29dddce1582d20d6b8b (patch) | |
| tree | 0684c123db375336e0e03f0240155a12e744db16 /src/shared | |
| parent | 0bcd752b2758bdb072b498ccc90905276be065e9 (diff) | |
| parent | 5e5c9c07291f6b09623d31c92b1fb61c4ede576e (diff) | |
Merge pull request #236 from SuperSandro2000/new_vfs_library
Update reame.md
Diffstat (limited to 'src/shared')
| -rw-r--r-- | src/shared/appconfig.cpp | 4 | ||||
| -rw-r--r-- | src/shared/appconfig.h | 4 | ||||
| -rw-r--r-- | src/shared/directoryentry.cpp | 1312 | ||||
| -rw-r--r-- | src/shared/directoryentry.h | 385 | ||||
| -rw-r--r-- | src/shared/error_report.cpp | 98 | ||||
| -rw-r--r-- | src/shared/leaktrace.cpp | 70 | ||||
| -rw-r--r-- | src/shared/leaktrace.h | 7 | ||||
| -rw-r--r-- | src/shared/stackdata.cpp | 213 | ||||
| -rw-r--r-- | src/shared/stackdata.h | 43 | ||||
| -rw-r--r-- | src/shared/util.cpp | 205 | ||||
| -rw-r--r-- | src/shared/util.h | 23 | ||||
| -rw-r--r-- | src/shared/windows_error.cpp | 35 | ||||
| -rw-r--r-- | src/shared/windows_error.h | 14 |
13 files changed, 1095 insertions, 1318 deletions
diff --git a/src/shared/appconfig.cpp b/src/shared/appconfig.cpp index 49edcbcc..ebb72aba 100644 --- a/src/shared/appconfig.cpp +++ b/src/shared/appconfig.cpp @@ -22,12 +22,12 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. namespace AppConfig {
#define PARWSTRING wstring
-#define APPPARAM(partype, parid, value) partype parid () { return value; }
+#define APPPARAM(partype, parid, value) \
+ partype parid() { return value; }
#include "appconfig.inc"
namespace MOShared {
#undef PARWSTRING
#undef APPPARAM
-
}
} // namespace MOShared
diff --git a/src/shared/appconfig.h b/src/shared/appconfig.h index b32043e5..b2dda14a 100644 --- a/src/shared/appconfig.h +++ b/src/shared/appconfig.h @@ -24,15 +24,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. namespace AppConfig {
-
#define PARWSTRING wstring
-#define APPPARAM(partype, parid, value) partype parid ();
+#define APPPARAM(partype, parid, value) partype parid();
#include "appconfig.inc"
namespace MOShared {
#undef PARWSTRING
#undef APPPARAM
-
}
} // namespace MOShared
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp index cebf270e..2e25a1a3 100644 --- a/src/shared/directoryentry.cpp +++ b/src/shared/directoryentry.cpp @@ -18,20 +18,19 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. */
#include "directoryentry.h"
-#include "windows_error.h"
-#include "leaktrace.h"
#include "error_report.h"
-#include <bsatk.h>
+#include "leaktrace.h"
+#include "windows_error.h"
#include <boost/bind.hpp>
#include <boost/scoped_array.hpp>
+#include <bsatk.h>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
-#include <sstream>
-#include <ctime>
#include <algorithm>
-#include <map>
#include <atomic>
-
+#include <ctime>
+#include <map>
+#include <sstream>
namespace MOShared {
@@ -40,671 +39,576 @@ static const int MAXPATH_UNICODE = 32767; class OriginConnection {
public:
-
- typedef int Index;
- static const int INVALID_INDEX = INT_MIN;
+ typedef int Index;
+ static const int INVALID_INDEX = INT_MIN;
public:
+ OriginConnection() : m_NextID(0) { LEAK_TRACE; }
- OriginConnection()
- : m_NextID(0)
- {
- LEAK_TRACE;
- }
-
- ~OriginConnection()
- {
- LEAK_UNTRACE;
- }
+ ~OriginConnection() { LEAK_UNTRACE; }
- 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];
- }
+ 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) {
- return m_OriginsNameMap.find(name) != m_OriginsNameMap.end();
- }
+ bool exists(const std::wstring& name) { return m_OriginsNameMap.find(name) != m_OriginsNameMap.end(); }
- FilesOrigin &getByID(Index ID) {
- return m_Origins[ID];
- }
+ FilesOrigin& getByID(Index ID) { return m_Origins[ID]; }
- 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 {
- std::ostringstream stream;
- stream << "invalid origin name: " << ToString(name, false);
- throw std::runtime_error(stream.str());
+ 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 {
+ std::ostringstream stream;
+ stream << "invalid origin name: " << ToString(name, false);
+ throw std::runtime_error(stream.str());
+ }
}
- }
- 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);
- m_OriginsPriorityMap[newPriority] = idx;
+ 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);
+ m_OriginsPriorityMap[newPriority] = idx;
+ }
}
- }
- 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);
- m_OriginsNameMap[newName] = idx;
- } else {
- log("failed to change name lookup from %ls to %ls", oldName.c_str(), newName.c_str());
+ 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);
+ m_OriginsNameMap[newName] = idx;
+ } else {
+ log("failed to change name lookup from %ls to %ls", oldName.c_str(), newName.c_str());
+ }
}
- }
private:
-
- Index createID() {
- return m_NextID++;
- }
+ Index createID() { return m_NextID++; }
private:
+ Index m_NextID;
- Index m_NextID;
-
- std::map<Index, FilesOrigin> m_Origins;
- std::map<std::wstring, Index> m_OriginsNameMap;
- std::map<int, Index> m_OriginsPriorityMap;
-
+ 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);
- }
+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;
}
-
-
-static std::wstring tail(const std::wstring &source, const size_t count)
-{
- if (count >= source.length()) {
- return source;
- }
-
- return source.substr(source.length() - count);
+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;
+ }
-FilesOrigin::FilesOrigin()
- : m_ID(0), m_Disabled(false), m_Name(), m_Path(), m_Priority(0)
-{
- LEAK_TRACE;
-}
-
-FilesOrigin::FilesOrigin(const FilesOrigin &reference)
- : m_ID(reference.m_ID)
- , m_Disabled(reference.m_Disabled)
- , m_Name(reference.m_Name)
- , m_Path(reference.m_Path)
- , m_Priority(reference.m_Priority)
- , m_FileRegister(reference.m_FileRegister)
- , m_OriginConnection(reference.m_OriginConnection)
-{
- LEAK_TRACE;
+ return source.substr(source.length() - count);
}
+FilesOrigin::FilesOrigin() : m_ID(0), m_Disabled(false), m_Name(), m_Path(), m_Priority(0) { LEAK_TRACE; }
-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;
+FilesOrigin::FilesOrigin(const FilesOrigin& reference)
+ : m_ID(reference.m_ID), m_Disabled(reference.m_Disabled), m_Name(reference.m_Name), m_Path(reference.m_Path),
+ m_Priority(reference.m_Priority), m_FileRegister(reference.m_FileRegister),
+ m_OriginConnection(reference.m_OriginConnection) {
+ LEAK_TRACE;
}
-FilesOrigin::~FilesOrigin()
-{
- LEAK_UNTRACE;
+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;
}
+FilesOrigin::~FilesOrigin() { LEAK_UNTRACE; }
-void FilesOrigin::setPriority(int priority)
-{
- m_OriginConnection.lock()->changePriorityLookup(m_Priority, priority);
+void FilesOrigin::setPriority(int priority) {
+ m_OriginConnection.lock()->changePriorityLookup(m_Priority, priority);
- m_Priority = 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;
+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))
- result.push_back(p);
+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))
+ result.push_back(p);
- return result;
+ return result;
}
-
//
// FileEntry
//
-void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring &archive)
-{
- m_LastAccessed = time(nullptr);
- if (m_Parent != nullptr) {
- m_Parent->propagateOrigin(origin);
- }
- if (m_Origin == -1) {
- m_Origin = origin;
- m_FileTime = fileTime;
- m_Archive = archive;
- } else if ((m_Parent != nullptr)
- && (m_Parent->getOriginByID(origin).getPriority() > m_Parent->getOriginByID(m_Origin).getPriority())
- && (archive.size() == 0 || m_Archive.size() > 0 )) {
- if (std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair<int, std::wstring> &i) -> bool { return i.first == m_Origin; }) == m_Alternatives.end()) {
- m_Alternatives.push_back(std::pair<int, std::wstring>(m_Origin, m_Archive));
- }
- m_Origin = origin;
- m_FileTime = fileTime;
- m_Archive = archive;
- } else {
- bool found = false;
- if (m_Origin == origin) {
- // already an origin
- return;
- }
- for (std::vector<std::pair<int, std::wstring>>::iterator 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::wstring>(origin, archive));
- found = true;
- break;
- }
+void FileEntry::addOrigin(int origin, FILETIME fileTime, const std::wstring& archive) {
+ m_LastAccessed = time(nullptr);
+ if (m_Parent != nullptr) {
+ m_Parent->propagateOrigin(origin);
}
- if (!found) {
- m_Alternatives.push_back(std::pair<int, std::wstring>(origin, archive));
+ if (m_Origin == -1) {
+ m_Origin = origin;
+ m_FileTime = fileTime;
+ m_Archive = archive;
+ } else if ((m_Parent != nullptr) &&
+ (m_Parent->getOriginByID(origin).getPriority() > m_Parent->getOriginByID(m_Origin).getPriority()) &&
+ (archive.size() == 0 || m_Archive.size() > 0)) {
+ if (std::find_if(m_Alternatives.begin(), m_Alternatives.end(),
+ [&](const std::pair<int, std::wstring>& i) -> bool { return i.first == m_Origin; }) ==
+ m_Alternatives.end()) {
+ m_Alternatives.push_back(std::pair<int, std::wstring>(m_Origin, m_Archive));
+ }
+ m_Origin = origin;
+ m_FileTime = fileTime;
+ m_Archive = archive;
+ } else {
+ bool found = false;
+ if (m_Origin == origin) {
+ // already an origin
+ return;
+ }
+ for (std::vector<std::pair<int, std::wstring>>::iterator 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::wstring>(origin, archive));
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ m_Alternatives.push_back(std::pair<int, std::wstring>(origin, archive));
+ }
}
- }
}
-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::wstring>>::iterator currentIter = m_Alternatives.begin();
- for (std::vector<std::pair<int, std::wstring>>::iterator iter = m_Alternatives.begin(); iter != m_Alternatives.end(); ++iter) {
- if ((m_Parent->getOriginByID(iter->first).getPriority() > m_Parent->getOriginByID(currentIter->first).getPriority()) &&
- (iter->first != origin)) {
- currentIter = iter;
- }
- }
- int currentID = currentIter->first;
- m_Alternatives.erase(currentIter);
+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::wstring>>::iterator currentIter = m_Alternatives.begin();
+ for (std::vector<std::pair<int, std::wstring>>::iterator iter = m_Alternatives.begin();
+ iter != m_Alternatives.end(); ++iter) {
+ if ((m_Parent->getOriginByID(iter->first).getPriority() >
+ m_Parent->getOriginByID(currentIter->first).getPriority()) &&
+ (iter->first != origin)) {
+ currentIter = iter;
+ }
+ }
+ int currentID = currentIter->first;
+ m_Alternatives.erase(currentIter);
- m_Origin = currentID;
+ 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 = L"bsa?";
- } else {
- m_Archive = L"";
- }
+ // 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 = L"bsa?";
+ } else {
+ m_Archive = L"";
+ }
- ::CloseHandle(file);
+ ::CloseHandle(file);
+ } else {
+ m_Origin = -1;
+ return true;
+ }
} else {
- m_Origin = -1;
- return true;
+ std::vector<std::pair<int, std::wstring>>::iterator newEnd =
+ std::find_if(m_Alternatives.begin(), m_Alternatives.end(),
+ [&](const std::pair<int, std::wstring>& i) -> bool { return i.first == origin; });
+ if (newEnd != m_Alternatives.end())
+ m_Alternatives.erase(newEnd, m_Alternatives.end());
}
- } else {
- std::vector<std::pair<int, std::wstring>>::iterator newEnd = std::find_if(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair<int, std::wstring> &i) -> bool { return i.first == origin; });
- if (newEnd != m_Alternatives.end())
- m_Alternatives.erase(newEnd, m_Alternatives.end());
- }
- return false;
+ return false;
}
-FileEntry::FileEntry()
- : m_Index(UINT_MAX), m_Name(), m_Origin(-1), m_Parent(nullptr), m_LastAccessed(time(nullptr))
-{
- LEAK_TRACE;
+FileEntry::FileEntry() : m_Index(UINT_MAX), m_Name(), m_Origin(-1), m_Parent(nullptr), m_LastAccessed(time(nullptr)) {
+ LEAK_TRACE;
}
-FileEntry::FileEntry(Index index, const std::wstring &name, DirectoryEntry *parent)
- : m_Index(index), m_Name(name), m_Origin(-1), m_Archive(L""), m_Parent(parent), m_LastAccessed(time(nullptr))
-{
- LEAK_TRACE;
+FileEntry::FileEntry(Index index, const std::wstring& name, DirectoryEntry* parent)
+ : m_Index(index), m_Name(name), m_Origin(-1), m_Archive(L""), m_Parent(parent), m_LastAccessed(time(nullptr)) {
+ LEAK_TRACE;
}
-FileEntry::~FileEntry()
-{
- LEAK_UNTRACE;
-}
+FileEntry::~FileEntry() { LEAK_UNTRACE; }
-void FileEntry::sortOrigins()
-{
- m_Alternatives.push_back(std::pair<int, std::wstring>(m_Origin, m_Archive));
- std::sort(m_Alternatives.begin(), m_Alternatives.end(), [&](const std::pair<int, std::wstring> &LHS, const std::pair<int, std::wstring> &RHS) -> bool {
- if ((!LHS.second.size() && !RHS.second.size()) || (LHS.second.size() && RHS.second.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;
+void FileEntry::sortOrigins() {
+ m_Alternatives.push_back(std::pair<int, std::wstring>(m_Origin, m_Archive));
+ std::sort(m_Alternatives.begin(), m_Alternatives.end(),
+ [&](const std::pair<int, std::wstring>& LHS, const std::pair<int, std::wstring>& RHS) -> bool {
+ if ((!LHS.second.size() && !RHS.second.size()) || (LHS.second.size() && RHS.second.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;
- return l < r;
- }
+ return l < r;
+ }
- if (RHS.second.size()) return false;
- return true;
- });
- if (!m_Alternatives.empty()) {
- m_Origin = m_Alternatives.back().first;
- m_Archive = m_Alternatives.back().second;
- m_Alternatives.pop_back();
- }
+ if (RHS.second.size())
+ return false;
+ return true;
+ });
+ if (!m_Alternatives.empty()) {
+ m_Origin = m_Alternatives.back().first;
+ m_Archive = m_Alternatives.back().second;
+ m_Alternatives.pop_back();
+ }
}
-
-bool FileEntry::recurseParents(std::wstring &path, const DirectoryEntry *parent) const
-{
- if (parent == nullptr) {
- return false;
- } else {
- // don't append the topmost parent because it is the virtual data-root
- if (recurseParents(path, parent->getParent())) {
- path.append(L"\\").append(parent->getName());
+bool FileEntry::recurseParents(std::wstring& path, const DirectoryEntry* parent) const {
+ if (parent == nullptr) {
+ return false;
+ } else {
+ // don't append the topmost parent because it is the virtual data-root
+ if (recurseParents(path, parent->getParent())) {
+ path.append(L"\\").append(parent->getName());
+ }
+ return true;
}
- 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
- return result + L"\\" + m_Name;
+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
+ return result + L"\\" + m_Name;
}
-std::wstring FileEntry::getRelativePath() const
-{
- std::wstring result;
- recurseParents(result, m_Parent); // all intermediate directories
- return result + L"\\" + m_Name;
+std::wstring FileEntry::getRelativePath() const {
+ std::wstring result;
+ recurseParents(result, m_Parent); // all intermediate directories
+ return result + L"\\" + m_Name;
}
-
//
// DirectoryEntry
//
-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));
- m_Origins.insert(originID);
- 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),
- m_Name(name), m_Parent(parent), m_Populated(false), m_TopLevel(false)
-{
- LEAK_TRACE;
- m_Origins.insert(originID);
+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));
+ m_Origins.insert(originID);
+ LEAK_TRACE;
}
-
-DirectoryEntry::~DirectoryEntry()
-{
- LEAK_UNTRACE;
- clear();
+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);
}
-
-const std::wstring &DirectoryEntry::getName() const
-{
- return m_Name;
+DirectoryEntry::~DirectoryEntry() {
+ LEAK_UNTRACE;
+ clear();
}
+const std::wstring& DirectoryEntry::getName() const { return m_Name; }
-void DirectoryEntry::clear()
-{
- m_Files.clear();
- for (DirectoryEntry *entry : m_SubDirectories) {
- delete entry;
- }
- m_SubDirectories.clear();
+void DirectoryEntry::clear() {
+ m_Files.clear();
+ for (DirectoryEntry* entry : m_SubDirectories) {
+ delete entry;
+ }
+ m_SubDirectories.clear();
}
-
-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);
- }
+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);
+ }
}
-
-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);
- int offset = _snwprintf(buffer.get(), MAXPATH_UNICODE, L"%ls", directory.c_str());
- buffer.get()[offset] = L'\0';
- addFiles(origin, buffer.get(), offset);
- }
- m_Populated = true;
+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);
+ int offset = _snwprintf(buffer.get(), MAXPATH_UNICODE, L"%ls", directory.c_str());
+ 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) {
+ FilesOrigin& origin = createOrigin(originName, directory, priority);
-void DirectoryEntry::addFromBSA(const std::wstring &originName, std::wstring &directory, const std::wstring &fileName, int priority)
-{
- FilesOrigin &origin = createOrigin(originName, directory, priority);
-
- WIN32_FILE_ATTRIBUTE_DATA fileData;
- if (::GetFileAttributesExW(fileName.c_str(), GetFileExInfoStandard, &fileData) == 0) {
- throw windows_error("failed to determine file time");
- }
+ WIN32_FILE_ATTRIBUTE_DATA fileData;
+ if (::GetFileAttributesExW(fileName.c_str(), GetFileExInfoStandard, &fileData) == 0) {
+ throw windows_error("failed to determine file time");
+ }
- 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 << "invalid bsa file: " << ToString(fileName, false) << " errorcode " << res << " - " << ::GetLastError();
- throw std::runtime_error(stream.str());
- }
- size_t namePos = fileName.find_last_of(L"\\/");
- if (namePos == std::wstring::npos) {
- namePos = 0;
- } else {
- ++namePos;
- }
+ 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 << "invalid bsa file: " << ToString(fileName, false) << " errorcode " << res << " - "
+ << ::GetLastError();
+ throw std::runtime_error(stream.str());
+ }
+ size_t namePos = fileName.find_last_of(L"\\/");
+ if (namePos == std::wstring::npos) {
+ namePos = 0;
+ } else {
+ ++namePos;
+ }
- addFiles(origin, archive.getRoot(), fileData.ftLastWriteTime, fileName.substr(namePos));
- m_Populated = true;
+ addFiles(origin, archive.getRoot(), fileData.ftLastWriteTime, fileName.substr(namePos));
+ m_Populated = true;
}
-void DirectoryEntry::propagateOrigin(int origin)
-{
- m_Origins.insert(origin);
- if (m_Parent != nullptr) {
- m_Parent->propagateOrigin(origin);
- }
+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
-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);
+ 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;
+ 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;
+static bool DirCompareByName(const DirectoryEntry* lhs, const DirectoryEntry* rhs) {
+ return _wcsicmp(lhs->getName().c_str(), rhs->getName().c_str()) < 0;
}
+void DirectoryEntry::addFiles(FilesOrigin& origin, wchar_t* buffer, int bufferOffset) {
+ WIN32_FIND_DATAW findData;
-void DirectoryEntry::addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOffset)
-{
- WIN32_FIND_DATAW findData;
-
- _snwprintf_s(buffer + bufferOffset, MAXPATH_UNICODE - bufferOffset, _TRUNCATE, L"\\*");
+ _snwprintf_s(buffer + bufferOffset, MAXPATH_UNICODE - bufferOffset, _TRUNCATE, L"\\*");
- HANDLE searchHandle = nullptr;
+ HANDLE searchHandle = nullptr;
- if (SupportOptimizedFind()) {
- searchHandle = ::FindFirstFileExW(buffer, FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr,
- FIND_FIRST_EX_LARGE_FETCH);
- } else {
- searchHandle = ::FindFirstFileExW(buffer, FindExInfoStandard, &findData, FindExSearchNameMatch, nullptr, 0);
- }
+ if (SupportOptimizedFind()) {
+ searchHandle = ::FindFirstFileExW(buffer, FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr,
+ FIND_FIRST_EX_LARGE_FETCH);
+ } else {
+ 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) &&
- (wcscmp(findData.cFileName, L"..") != 0)) {
- int offset = _snwprintf(buffer + bufferOffset, MAXPATH_UNICODE, L"\\%ls", findData.cFileName);
- // recurse into subdirectories
- getSubDirectory(findData.cFileName, true, origin.getID())->addFiles(origin, buffer, bufferOffset + offset);
+ if (searchHandle != INVALID_HANDLE_VALUE) {
+ BOOL result = true;
+ while (result) {
+ if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ if ((wcscmp(findData.cFileName, L".") != 0) && (wcscmp(findData.cFileName, L"..") != 0)) {
+ int offset = _snwprintf(buffer + bufferOffset, MAXPATH_UNICODE, L"\\%ls", findData.cFileName);
+ // recurse into subdirectories
+ getSubDirectory(findData.cFileName, true, origin.getID())
+ ->addFiles(origin, buffer, bufferOffset + offset);
+ }
+ } else {
+ insert(findData.cFileName, origin, findData.ftLastWriteTime, L"");
+ }
+ result = ::FindNextFileW(searchHandle, &findData);
}
- } else {
- insert(findData.cFileName, origin, findData.ftLastWriteTime, L"");
- }
- result = ::FindNextFileW(searchHandle, &findData);
}
- }
- std::sort(m_SubDirectories.begin(), m_SubDirectories.end(), &DirCompareByName);
- ::FindClose(searchHandle);
+ 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) {
+ // add files
+ for (unsigned int fileIdx = 0; fileIdx < archiveFolder->getNumFiles(); ++fileIdx) {
+ BSA::File::Ptr file = archiveFolder->getFile(fileIdx);
+ insert(ToWString(file->getName(), true), origin, fileTime, archiveName);
+ }
-void DirectoryEntry::addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime, const std::wstring &archiveName)
-{
- // add files
- for (unsigned int fileIdx = 0; fileIdx < archiveFolder->getNumFiles(); ++fileIdx) {
- BSA::File::Ptr file = archiveFolder->getFile(fileIdx);
- insert(ToWString(file->getName(), true), origin, fileTime, archiveName);
- }
-
- // recurse into subdirectories
- for (unsigned int folderIdx = 0; folderIdx < archiveFolder->getNumSubFolders(); ++folderIdx) {
- BSA::Folder::Ptr folder = archiveFolder->getSubFolder(folderIdx);
- DirectoryEntry *folderEntry = getSubDirectoryRecursive(ToWString(folder->getName(), true), true, origin.getID());
+ // recurse into subdirectories
+ for (unsigned int folderIdx = 0; folderIdx < archiveFolder->getNumSubFolders(); ++folderIdx) {
+ BSA::Folder::Ptr folder = archiveFolder->getSubFolder(folderIdx);
+ DirectoryEntry* folderEntry =
+ getSubDirectoryRecursive(ToWString(folder->getName(), true), true, origin.getID());
- folderEntry->addFiles(origin, folder, fileTime, archiveName);
- }
+ folderEntry->addFiles(origin, folder, fileTime, archiveName);
+ }
}
-
-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);
- } 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);
+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);
} else {
- return false;
+ 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;
+ }
}
- }
}
-void DirectoryEntry::removeDirRecursive()
-{
- while (!m_Files.empty()) {
- m_FileRegister->removeFile(m_Files.begin()->second);
- }
-
- for (DirectoryEntry *entry : m_SubDirectories) {
- entry->removeDirRecursive();
- delete entry;
- }
- m_SubDirectories.clear();
-}
+void DirectoryEntry::removeDirRecursive() {
+ while (!m_Files.empty()) {
+ m_FileRegister->removeFile(m_Files.begin()->second);
+ }
-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)) {
+ for (DirectoryEntry* entry : m_SubDirectories) {
entry->removeDirRecursive();
- m_SubDirectories.erase(iter);
delete entry;
- break;
- }
- }
- } else {
- 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);
}
- }
-}
-
-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)
-{
- size_t pos = filePath.find_first_of(L"\\/");
- if (pos == std::string::npos) {
- this->insert(filePath, origin, fileTime, std::wstring());
- } else {
- std::wstring dirName = filePath.substr(0, pos);
- std::wstring rest = filePath.substr(pos + 1);
- getSubDirectoryRecursive(dirName, true, origin.getID())->insertFile(rest, origin, fileTime);
- }
+ m_SubDirectories.clear();
}
-
-void DirectoryEntry::removeFile(FileEntry::Index index)
-{
- if (!m_Files.empty()) {
- auto iter = std::find_if(m_Files.begin(), m_Files.end(),
- [&index](const std::pair<std::wstring, FileEntry::Index> &iter) -> bool {
- return iter.second == index; } );
- if (iter != m_Files.end()) {
- m_Files.erase(iter);
+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();
+ m_SubDirectories.erase(iter);
+ delete entry;
+ break;
+ }
+ }
} else {
- log("file \"%ls\" not in directory \"%ls\"",
- m_FileRegister->getFile(index)->getName().c_str(),
- this->getName().c_str());
+ 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);
+ }
}
- } else {
- log("file \"%ls\" not in directory \"%ls\", directory empty",
- m_FileRegister->getFile(index)->getName().c_str(),
- this->getName().c_str());
- }
}
+bool DirectoryEntry::hasContentsFromOrigin(int originID) const { return m_Origins.find(originID) != m_Origins.end(); }
-void DirectoryEntry::removeFiles(const std::set<FileEntry::Index> &indices)
-{
- for (auto iter = m_Files.begin(); iter != m_Files.end();) {
- if (indices.find(iter->second) != indices.end()) {
- m_Files.erase(iter++);
+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());
} else {
- ++iter;
+ std::wstring dirName = filePath.substr(0, pos);
+ std::wstring rest = filePath.substr(pos + 1);
+ getSubDirectoryRecursive(dirName, true, origin.getID())->insertFile(rest, origin, fileTime);
}
- }
}
-
-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()) {
- return entry->getOrigin(ignore);
+void DirectoryEntry::removeFile(FileEntry::Index index) {
+ if (!m_Files.empty()) {
+ auto iter = std::find_if(
+ m_Files.begin(), m_Files.end(),
+ [&index](const std::pair<std::wstring, FileEntry::Index>& iter) -> bool { return iter.second == index; });
+ if (iter != m_Files.end()) {
+ m_Files.erase(iter);
+ } else {
+ log("file \"%ls\" not in directory \"%ls\"", m_FileRegister->getFile(index)->getName().c_str(),
+ this->getName().c_str());
+ }
+ } else {
+ log("file \"%ls\" not in directory \"%ls\", directory empty", m_FileRegister->getFile(index)->getName().c_str(),
+ this->getName().c_str());
}
- }
+}
- // if we got here, no file directly within this directory is a valid indicator for a mod, thus
- // we continue looking in subdirectories
- for (DirectoryEntry *entry : m_SubDirectories) {
- int res = entry->anyOrigin();
- if (res != -1){
- return res;
+void DirectoryEntry::removeFiles(const std::set<FileEntry::Index>& indices) {
+ for (auto iter = m_Files.begin(); iter != m_Files.end();) {
+ if (indices.find(iter->second) != indices.end()) {
+ m_Files.erase(iter++);
+ } else {
+ ++iter;
+ }
}
- }
- return *(m_Origins.begin());
}
+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()) {
+ return entry->getOrigin(ignore);
+ }
+ }
-bool DirectoryEntry::originExists(const std::wstring &name) const
-{
- return m_OriginConnection->exists(name);
+ // if we got here, no file directly within this directory is a valid indicator for a mod, thus
+ // we continue looking in subdirectories
+ for (DirectoryEntry* entry : m_SubDirectories) {
+ int res = entry->anyOrigin();
+ if (res != -1) {
+ 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::getOriginByID(int ID) const { return m_OriginConnection->getByID(ID); }
-
-FilesOrigin &DirectoryEntry::getOriginByName(const std::wstring &name) const
-{
- return m_OriginConnection->getByName(name);
+FilesOrigin& DirectoryEntry::getOriginByName(const std::wstring& name) const {
+ return m_OriginConnection->getByName(name);
}
/*
@@ -723,251 +627,219 @@ int DirectoryEntry::getOrigin(const std::wstring &path, bool &archive) }
}*/
-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;
+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) {
- *directory = nullptr;
- }
-
- if ((path.length() == 0) || (path == L"*")) {
- // no file name -> the path ended on a (back-)slash
+const FileEntry::Ptr DirectoryEntry::searchFile(const std::wstring& path, const DirectoryEntry** directory) const {
if (directory != nullptr) {
- *directory = this;
+ *directory = nullptr;
}
- return FileEntry::Ptr();
- }
-
- size_t len = path.find_first_of(L"\\/");
- if (len == std::string::npos) {
- // no more path components
- auto iter = m_Files.find(ToLower(path));
- if (iter != m_Files.end()) {
- return m_FileRegister->getFile(iter->second);
- } else if (directory != nullptr) {
- DirectoryEntry *temp = findSubDirectory(path);
- if (temp != nullptr) {
- *directory = temp;
- }
- }
- } else {
- // file is in 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("unexpected end of path");
+ if ((path.length() == 0) || (path == L"*")) {
+ // no file name -> the path ended on a (back-)slash
+ if (directory != nullptr) {
+ *directory = this;
+ }
return FileEntry::Ptr();
- }
- return temp->searchFile(path.substr(len + 1), directory);
}
- }
- return FileEntry::Ptr();
-}
+ size_t len = path.find_first_of(L"\\/");
-DirectoryEntry *DirectoryEntry::findSubDirectory(const std::wstring &name) const
-{
- for (DirectoryEntry *entry : m_SubDirectories) {
- if (CaseInsensitiveEqual(entry->getName(), name)) {
- return entry;
+ if (len == std::string::npos) {
+ // no more path components
+ auto iter = m_Files.find(ToLower(path));
+ if (iter != m_Files.end()) {
+ return m_FileRegister->getFile(iter->second);
+ } else if (directory != nullptr) {
+ DirectoryEntry* temp = findSubDirectory(path);
+ if (temp != nullptr) {
+ *directory = temp;
+ }
+ }
+ } else {
+ // file is in 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("unexpected end of path");
+ return FileEntry::Ptr();
+ }
+ return temp->searchFile(path.substr(len + 1), directory);
+ }
}
- }
- return nullptr;
-}
-
-
-DirectoryEntry *DirectoryEntry::findSubDirectoryRecursive(const std::wstring &path)
-{
- return getSubDirectoryRecursive(path, false, -1);
-}
-
-
-const FileEntry::Ptr DirectoryEntry::findFile(const std::wstring &name) const
-{
- auto iter = m_Files.find(ToLower(name));
- if (iter != m_Files.end()) {
- return m_FileRegister->getFile(iter->second);
- } else {
return FileEntry::Ptr();
- }
}
-DirectoryEntry *DirectoryEntry::getSubDirectory(const std::wstring &name, bool create, int originID)
-{
- for (DirectoryEntry *entry : m_SubDirectories) {
- if (CaseInsensitiveEqual(entry->getName(), name)) {
- return entry;
+DirectoryEntry* DirectoryEntry::findSubDirectory(const std::wstring& name) const {
+ for (DirectoryEntry* entry : m_SubDirectories) {
+ if (CaseInsensitiveEqual(entry->getName(), name)) {
+ return entry;
+ }
}
- }
- if (create) {
- std::vector<DirectoryEntry*>::iterator iter = m_SubDirectories.insert(m_SubDirectories.end(),
- new DirectoryEntry(name, this, originID, m_FileRegister, m_OriginConnection));
- return *iter;
- } else {
return nullptr;
- }
}
+DirectoryEntry* DirectoryEntry::findSubDirectoryRecursive(const std::wstring& path) {
+ return getSubDirectoryRecursive(path, false, -1);
+}
-DirectoryEntry *DirectoryEntry::getSubDirectoryRecursive(const std::wstring &path, bool create, int originID)
-{
- if (path.length() == 0) {
- // path ended with a backslash?
- return this;
- }
+const FileEntry::Ptr DirectoryEntry::findFile(const std::wstring& name) const {
+ auto iter = m_Files.find(ToLower(name));
+ if (iter != m_Files.end()) {
+ return m_FileRegister->getFile(iter->second);
+ } else {
+ return FileEntry::Ptr();
+ }
+}
- 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;
+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) {
+ std::vector<DirectoryEntry*>::iterator iter = m_SubDirectories.insert(
+ m_SubDirectories.end(), new DirectoryEntry(name, this, originID, m_FileRegister, m_OriginConnection));
+ return *iter;
} else {
- return nextChild->getSubDirectoryRecursive(path.substr(pos + 1), create, originID);
+ return nullptr;
}
- }
}
+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"\\/");
+ 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 {
+ return nextChild->getSubDirectoryRecursive(path.substr(pos + 1), create, originID);
+ }
+ }
+}
FileRegister::FileRegister(boost::shared_ptr<OriginConnection> originConnection)
- : m_OriginConnection(originConnection)
-{
- LEAK_TRACE;
+ : m_OriginConnection(originConnection) {
+ LEAK_TRACE;
}
-FileRegister::~FileRegister()
-{
- LEAK_UNTRACE;
- m_Files.clear();
+FileRegister::~FileRegister() {
+ LEAK_UNTRACE;
+ m_Files.clear();
}
-
-FileEntry::Index FileRegister::generateIndex()
-{
- static std::atomic<FileEntry::Index> sIndex(0);
- return sIndex++;
+FileEntry::Index FileRegister::generateIndex() {
+ static std::atomic<FileEntry::Index> sIndex(0);
+ return sIndex++;
}
-bool FileRegister::indexValid(FileEntry::Index index) const
-{
- return m_Files.find(index) != m_Files.end();
-}
+bool FileRegister::indexValid(FileEntry::Index index) const { 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::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 {
- return FileEntry::Ptr();
- }
+FileEntry::Ptr FileRegister::getFile(FileEntry::Index index) const {
+ auto iter = m_Files.find(index);
+ if (iter != m_Files.end()) {
+ return iter->second;
+ } else {
+ return FileEntry::Ptr();
+ }
}
-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::wstring>> &alternatives = file->getAlternatives();
- for (auto iter = alternatives.begin(); iter != alternatives.end(); ++iter) {
- m_OriginConnection->getByID(iter->first).removeFile(file->getIndex());
- }
+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::wstring>>& alternatives = file->getAlternatives();
+ for (auto iter = alternatives.begin(); iter != alternatives.end(); ++iter) {
+ m_OriginConnection->getByID(iter->first).removeFile(file->getIndex());
+ }
- // unregister from directory
- if (file->getParent() != nullptr) {
- file->getParent()->removeFile(file->getIndex());
- }
+ // unregister from directory
+ if (file->getParent() != nullptr) {
+ file->getParent()->removeFile(file->getIndex());
+ }
}
-
-bool FileRegister::removeFile(FileEntry::Index index)
-{
- auto iter = m_Files.find(index);
- if (iter != m_Files.end()) {
- unregisterFile(iter->second);
- m_Files.erase(index);
- return true;
- } else {
- log("invalid file index for remove: %lu", index);
- return false;
- }
+bool FileRegister::removeFile(FileEntry::Index index) {
+ auto iter = m_Files.find(index);
+ if (iter != m_Files.end()) {
+ unregisterFile(iter->second);
+ m_Files.erase(index);
+ return true;
+ } else {
+ log("invalid file index for remove: %lu", index);
+ return false;
+ }
}
-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);
- m_Files.erase(iter);
+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);
+ m_Files.erase(iter);
+ }
+ } else {
+ log("invalid file index for remove (for origin): %lu", index);
}
- } else {
- log("invalid file index for remove (for origin): %lu", index);
- }
}
-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();) {
- auto pos = m_Files.find(*iter);
- if (pos != m_Files.end()
- && (pos->second->lastAccessed() < notAfter)
- && pos->second->removeOrigin(originID)) {
- removedFiles.push_back(pos->second);
- m_Files.erase(pos);
- ++iter;
- } else {
- indices.erase(iter++);
+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();) {
+ auto pos = m_Files.find(*iter);
+ if (pos != m_Files.end() && (pos->second->lastAccessed() < notAfter) && pos->second->removeOrigin(originID)) {
+ removedFiles.push_back(pos->second);
+ m_Files.erase(pos);
+ ++iter;
+ } else {
+ indices.erase(iter++);
+ }
}
- }
- // 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
- std::set<DirectoryEntry*> parents;
- for (const FileEntry::Ptr &file : removedFiles) {
- if (file->getParent() != nullptr) {
- parents.insert(file->getParent());
+ // 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);
}
- }
- for (DirectoryEntry *parent : parents) {
- parent->removeFiles(indices);
- }
}
-void FileRegister::sortOrigins()
-{
- for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) {
- iter->second->sortOrigins();
- }
+void FileRegister::sortOrigins() {
+ for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) {
+ iter->second->sortOrigins();
+ }
}
} // namespace MOShared
diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h index 8dbedaf4..c26fb433 100644 --- a/src/shared/directoryentry.h +++ b/src/shared/directoryentry.h @@ -20,12 +20,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #ifndef DIRECTORYENTRY_H
#define DIRECTORYENTRY_H
-
-#include <string>
+#include <cassert>
+#include <map>
#include <set>
+#include <string>
#include <vector>
-#include <map>
-#include <cassert>
#define WIN32_MEAN_AND_LEAN
#include <Windows.h>
#include <bsatk.h>
@@ -35,311 +34,291 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #endif
#include "util.h"
-
namespace MOShared {
-
class DirectoryEntry;
class OriginConnection;
class FileRegister;
-
class FileEntry {
public:
+ typedef unsigned int Index;
- typedef unsigned int Index;
-
- typedef boost::shared_ptr<FileEntry> Ptr;
+ typedef boost::shared_ptr<FileEntry> Ptr;
public:
+ FileEntry();
- FileEntry();
-
- FileEntry(Index index, const std::wstring &name, DirectoryEntry *parent);
+ FileEntry(Index index, const std::wstring& name, DirectoryEntry* parent);
- ~FileEntry();
+ ~FileEntry();
- Index getIndex() const { return m_Index; }
+ Index getIndex() const { return m_Index; }
- time_t lastAccessed() const { return m_LastAccessed; }
+ time_t lastAccessed() const { return m_LastAccessed; }
- void addOrigin(int origin, FILETIME fileTime, const std::wstring &archive);
- // remove the specified origin from the list of origins that contain this file. if no origin is left,
- // the file is effectively deleted and true is returned. otherwise, false is returned
- bool removeOrigin(int origin);
- void sortOrigins();
+ void addOrigin(int origin, FILETIME fileTime, const std::wstring& archive);
+ // remove the specified origin from the list of origins that contain this file. if no origin is left,
+ // the file is effectively deleted and true is returned. otherwise, false is returned
+ bool removeOrigin(int origin);
+ void sortOrigins();
- // gets the list of alternative origins (origins with lower priority than the primary one).
- // if sortOrigins has been called, it is sorted by priority (ascending)
- const std::vector<std::pair<int, std::wstring>> &getAlternatives() const { return m_Alternatives; }
+ // gets the list of alternative origins (origins with lower priority than the primary one).
+ // if sortOrigins has been called, it is sorted by priority (ascending)
+ const std::vector<std::pair<int, std::wstring>>& getAlternatives() const { return m_Alternatives; }
- const std::wstring &getName() const { return m_Name; }
- int getOrigin() const { return m_Origin; }
- int getOrigin(bool &archive) const { archive = (m_Archive.length() != 0); return m_Origin; }
- const std::wstring &getArchive() const { return m_Archive; }
- bool isFromArchive() const { return m_Archive.length() != 0; }
- std::wstring getFullPath() const;
- std::wstring getRelativePath() const;
- DirectoryEntry *getParent() { return m_Parent; }
+ const std::wstring& getName() const { return m_Name; }
+ int getOrigin() const { return m_Origin; }
+ int getOrigin(bool& archive) const {
+ archive = (m_Archive.length() != 0);
+ return m_Origin;
+ }
+ const std::wstring& getArchive() const { return m_Archive; }
+ bool isFromArchive() const { return m_Archive.length() != 0; }
+ std::wstring getFullPath() const;
+ std::wstring getRelativePath() const;
+ DirectoryEntry* getParent() { return m_Parent; }
- void setFileTime(FILETIME fileTime) const { m_FileTime = fileTime; }
- FILETIME getFileTime() const { return m_FileTime; }
+ void setFileTime(FILETIME fileTime) const { m_FileTime = fileTime; }
+ FILETIME getFileTime() const { return m_FileTime; }
private:
+ bool recurseParents(std::wstring& path, const DirectoryEntry* parent) const;
- bool recurseParents(std::wstring &path, const DirectoryEntry *parent) const;
-
- void determineTime();
+ void determineTime();
private:
+ Index m_Index;
+ std::wstring m_Name;
+ int m_Origin = -1;
+ std::wstring m_Archive;
+ std::vector<std::pair<int, std::wstring>> m_Alternatives;
+ DirectoryEntry* m_Parent;
+ mutable FILETIME m_FileTime;
- Index m_Index;
- std::wstring m_Name;
- int m_Origin = -1;
- std::wstring m_Archive;
- std::vector<std::pair<int, std::wstring>> m_Alternatives;
- DirectoryEntry *m_Parent;
- mutable FILETIME m_FileTime;
-
- time_t m_LastAccessed;
+ time_t m_LastAccessed;
- friend bool operator<(const FileEntry &lhs, const FileEntry &rhs) {
- return _wcsicmp(lhs.m_Name.c_str(), rhs.m_Name.c_str()) < 0;
- }
- friend bool operator==(const FileEntry &lhs, const FileEntry &rhs) {
- return _wcsicmp(lhs.m_Name.c_str(), rhs.m_Name.c_str()) == 0;
- }
+ friend bool operator<(const FileEntry& lhs, const FileEntry& rhs) {
+ return _wcsicmp(lhs.m_Name.c_str(), rhs.m_Name.c_str()) < 0;
+ }
+ friend bool operator==(const FileEntry& lhs, const FileEntry& rhs) {
+ return _wcsicmp(lhs.m_Name.c_str(), rhs.m_Name.c_str()) == 0;
+ }
};
-
// represents a mod or the data directory, providing files to the tree
class FilesOrigin {
- friend class OriginConnection;
-public:
+ friend class OriginConnection;
- FilesOrigin();
- FilesOrigin(const FilesOrigin &reference);
- ~FilesOrigin();
+public:
+ FilesOrigin();
+ FilesOrigin(const FilesOrigin& reference);
+ ~FilesOrigin();
- // sets priority for this origin, but it will overwrite the exisiting mapping for this priority,
- // the previous origin will no longer be referenced
- void setPriority(int priority);
+ // sets priority for this origin, but it will overwrite the exisiting mapping for this priority,
+ // the previous origin will no longer be referenced
+ void setPriority(int priority);
- int getPriority() const { return m_Priority; }
+ int getPriority() const { return m_Priority; }
- void setName(const std::wstring &name);
- const std::wstring &getName() const { return m_Name; }
+ void setName(const std::wstring& name);
+ const std::wstring& getName() const { return m_Name; }
- int getID() const { return m_ID; }
- const std::wstring &getPath() const { return m_Path; }
+ int getID() const { return m_ID; }
+ const std::wstring& getPath() const { return m_Path; }
- std::vector<FileEntry::Ptr> getFiles() const;
+ std::vector<FileEntry::Ptr> getFiles() const;
- void enable(bool enabled, time_t notAfter = LONG_MAX);
- bool isDisabled() const { return m_Disabled; }
+ void enable(bool enabled, time_t notAfter = LONG_MAX);
+ bool isDisabled() const { return m_Disabled; }
- void addFile(FileEntry::Index index) { m_Files.insert(index); }
- void removeFile(FileEntry::Index index);
+ void addFile(FileEntry::Index index) { m_Files.insert(index); }
+ void removeFile(FileEntry::Index index);
private:
-
- FilesOrigin(int ID, const std::wstring &name, const std::wstring &path, int priority,
- boost::shared_ptr<FileRegister> fileRegister, boost::shared_ptr<OriginConnection> originConnection);
-
+ FilesOrigin(int ID, const std::wstring& name, const std::wstring& path, int priority,
+ boost::shared_ptr<FileRegister> fileRegister, boost::shared_ptr<OriginConnection> originConnection);
private:
+ int m_ID;
- int m_ID;
-
- bool m_Disabled;
-
- std::set<FileEntry::Index> m_Files;
- std::wstring m_Name;
- std::wstring m_Path;
- int m_Priority;
- boost::weak_ptr<FileRegister> m_FileRegister;
- boost::weak_ptr<OriginConnection> m_OriginConnection;
+ bool m_Disabled;
+ std::set<FileEntry::Index> m_Files;
+ std::wstring m_Name;
+ std::wstring m_Path;
+ int m_Priority;
+ boost::weak_ptr<FileRegister> m_FileRegister;
+ boost::weak_ptr<OriginConnection> m_OriginConnection;
};
-
-class FileRegister
-{
+class FileRegister {
public:
+ FileRegister(boost::shared_ptr<OriginConnection> originConnection);
+ ~FileRegister();
- FileRegister(boost::shared_ptr<OriginConnection> originConnection);
- ~FileRegister();
-
- bool indexValid(FileEntry::Index index) const;
+ bool indexValid(FileEntry::Index index) const;
- FileEntry::Ptr createFile(const std::wstring &name, DirectoryEntry *parent);
- FileEntry::Ptr getFile(FileEntry::Index index) const;
+ FileEntry::Ptr createFile(const std::wstring& name, DirectoryEntry* parent);
+ FileEntry::Ptr getFile(FileEntry::Index index) const;
- size_t size() const { return m_Files.size(); }
+ size_t size() const { return m_Files.size(); }
- bool removeFile(FileEntry::Index index);
- void removeOrigin(FileEntry::Index index, int originID);
- void removeOriginMulti(std::set<FileEntry::Index> indices, int originID, time_t notAfter);
+ bool removeFile(FileEntry::Index index);
+ void removeOrigin(FileEntry::Index index, int originID);
+ void removeOriginMulti(std::set<FileEntry::Index> indices, int originID, time_t notAfter);
- void sortOrigins();
+ void sortOrigins();
private:
+ FileEntry::Index generateIndex();
- FileEntry::Index generateIndex();
-
- void unregisterFile(FileEntry::Ptr file);
+ void unregisterFile(FileEntry::Ptr file);
private:
+ std::map<FileEntry::Index, FileEntry::Ptr> m_Files;
- std::map<FileEntry::Index, FileEntry::Ptr> m_Files;
-
- boost::shared_ptr<OriginConnection> m_OriginConnection;
-
+ boost::shared_ptr<OriginConnection> m_OriginConnection;
};
-
-class DirectoryEntry
-{
+class DirectoryEntry {
public:
+ DirectoryEntry(const std::wstring& name, DirectoryEntry* parent, int originID);
- DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, int originID);
-
- DirectoryEntry(const std::wstring &name, DirectoryEntry *parent, int originID,
- boost::shared_ptr<FileRegister> fileRegister,
- boost::shared_ptr<OriginConnection> originConnection);
+ DirectoryEntry(const std::wstring& name, DirectoryEntry* parent, int originID,
+ boost::shared_ptr<FileRegister> fileRegister, boost::shared_ptr<OriginConnection> originConnection);
- ~DirectoryEntry();
+ ~DirectoryEntry();
- void clear();
- bool isPopulated() const { return m_Populated; }
+ void clear();
+ bool isPopulated() const { return m_Populated; }
- bool isEmpty() const { return m_Files.empty() && m_SubDirectories.empty(); }
+ bool isEmpty() const { return m_Files.empty() && m_SubDirectories.empty(); }
- const DirectoryEntry *getParent() const { return m_Parent; }
+ const DirectoryEntry* getParent() const { return m_Parent; }
- // add files to this directory (and subdirectories) from the specified origin. That origin may exist or not
- void addFromOrigin(const std::wstring &originName, const std::wstring &directory, int priority);
- void addFromBSA(const std::wstring &originName, std::wstring &directory, const std::wstring &fileName, int priority);
+ // add files to this directory (and subdirectories) from the specified origin. That origin may exist or not
+ void addFromOrigin(const std::wstring& originName, const std::wstring& directory, int priority);
+ void addFromBSA(const std::wstring& originName, std::wstring& directory, const std::wstring& fileName,
+ int priority);
- void propagateOrigin(int origin);
+ void propagateOrigin(int origin);
- const std::wstring &getName() const;
+ const std::wstring& getName() const;
- boost::shared_ptr<FileRegister> getFileRegister() { return m_FileRegister; }
+ boost::shared_ptr<FileRegister> getFileRegister() { return m_FileRegister; }
- bool originExists(const std::wstring &name) const;
- FilesOrigin &getOriginByID(int ID) const;
- FilesOrigin &getOriginByName(const std::wstring &name) const;
+ bool originExists(const std::wstring& name) const;
+ FilesOrigin& getOriginByID(int ID) const;
+ FilesOrigin& getOriginByName(const std::wstring& name) const;
- int anyOrigin() const;
+ int anyOrigin() const;
- //int getOrigin(const std::wstring &path, bool &archive);
+ // int getOrigin(const std::wstring &path, bool &archive);
- std::vector<FileEntry::Ptr> getFiles() const;
+ std::vector<FileEntry::Ptr> getFiles() const;
- void getSubDirectories(std::vector<DirectoryEntry*>::const_iterator &begin
- , std::vector<DirectoryEntry*>::const_iterator &end) const {
- begin = m_SubDirectories.begin(); end = m_SubDirectories.end();
- }
+ void getSubDirectories(std::vector<DirectoryEntry*>::const_iterator& begin,
+ std::vector<DirectoryEntry*>::const_iterator& end) const {
+ begin = m_SubDirectories.begin();
+ end = m_SubDirectories.end();
+ }
- DirectoryEntry *findSubDirectory(const std::wstring &name) const;
- DirectoryEntry *findSubDirectoryRecursive(const std::wstring &path);
+ DirectoryEntry* findSubDirectory(const std::wstring& name) const;
+ DirectoryEntry* findSubDirectoryRecursive(const std::wstring& path);
- /** retrieve a file in this directory by name.
- * @param name name of the file
- * @return fileentry object for the file or nullptr if no file matches
- */
- const FileEntry::Ptr findFile(const std::wstring &name) const;
+ /** retrieve a file in this directory by name.
+ * @param name name of the file
+ * @return fileentry object for the file or nullptr if no file matches
+ */
+ const FileEntry::Ptr findFile(const std::wstring& name) const;
- /** search through this directory and all subdirectories for a file by the specified name (relative path).
- if directory is not nullptr, the referenced variable will be set to the path containing the file */
- const FileEntry::Ptr searchFile(const std::wstring &path, const DirectoryEntry **directory) const;
+ /** search through this directory and all subdirectories for a file by the specified name (relative path).
+ if directory is not nullptr, the referenced variable will be set to the path containing the file */
+ const FileEntry::Ptr searchFile(const std::wstring& path, const DirectoryEntry** directory) const;
- void insertFile(const std::wstring &filePath, FilesOrigin &origin, FILETIME fileTime);
+ void insertFile(const std::wstring& filePath, FilesOrigin& origin, FILETIME fileTime);
- void removeFile(FileEntry::Index index);
+ void removeFile(FileEntry::Index index);
- // remove the specified file from the tree. This can be a path leading to a file in a subdirectory
- bool removeFile(const std::wstring &filePath, int *origin = nullptr);
+ // remove the specified file from the tree. This can be a path leading to a file in a subdirectory
+ bool removeFile(const std::wstring& filePath, int* origin = nullptr);
- /**
- * @brief remove the specified directory
- * @param path directory to remove
- */
- void removeDir(const std::wstring &path);
+ /**
+ * @brief remove the specified directory
+ * @param path directory to remove
+ */
+ void removeDir(const std::wstring& path);
- bool remove(const std::wstring &fileName, int *origin) {
- auto iter = m_Files.find(ToLower(fileName));
- if (iter != m_Files.end()) {
- if (origin != nullptr) {
- FileEntry::Ptr entry = m_FileRegister->getFile(iter->second);
- if (entry.get() != nullptr) {
- bool ignore;
- *origin = entry->getOrigin(ignore);
+ bool remove(const std::wstring& fileName, int* origin) {
+ auto iter = m_Files.find(ToLower(fileName));
+ if (iter != m_Files.end()) {
+ if (origin != nullptr) {
+ FileEntry::Ptr entry = m_FileRegister->getFile(iter->second);
+ if (entry.get() != nullptr) {
+ bool ignore;
+ *origin = entry->getOrigin(ignore);
+ }
+ }
+ return m_FileRegister->removeFile(iter->second);
+ } else {
+ return false;
}
- }
- return m_FileRegister->removeFile(iter->second);
- } else {
- return false;
}
- }
- bool hasContentsFromOrigin(int originID) const;
+ bool hasContentsFromOrigin(int originID) const;
- FilesOrigin &createOrigin(const std::wstring &originName, const std::wstring &directory, int priority);
+ FilesOrigin& createOrigin(const std::wstring& originName, const std::wstring& directory, int priority);
- void removeFiles(const std::set<FileEntry::Index> &indices);
+ void removeFiles(const std::set<FileEntry::Index>& indices);
private:
+ DirectoryEntry(const DirectoryEntry& reference);
+ DirectoryEntry& operator=(const DirectoryEntry& reference);
- DirectoryEntry(const DirectoryEntry &reference);
- DirectoryEntry &operator=(const DirectoryEntry &reference);
-
- void insert(const std::wstring &fileName, FilesOrigin &origin, FILETIME fileTime, const std::wstring &archive) {
- std::wstring fileNameLower = ToLower(fileName);
- auto iter = m_Files.find(fileNameLower);
- FileEntry::Ptr file;
- if (iter != m_Files.end()) {
- file = m_FileRegister->getFile(iter->second);
- } else {
- file = m_FileRegister->createFile(fileName, this);
- // TODO this has been observed to cause a crash, no clue why
- m_Files[fileNameLower] = file->getIndex();
+ void insert(const std::wstring& fileName, FilesOrigin& origin, FILETIME fileTime, const std::wstring& archive) {
+ std::wstring fileNameLower = ToLower(fileName);
+ auto iter = m_Files.find(fileNameLower);
+ FileEntry::Ptr file;
+ if (iter != m_Files.end()) {
+ file = m_FileRegister->getFile(iter->second);
+ } else {
+ file = m_FileRegister->createFile(fileName, this);
+ // TODO this has been observed to cause a crash, no clue why
+ m_Files[fileNameLower] = file->getIndex();
+ }
+ file->addOrigin(origin.getID(), fileTime, archive);
+ origin.addFile(file->getIndex());
}
- file->addOrigin(origin.getID(), fileTime, archive);
- origin.addFile(file->getIndex());
- }
- void addFiles(FilesOrigin &origin, wchar_t *buffer, int bufferOffset);
- void addFiles(FilesOrigin &origin, BSA::Folder::Ptr archiveFolder, FILETIME &fileTime, const std::wstring &archiveName);
+ void addFiles(FilesOrigin& origin, wchar_t* buffer, int bufferOffset);
+ void addFiles(FilesOrigin& origin, BSA::Folder::Ptr archiveFolder, FILETIME& fileTime,
+ const std::wstring& archiveName);
- DirectoryEntry *getSubDirectory(const std::wstring &name, bool create, int originID = -1);
+ DirectoryEntry* getSubDirectory(const std::wstring& name, bool create, int originID = -1);
- DirectoryEntry *getSubDirectoryRecursive(const std::wstring &path, bool create, int originID = -1);
+ DirectoryEntry* getSubDirectoryRecursive(const std::wstring& path, bool create, int originID = -1);
- void removeDirRecursive();
+ void removeDirRecursive();
private:
+ boost::shared_ptr<FileRegister> m_FileRegister;
+ boost::shared_ptr<OriginConnection> m_OriginConnection;
- boost::shared_ptr<FileRegister> m_FileRegister;
- boost::shared_ptr<OriginConnection> m_OriginConnection;
-
- std::wstring m_Name;
- std::map<std::wstring, FileEntry::Index> m_Files;
- std::vector<DirectoryEntry*> m_SubDirectories;
+ std::wstring m_Name;
+ std::map<std::wstring, FileEntry::Index> m_Files;
+ std::vector<DirectoryEntry*> m_SubDirectories;
- DirectoryEntry *m_Parent;
- std::set<int> m_Origins;
+ DirectoryEntry* m_Parent;
+ std::set<int> m_Origins;
- bool m_Populated;
-
- bool m_TopLevel;
+ bool m_Populated;
+ bool m_TopLevel;
};
-
} // namespace MOShared
#endif // DIRECTORYENTRY_H
diff --git a/src/shared/error_report.cpp b/src/shared/error_report.cpp index 6d091630..fffd77b9 100644 --- a/src/shared/error_report.cpp +++ b/src/shared/error_report.cpp @@ -23,77 +23,71 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. namespace MOShared {
+void reportError(LPCSTR format, ...) {
+ char buffer[1025];
+ memset(buffer, 0, sizeof(char) * 1025);
-void reportError(LPCSTR format, ...)
-{
- char buffer[1025];
- memset(buffer, 0, sizeof(char) * 1025);
+ va_list argList;
+ va_start(argList, format);
- va_list argList;
- va_start(argList, format);
+ vsnprintf(buffer, 1024, format, argList);
+ va_end(argList);
- vsnprintf(buffer, 1024, format, argList);
- va_end(argList);
-
- MessageBoxA(nullptr, buffer, "Error", MB_OK | MB_ICONERROR);
+ MessageBoxA(nullptr, buffer, "Error", MB_OK | MB_ICONERROR);
}
-void reportError(LPCWSTR format, ...)
-{
- WCHAR buffer[1025];
- memset(buffer, 0, sizeof(WCHAR) * 1025);
+void reportError(LPCWSTR format, ...) {
+ WCHAR buffer[1025];
+ memset(buffer, 0, sizeof(WCHAR) * 1025);
- va_list argList;
- va_start(argList, format);
+ va_list argList;
+ va_start(argList, format);
- _vsnwprintf_s(buffer, 1024, format, argList);
- va_end(argList);
+ _vsnwprintf_s(buffer, 1024, format, argList);
+ va_end(argList);
- MessageBoxW(nullptr, buffer, L"Error", MB_OK | MB_ICONERROR);
+ MessageBoxW(nullptr, buffer, L"Error", MB_OK | MB_ICONERROR);
}
+std::string getCurrentErrorStringA() {
+ LPSTR buffer = nullptr;
-std::string getCurrentErrorStringA()
-{
- LPSTR buffer = nullptr;
-
- DWORD errorCode = ::GetLastError();
+ DWORD errorCode = ::GetLastError();
- if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, nullptr) == 0) {
- ::SetLastError(errorCode);
- return std::string();
- } else {
- LPSTR lastChar = buffer + strlen(buffer) - 2;
- *lastChar = '\0';
+ if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, errorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, nullptr) == 0) {
+ ::SetLastError(errorCode);
+ return std::string();
+ } else {
+ LPSTR lastChar = buffer + strlen(buffer) - 2;
+ *lastChar = '\0';
- std::string result(buffer);
+ std::string result(buffer);
- LocalFree(buffer);
- ::SetLastError(errorCode);
- return result;
- }
+ LocalFree(buffer);
+ ::SetLastError(errorCode);
+ return result;
+ }
}
-std::wstring getCurrentErrorStringW()
-{
- LPWSTR buffer = nullptr;
+std::wstring getCurrentErrorStringW() {
+ LPWSTR buffer = nullptr;
- DWORD errorCode = ::GetLastError();
+ DWORD errorCode = ::GetLastError();
- if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&buffer, 0, nullptr) == 0) {
- ::SetLastError(errorCode);
- return std::wstring();
- } else {
- LPWSTR lastChar = buffer + wcslen(buffer) - 2;
- *lastChar = '\0';
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, errorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&buffer, 0, nullptr) == 0) {
+ ::SetLastError(errorCode);
+ return std::wstring();
+ } else {
+ LPWSTR lastChar = buffer + wcslen(buffer) - 2;
+ *lastChar = '\0';
- std::wstring result(buffer);
+ std::wstring result(buffer);
- LocalFree(buffer);
- ::SetLastError(errorCode);
- return result;
- }
+ LocalFree(buffer);
+ ::SetLastError(errorCode);
+ return result;
+ }
}
} // namespace MOShared
diff --git a/src/shared/leaktrace.cpp b/src/shared/leaktrace.cpp index 1ff1fa9d..dd85c4b4 100644 --- a/src/shared/leaktrace.cpp +++ b/src/shared/leaktrace.cpp @@ -1,57 +1,47 @@ #include "leaktrace.h"
#include "stackdata.h"
-#include <Windows.h>
#include <DbgHelp.h>
-#include <set>
+#include <Windows.h>
+#include <algorithm>
#include <map>
-#include <vector>
+#include <set>
#include <sstream>
-#include <algorithm>
-
+#include <vector>
using namespace MOShared;
-
static struct __TraceData {
- void regTrace(void *pointer, const char *functionName, int line) {
- m_Traces[reinterpret_cast<unsigned long>(pointer)] = StackData(functionName, line);
- }
- void deregTrace(void *pointer) {
- auto iter = m_Traces.find(reinterpret_cast<unsigned long>(pointer));
- if (iter != m_Traces.end()) {
- m_Traces.erase(iter);
+ void regTrace(void* pointer, const char* functionName, int line) {
+ m_Traces[reinterpret_cast<unsigned long>(pointer)] = StackData(functionName, line);
}
- }
-
- ~__TraceData() {
- std::map<StackData, std::vector<unsigned long> > result;
- for (auto iter = m_Traces.begin(); iter != m_Traces.end(); ++iter) {
- result[iter->second].push_back(iter->first);
+ void deregTrace(void* pointer) {
+ auto iter = m_Traces.find(reinterpret_cast<unsigned long>(pointer));
+ if (iter != m_Traces.end()) {
+ m_Traces.erase(iter);
+ }
}
- for (auto iter = result.begin(); iter != result.end(); ++iter) {
- printf("-----------------------------------\n"
- "%d objects not freed, allocated at:\n%s",
- iter->second.size(), iter->first.toString().c_str());
- printf("Addresses: ");
- for (int i = 0;
- i < (std::min<int>)(5, static_cast<int>(iter->second.size())); ++i) {
- printf("%p, ", reinterpret_cast<void *>(iter->second[i]));
- }
- printf("\n");
+
+ ~__TraceData() {
+ std::map<StackData, std::vector<unsigned long>> result;
+ for (auto iter = m_Traces.begin(); iter != m_Traces.end(); ++iter) {
+ result[iter->second].push_back(iter->first);
+ }
+ for (auto iter = result.begin(); iter != result.end(); ++iter) {
+ printf("-----------------------------------\n"
+ "%d objects not freed, allocated at:\n%s",
+ iter->second.size(), iter->first.toString().c_str());
+ printf("Addresses: ");
+ for (int i = 0; i < (std::min<int>)(5, static_cast<int>(iter->second.size())); ++i) {
+ printf("%p, ", reinterpret_cast<void*>(iter->second[i]));
+ }
+ printf("\n");
+ }
}
- }
- std::map<unsigned long, StackData> m_Traces;
+ std::map<unsigned long, StackData> m_Traces;
} __trace;
+void LeakTrace::TraceAlloc(void* ptr, const char* functionName, int line) { __trace.regTrace(ptr, functionName, line); }
-void LeakTrace::TraceAlloc(void *ptr, const char *functionName, int line)
-{
- __trace.regTrace(ptr, functionName, line);
-}
-
-void LeakTrace::TraceDealloc(void *ptr)
-{
- __trace.deregTrace(ptr);
-}
+void LeakTrace::TraceDealloc(void* ptr) { __trace.deregTrace(ptr); }
diff --git a/src/shared/leaktrace.h b/src/shared/leaktrace.h index 4985925e..b0d04129 100644 --- a/src/shared/leaktrace.h +++ b/src/shared/leaktrace.h @@ -1,13 +1,12 @@ #ifndef LEAKTRACE_H
#define LEAKTRACE_H
-
namespace LeakTrace {
-void TraceAlloc(void *ptr, const char *functionName, int line);
-void TraceDealloc(void *ptr);
+void TraceAlloc(void* ptr, const char* functionName, int line);
+void TraceDealloc(void* ptr);
-};
+}; // namespace LeakTrace
#ifdef TRACE_LEAKS
diff --git a/src/shared/stackdata.cpp b/src/shared/stackdata.cpp index b336593a..5f77bbfa 100644 --- a/src/shared/stackdata.cpp +++ b/src/shared/stackdata.cpp @@ -1,169 +1,150 @@ #include "stackdata.h"
+#include "error_report.h"
#include "util.h"
#include <DbgHelp.h>
-#include <sstream>
#include <TlHelp32.h>
-#include <set>
-#include "error_report.h"
#include <boost/predef.h>
-
+#include <set>
+#include <sstream>
using namespace MOShared;
#if defined _MSC_VER
-static void initDbgIfNecess()
-{
- HANDLE process = ::GetCurrentProcess();
- static std::set<DWORD> initialized;
- if (initialized.find(::GetCurrentProcessId()) == initialized.end()) {
- static bool firstCall = true;
- if (firstCall) {
- ::SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
- firstCall = false;
+static void initDbgIfNecess() {
+ HANDLE process = ::GetCurrentProcess();
+ static std::set<DWORD> initialized;
+ if (initialized.find(::GetCurrentProcessId()) == initialized.end()) {
+ static bool firstCall = true;
+ if (firstCall) {
+ ::SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
+ firstCall = false;
+ }
+ if (!::SymInitialize(process, NULL, TRUE)) {
+ printf("failed to initialize symbols: %lu", ::GetLastError());
+ }
+ initialized.insert(::GetCurrentProcessId());
}
- if (!::SymInitialize(process, NULL, TRUE)) {
- printf("failed to initialize symbols: %lu", ::GetLastError());
- }
- initialized.insert(::GetCurrentProcessId());
- }
-}
-
-
-
-StackData::StackData()
- : m_Count(0)
- , m_Function()
- , m_Line(-1)
-{
- initTrace();
}
-StackData::StackData(const char *function, int line)
- : m_Count(0)
- , m_Function(function)
- , m_Line(line)
-{
+StackData::StackData() : m_Count(0), m_Function(), m_Line(-1) { initTrace(); }
-}
+StackData::StackData(const char* function, int line) : m_Count(0), m_Function(function), m_Line(line) {}
std::string StackData::toString() const {
- initDbgIfNecess();
+ initDbgIfNecess();
- char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
- PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
- symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
- symbol->MaxNameLen = MAX_SYM_NAME;
+ char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
+ PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
+ symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
+ symbol->MaxNameLen = MAX_SYM_NAME;
- std::ostringstream stackStream;
+ std::ostringstream stackStream;
- if (m_Function.length() > 0) {
- stackStream << "[" << m_Function << ":" << m_Line << "]\n";
- }
+ if (m_Function.length() > 0) {
+ stackStream << "[" << m_Function << ":" << m_Line << "]\n";
+ }
- for(unsigned int i = 0; i < m_Count; ++i) {
- DWORD64 displacement = 0;
- if (!::SymFromAddr(::GetCurrentProcess(), (DWORD64)m_Stack[i], &displacement, symbol)) {
- stackStream << m_Count - i - 1 << ": [" << m_Stack[i] << "]\n";
- } else {
- stackStream << m_Count - i - 1 << ": " << symbol->Name << "\n";
+ for (unsigned int i = 0; i < m_Count; ++i) {
+ DWORD64 displacement = 0;
+ if (!::SymFromAddr(::GetCurrentProcess(), (DWORD64)m_Stack[i], &displacement, symbol)) {
+ stackStream << m_Count - i - 1 << ": [" << m_Stack[i] << "]\n";
+ } else {
+ stackStream << m_Count - i - 1 << ": " << symbol->Name << "\n";
+ }
}
- }
- return stackStream.str();
+ return stackStream.str();
}
void StackData::load_modules(HANDLE process, DWORD processID) {
- HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID);
- if (snap == INVALID_HANDLE_VALUE)
- return;
+ HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processID);
+ if (snap == INVALID_HANDLE_VALUE)
+ return;
- MODULEENTRY32 entry;
- entry.dwSize = sizeof(entry);
+ MODULEENTRY32 entry;
+ entry.dwSize = sizeof(entry);
- if (Module32First(snap, &entry)) {
- do {
- std::string fileName = ToString(entry.szExePath, false);
- std::string moduleName = ToString(entry.szModule, false);
- SymLoadModule64(process, NULL, fileName.c_str(), moduleName.c_str(), (DWORD64) entry.modBaseAddr, entry.modBaseSize);
- } while (Module32Next(snap, &entry));
- }
- CloseHandle(snap);
+ if (Module32First(snap, &entry)) {
+ do {
+ std::string fileName = ToString(entry.szExePath, false);
+ std::string moduleName = ToString(entry.szModule, false);
+ SymLoadModule64(process, NULL, fileName.c_str(), moduleName.c_str(), (DWORD64)entry.modBaseAddr,
+ entry.modBaseSize);
+ } while (Module32Next(snap, &entry));
+ }
+ CloseHandle(snap);
}
-#pragma warning( disable : 4748 )
+#pragma warning(disable : 4748)
void StackData::initTrace() {
#ifdef _X86_
- load_modules(::GetCurrentProcess(), ::GetCurrentProcessId());
- CONTEXT context;
- std::memset(&context, 0, sizeof(CONTEXT));
- context.ContextFlags = CONTEXT_CONTROL;
- //Why only for 64 bit?
+ load_modules(::GetCurrentProcess(), ::GetCurrentProcessId());
+ CONTEXT context;
+ std::memset(&context, 0, sizeof(CONTEXT));
+ context.ContextFlags = CONTEXT_CONTROL;
+ // Why only for 64 bit?
#if BOOST_ARCH_X86_64 || defined(__clang__)
- ::RtlCaptureContext(&context);
+ ::RtlCaptureContext(&context);
#else
- __asm
- {
+ __asm {
Label:
mov [context.Ebp], ebp;
mov [context.Esp], esp;
mov eax, [Label];
mov [context.Eip], eax;
- }
+ }
#endif
- STACKFRAME64 stackFrame;
- ::ZeroMemory(&stackFrame, sizeof(STACKFRAME64));
- stackFrame.AddrPC.Offset = context.Eip;
- stackFrame.AddrPC.Mode = AddrModeFlat;
- stackFrame.AddrFrame.Offset = context.Ebp;
- stackFrame.AddrFrame.Mode = AddrModeFlat;
- stackFrame.AddrStack.Offset = context.Esp;
- stackFrame.AddrStack.Mode = AddrModeFlat;
- m_Count = 0;
- while (m_Count < FRAMES_TO_CAPTURE) {
- if (!StackWalk64(IMAGE_FILE_MACHINE_I386, ::GetCurrentProcess(),
- ::GetCurrentThread(), &stackFrame, &context, NULL,
- &SymFunctionTableAccess64, &SymGetModuleBase64, NULL)) {
- break;
- }
+ STACKFRAME64 stackFrame;
+ ::ZeroMemory(&stackFrame, sizeof(STACKFRAME64));
+ stackFrame.AddrPC.Offset = context.Eip;
+ stackFrame.AddrPC.Mode = AddrModeFlat;
+ stackFrame.AddrFrame.Offset = context.Ebp;
+ stackFrame.AddrFrame.Mode = AddrModeFlat;
+ stackFrame.AddrStack.Offset = context.Esp;
+ stackFrame.AddrStack.Mode = AddrModeFlat;
+ m_Count = 0;
+ while (m_Count < FRAMES_TO_CAPTURE) {
+ if (!StackWalk64(IMAGE_FILE_MACHINE_I386, ::GetCurrentProcess(), ::GetCurrentThread(), &stackFrame, &context,
+ NULL, &SymFunctionTableAccess64, &SymGetModuleBase64, NULL)) {
+ break;
+ }
- if (stackFrame.AddrPC.Offset == 0) {
- continue;
- break;
- }
+ if (stackFrame.AddrPC.Offset == 0) {
+ continue;
+ break;
+ }
- m_Stack[m_Count++] = reinterpret_cast<void *>(stackFrame.AddrPC.Offset);
- }
+ m_Stack[m_Count++] = reinterpret_cast<void*>(stackFrame.AddrPC.Offset);
+ }
#endif
}
-
-bool MOShared::operator==(const StackData &LHS, const StackData &RHS) {
- if (LHS.m_Count != RHS.m_Count) {
- return false;
- } else {
- for (int i = 0; i < LHS.m_Count; ++i) {
- if (LHS.m_Stack[i] != RHS.m_Stack[i]) {
+bool MOShared::operator==(const StackData& LHS, const StackData& RHS) {
+ if (LHS.m_Count != RHS.m_Count) {
return false;
- }
+ } else {
+ for (int i = 0; i < LHS.m_Count; ++i) {
+ if (LHS.m_Stack[i] != RHS.m_Stack[i]) {
+ return false;
+ }
+ }
}
- }
- return true;
+ return true;
}
-
-bool MOShared::operator<(const StackData &LHS, const StackData &RHS) {
- if (LHS.m_Count != RHS.m_Count) {
- return LHS.m_Count < RHS.m_Count;
- } else {
- for (int i = 0; i < LHS.m_Count; ++i) {
- if (LHS.m_Stack[i] != RHS.m_Stack[i]) {
- return LHS.m_Stack[i] < RHS.m_Stack[i];
- }
+bool MOShared::operator<(const StackData& LHS, const StackData& RHS) {
+ if (LHS.m_Count != RHS.m_Count) {
+ return LHS.m_Count < RHS.m_Count;
+ } else {
+ for (int i = 0; i < LHS.m_Count; ++i) {
+ if (LHS.m_Stack[i] != RHS.m_Stack[i]) {
+ return LHS.m_Stack[i] < RHS.m_Stack[i];
+ }
+ }
}
- }
- return false;
+ return false;
}
#endif
diff --git a/src/shared/stackdata.h b/src/shared/stackdata.h index 7151699c..252b5ba4 100644 --- a/src/shared/stackdata.h +++ b/src/shared/stackdata.h @@ -1,50 +1,41 @@ #ifndef STACKDATA_H
#define STACKDATA_H
-
-#include <string>
#include <Windows.h>
-
+#include <string>
namespace MOShared {
-
class StackData {
- friend bool operator==(const StackData &LHS, const StackData &RHS);
- friend bool operator<(const StackData &LHS, const StackData &RHS);
-public:
+ friend bool operator==(const StackData& LHS, const StackData& RHS);
+ friend bool operator<(const StackData& LHS, const StackData& RHS);
- StackData();
- StackData(const char *function, int line);
+public:
+ StackData();
+ StackData(const char* function, int line);
- std::string toString() const;
+ std::string toString() const;
private:
+ void load_modules(HANDLE process, DWORD processID);
- void load_modules(HANDLE process, DWORD processID);
-
- void initTrace();
+ void initTrace();
private:
-
- static const int FRAMES_TO_SKIP = 1;
- static const int FRAMES_TO_CAPTURE = 20;
+ static const int FRAMES_TO_SKIP = 1;
+ static const int FRAMES_TO_CAPTURE = 20;
private:
-
- LPVOID m_Stack[FRAMES_TO_CAPTURE];
- USHORT m_Count;
- std::string m_Function;
- int m_Line;
-
+ LPVOID m_Stack[FRAMES_TO_CAPTURE];
+ USHORT m_Count;
+ std::string m_Function;
+ int m_Line;
};
+bool operator==(const StackData& LHS, const StackData& RHS);
-bool operator==(const StackData &LHS, const StackData &RHS);
-
-bool operator<(const StackData &LHS, const StackData &RHS);
+bool operator<(const StackData& LHS, const StackData& RHS);
} // namespace MOShared
-
#endif // STACKDATA_H
diff --git a/src/shared/util.cpp b/src/shared/util.cpp index 5491a9e6..0243bb88 100644 --- a/src/shared/util.cpp +++ b/src/shared/util.cpp @@ -18,161 +18,136 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. */
#include "util.h"
-#include "windows_error.h"
#include "error_report.h"
+#include "windows_error.h"
-#include <sstream>
-#include <locale>
-#include <algorithm>
#include <DbgHelp.h>
-#include <set>
+#include <algorithm>
#include <boost/scoped_array.hpp>
+#include <locale>
+#include <set>
+#include <sstream>
namespace MOShared {
+bool FileExists(const std::string& filename) {
+ DWORD dwAttrib = ::GetFileAttributesA(filename.c_str());
-bool FileExists(const std::string &filename)
-{
- DWORD dwAttrib = ::GetFileAttributesA(filename.c_str());
-
- return (dwAttrib != INVALID_FILE_ATTRIBUTES);
+ return (dwAttrib != INVALID_FILE_ATTRIBUTES);
}
-bool FileExists(const std::wstring &filename)
-{
- DWORD dwAttrib = ::GetFileAttributesW(filename.c_str());
+bool FileExists(const std::wstring& filename) {
+ DWORD dwAttrib = ::GetFileAttributesW(filename.c_str());
- return (dwAttrib != INVALID_FILE_ATTRIBUTES);
+ return (dwAttrib != INVALID_FILE_ATTRIBUTES);
}
-bool FileExists(const std::wstring &searchPath, const std::wstring &filename)
-{
- std::wstringstream stream;
- stream << searchPath << "\\" << filename;
- return FileExists(stream.str());
+bool FileExists(const std::wstring& searchPath, const std::wstring& filename) {
+ std::wstringstream stream;
+ stream << searchPath << "\\" << filename;
+ return FileExists(stream.str());
}
-std::string ToString(const std::wstring &source, bool utf8)
-{
- std::string result;
- if (source.length() > 0) {
- UINT codepage = CP_UTF8;
- if (!utf8) {
- codepage = AreFileApisANSI() ? GetACP() : GetOEMCP();
- }
- int sizeRequired = ::WideCharToMultiByte(codepage, 0, &source[0], -1, nullptr, 0, nullptr, nullptr);
- if (sizeRequired == 0) {
- throw windows_error("failed to convert string to multibyte");
+std::string ToString(const std::wstring& source, bool utf8) {
+ std::string result;
+ if (source.length() > 0) {
+ UINT codepage = CP_UTF8;
+ if (!utf8) {
+ codepage = AreFileApisANSI() ? GetACP() : GetOEMCP();
+ }
+ int sizeRequired = ::WideCharToMultiByte(codepage, 0, &source[0], -1, nullptr, 0, nullptr, nullptr);
+ if (sizeRequired == 0) {
+ throw windows_error("failed to convert string to multibyte");
+ }
+ // the size returned by WideCharToMultiByte contains zero termination IF -1 is specified for the length.
+ // we don't want that \0 in the string because then the length field would be wrong. Because madness
+ result.resize(sizeRequired - 1, '\0');
+ ::WideCharToMultiByte(codepage, 0, &source[0], (int)source.size(), &result[0], sizeRequired, nullptr, nullptr);
}
- // the size returned by WideCharToMultiByte contains zero termination IF -1 is specified for the length.
- // we don't want that \0 in the string because then the length field would be wrong. Because madness
- result.resize(sizeRequired - 1, '\0');
- ::WideCharToMultiByte(codepage, 0, &source[0], (int)source.size(), &result[0], sizeRequired, nullptr, nullptr);
- }
- return result;
+ return result;
}
-std::wstring ToWString(const std::string &source, bool utf8)
-{
- std::wstring result;
- if (source.length() > 0) {
- UINT codepage = CP_UTF8;
- if (!utf8) {
- codepage = AreFileApisANSI() ? GetACP() : GetOEMCP();
- }
- int sizeRequired
- = ::MultiByteToWideChar(codepage, 0, source.c_str(),
- static_cast<int>(source.length()), nullptr, 0);
- if (sizeRequired == 0) {
- throw windows_error("failed to convert string to wide character");
+std::wstring ToWString(const std::string& source, bool utf8) {
+ std::wstring result;
+ if (source.length() > 0) {
+ UINT codepage = CP_UTF8;
+ if (!utf8) {
+ codepage = AreFileApisANSI() ? GetACP() : GetOEMCP();
+ }
+ int sizeRequired =
+ ::MultiByteToWideChar(codepage, 0, source.c_str(), static_cast<int>(source.length()), nullptr, 0);
+ if (sizeRequired == 0) {
+ throw windows_error("failed to convert string to wide character");
+ }
+ result.resize(sizeRequired, L'\0');
+ ::MultiByteToWideChar(codepage, 0, source.c_str(), static_cast<int>(source.length()), &result[0], sizeRequired);
}
- result.resize(sizeRequired, L'\0');
- ::MultiByteToWideChar(codepage, 0, source.c_str(),
- static_cast<int>(source.length()), &result[0],
- sizeRequired);
- }
- return result;
+ return result;
}
static std::locale loc("");
-static auto locToLowerW = [] (wchar_t in) -> wchar_t {
- return std::tolower(in, loc);
-};
+static auto locToLowerW = [](wchar_t in) -> wchar_t { return std::tolower(in, loc); };
-static auto locToLower = [] (char in) -> char {
- return std::tolower(in, loc);
-};
+static auto locToLower = [](char in) -> char { return std::tolower(in, loc); };
-std::string &ToLower(std::string &text)
-{
- std::transform(text.begin(), text.end(), text.begin(), locToLower);
- return text;
+std::string& ToLower(std::string& text) {
+ std::transform(text.begin(), text.end(), text.begin(), locToLower);
+ return text;
}
-std::string ToLower(const std::string &text)
-{
- std::string result(text);
- std::transform(result.begin(), result.end(), result.begin(), locToLower);
- return result;
+std::string ToLower(const std::string& text) {
+ std::string result(text);
+ std::transform(result.begin(), result.end(), result.begin(), locToLower);
+ return result;
}
-std::wstring &ToLower(std::wstring &text)
-{
- std::transform(text.begin(), text.end(), text.begin(), locToLowerW);
- return text;
+std::wstring& ToLower(std::wstring& text) {
+ std::transform(text.begin(), text.end(), text.begin(), locToLowerW);
+ return text;
}
-std::wstring ToLower(const std::wstring &text)
-{
- std::wstring result(text);
- std::transform(result.begin(), result.end(), result.begin(), locToLowerW);
- return result;
+std::wstring ToLower(const std::wstring& text) {
+ std::wstring result(text);
+ std::transform(result.begin(), result.end(), result.begin(), locToLowerW);
+ return result;
}
-bool CaseInsenstiveComparePred(wchar_t lhs, wchar_t rhs)
-{
- return std::tolower(lhs, loc) == std::tolower(rhs, loc);
-}
+bool CaseInsenstiveComparePred(wchar_t lhs, wchar_t rhs) { return std::tolower(lhs, loc) == std::tolower(rhs, loc); }
-bool CaseInsensitiveEqual(const std::wstring &lhs, const std::wstring &rhs)
-{
- return (lhs.length() == rhs.length())
- && std::equal(lhs.begin(), lhs.end(),
- rhs.begin(),
- [] (wchar_t lhs, wchar_t rhs) -> bool {
- return std::tolower(lhs, loc) == std::tolower(rhs, loc);
- });
+bool CaseInsensitiveEqual(const std::wstring& lhs, const std::wstring& rhs) {
+ return (lhs.length() == rhs.length()) &&
+ std::equal(lhs.begin(), lhs.end(), rhs.begin(), [](wchar_t lhs, wchar_t rhs) -> bool {
+ return std::tolower(lhs, loc) == std::tolower(rhs, loc);
+ });
}
-VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName)
-{
- DWORD handle = 0UL;
- DWORD size = ::GetFileVersionInfoSizeW(fileName.c_str(), &handle);
- if (size == 0) {
- throw windows_error("failed to determine file version info size");
- }
-
- boost::scoped_array<char> buffer(new char[size]);
- try {
- handle = 0UL;
- if (!::GetFileVersionInfoW(fileName.c_str(), handle, size, buffer.get())) {
- throw windows_error("failed to determine file version info");
+VS_FIXEDFILEINFO GetFileVersion(const std::wstring& fileName) {
+ DWORD handle = 0UL;
+ DWORD size = ::GetFileVersionInfoSizeW(fileName.c_str(), &handle);
+ if (size == 0) {
+ throw windows_error("failed to determine file version info size");
}
- void *versionInfoPtr = nullptr;
- UINT versionInfoLength = 0;
- if (!::VerQueryValue(buffer.get(), L"\\", &versionInfoPtr, &versionInfoLength)) {
- throw windows_error("failed to determine file version");
- }
+ boost::scoped_array<char> buffer(new char[size]);
+ try {
+ handle = 0UL;
+ if (!::GetFileVersionInfoW(fileName.c_str(), handle, size, buffer.get())) {
+ throw windows_error("failed to determine file version info");
+ }
- VS_FIXEDFILEINFO result = *(VS_FIXEDFILEINFO*)versionInfoPtr;
- return result;
- } catch (...) {
- throw;
- }
-}
+ void* versionInfoPtr = nullptr;
+ UINT versionInfoLength = 0;
+ if (!::VerQueryValue(buffer.get(), L"\\", &versionInfoPtr, &versionInfoLength)) {
+ throw windows_error("failed to determine file version");
+ }
+ VS_FIXEDFILEINFO result = *(VS_FIXEDFILEINFO*)versionInfoPtr;
+ return result;
+ } catch (...) {
+ throw;
+ }
+}
} // namespace MOShared
diff --git a/src/shared/util.h b/src/shared/util.h index 1e498059..4b390cf3 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -20,7 +20,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #ifndef UTIL_H
#define UTIL_H
-
#include <string>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
@@ -28,23 +27,23 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. namespace MOShared {
/// Test if a file (or directory) by the specified name exists
-bool FileExists(const std::string &filename);
-bool FileExists(const std::wstring &filename);
+bool FileExists(const std::string& filename);
+bool FileExists(const std::wstring& filename);
-bool FileExists(const std::wstring &searchPath, const std::wstring &filename);
+bool FileExists(const std::wstring& searchPath, const std::wstring& filename);
-std::string ToString(const std::wstring &source, bool utf8);
-std::wstring ToWString(const std::string &source, bool utf8);
+std::string ToString(const std::wstring& source, bool utf8);
+std::wstring ToWString(const std::string& source, bool utf8);
-std::string &ToLower(std::string &text);
-std::string ToLower(const std::string &text);
+std::string& ToLower(std::string& text);
+std::string ToLower(const std::string& text);
-std::wstring &ToLower(std::wstring &text);
-std::wstring ToLower(const std::wstring &text);
+std::wstring& ToLower(std::wstring& text);
+std::wstring ToLower(const std::wstring& text);
-bool CaseInsensitiveEqual(const std::wstring &lhs, const std::wstring &rhs);
+bool CaseInsensitiveEqual(const std::wstring& lhs, const std::wstring& rhs);
-VS_FIXEDFILEINFO GetFileVersion(const std::wstring &fileName);
+VS_FIXEDFILEINFO GetFileVersion(const std::wstring& fileName);
} // namespace MOShared
diff --git a/src/shared/windows_error.cpp b/src/shared/windows_error.cpp index 97a58a20..ab5c7b8e 100644 --- a/src/shared/windows_error.cpp +++ b/src/shared/windows_error.cpp @@ -22,28 +22,27 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. namespace MOShared {
-std::string windows_error::constructMessage(const std::string& input, int inErrorCode)
-{
- std::ostringstream finalMessage;
- finalMessage << input;
+std::string windows_error::constructMessage(const std::string& input, int inErrorCode) {
+ std::ostringstream finalMessage;
+ finalMessage << input;
- LPSTR buffer = nullptr;
+ LPSTR buffer = nullptr;
- DWORD errorCode = inErrorCode != -1 ? inErrorCode : ::GetLastError();
+ DWORD errorCode = inErrorCode != -1 ? inErrorCode : ::GetLastError();
- // TODO: the message is not english?
- if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- nullptr, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, nullptr) == 0) {
- finalMessage << " (errorcode " << errorCode << ")";
- } else {
- LPSTR lastChar = buffer + strlen(buffer) - 2;
- *lastChar = '\0';
- finalMessage << " (" << buffer << " [" << errorCode << "])";
- LocalFree(buffer); // allocated by FormatMessage
- }
+ // TODO: the message is not english?
+ if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, errorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, nullptr) == 0) {
+ finalMessage << " (errorcode " << errorCode << ")";
+ } else {
+ LPSTR lastChar = buffer + strlen(buffer) - 2;
+ *lastChar = '\0';
+ finalMessage << " (" << buffer << " [" << errorCode << "])";
+ LocalFree(buffer); // allocated by FormatMessage
+ }
- ::SetLastError(errorCode); // restore error code because FormatMessage might have modified it
- return finalMessage.str();
+ ::SetLastError(errorCode); // restore error code because FormatMessage might have modified it
+ return finalMessage.str();
}
} // namespace MOShared
diff --git a/src/shared/windows_error.h b/src/shared/windows_error.h index 03ce0abd..66c512f6 100644 --- a/src/shared/windows_error.h +++ b/src/shared/windows_error.h @@ -20,7 +20,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #ifndef WINDOWS_ERROR_H
#define WINDOWS_ERROR_H
-
#include <stdexcept>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@@ -29,14 +28,15 @@ namespace MOShared { class windows_error : public std::runtime_error {
public:
- windows_error(const std::string& message, int errorcode = ::GetLastError())
- : runtime_error(constructMessage(message, errorcode)), m_ErrorCode(errorcode)
- {}
- int getErrorCode() const { return m_ErrorCode; }
+ windows_error(const std::string& message, int errorcode = ::GetLastError())
+ : runtime_error(constructMessage(message, errorcode)), m_ErrorCode(errorcode) {}
+ int getErrorCode() const { return m_ErrorCode; }
+
private:
- std::string constructMessage(const std::string& input, int errorcode);
+ std::string constructMessage(const std::string& input, int errorcode);
+
private:
- int m_ErrorCode;
+ int m_ErrorCode;
};
} // namespace MOShared
|
