diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/bit_field.h | 11 | ||||
-rw-r--r-- | src/common/file_util.cpp | 164 | ||||
-rw-r--r-- | src/common/file_util.h | 26 | ||||
-rw-r--r-- | src/common/hash.cpp | 16 | ||||
-rw-r--r-- | src/common/symbols.cpp | 41 | ||||
-rw-r--r-- | src/common/symbols.h | 21 |
6 files changed, 112 insertions, 167 deletions
diff --git a/src/common/bit_field.h b/src/common/bit_field.h index d306ce9a9..66689f398 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h @@ -125,21 +125,10 @@ public: // so that we can use this within unions BitField() = default; -#ifndef _WIN32 // We explicitly delete the copy assigment operator here, because the // default copy assignment would copy the full storage value, rather than // just the bits relevant to this particular bit field. - // Ideally, we would just implement the copy assignment to copy only the - // relevant bits, but this requires compiler support for unrestricted - // unions. - // MSVC 2013 has no support for this, hence we disable this code on - // Windows (so that the default copy assignment operator will be used). - // For any C++11 conformant compiler we delete the operator to make sure - // we never use this inappropriate operator to begin with. - // TODO: Implement this operator properly once all target compilers - // support unrestricted unions. BitField& operator=(const BitField&) = delete; -#endif FORCE_INLINE BitField& operator=(T val) { diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 836b58d52..1e0d33313 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -420,28 +420,23 @@ bool CreateEmptyFile(const std::string &filename) } -// Scans the directory tree gets, starting from _Directory and adds the -// results into parentEntry. Returns the number of files+directories found -u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) +int ScanDirectoryTreeAndCallback(const std::string &directory, std::function<int(const std::string&, const std::string&)> callback) { LOG_TRACE(Common_Filesystem, "directory %s", directory.c_str()); // How many files + directories we found - u32 foundEntries = 0; + int found_entries = 0; #ifdef _WIN32 // Find the first file in the directory. WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile(Common::UTF8ToTStr(directory + "\\*").c_str(), &ffd); - if (hFind == INVALID_HANDLE_VALUE) - { - FindClose(hFind); - return foundEntries; + HANDLE handle_find = FindFirstFile(Common::UTF8ToTStr(directory + "\\*").c_str(), &ffd); + if (handle_find == INVALID_HANDLE_VALUE) { + FindClose(handle_find); + return found_entries; } // windows loop - do - { - FSTEntry entry; - const std::string virtualName(Common::TStrToUTF8(ffd.cFileName)); + do { + const std::string virtual_name(Common::TStrToUTF8(ffd.cFileName)); #else struct dirent dirent, *result = nullptr; @@ -450,115 +445,80 @@ u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) return 0; // non windows loop - while (!readdir_r(dirp, &dirent, &result) && result) - { - FSTEntry entry; - const std::string virtualName(result->d_name); + while (!readdir_r(dirp, &dirent, &result) && result) { + const std::string virtual_name(result->d_name); #endif // check for "." and ".." - if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || - ((virtualName[0] == '.') && (virtualName[1] == '.') && - (virtualName[2] == '\0'))) + if (((virtual_name[0] == '.') && (virtual_name[1] == '\0')) || + ((virtual_name[0] == '.') && (virtual_name[1] == '.') && + (virtual_name[2] == '\0'))) continue; - entry.virtualName = virtualName; - entry.physicalName = directory; - entry.physicalName += DIR_SEP + entry.virtualName; - if (IsDirectory(entry.physicalName.c_str())) - { - entry.isDirectory = true; - // is a directory, lets go inside - entry.size = ScanDirectoryTree(entry.physicalName, entry); - foundEntries += (u32)entry.size; - } - else - { // is a file - entry.isDirectory = false; - entry.size = GetSize(entry.physicalName.c_str()); + int ret = callback(directory, virtual_name); + if (ret < 0) { + if (ret != -1) + found_entries = ret; + break; } - ++foundEntries; - // Push into the tree - parentEntry.children.push_back(entry); + found_entries += ret; + #ifdef _WIN32 - } while (FindNextFile(hFind, &ffd) != 0); - FindClose(hFind); + } while (FindNextFile(handle_find, &ffd) != 0); + FindClose(handle_find); #else } closedir(dirp); #endif // Return number of entries found. - return foundEntries; + return found_entries; } - -// Deletes the given directory and anything under it. Returns true on success. -bool DeleteDirRecursively(const std::string &directory) +int ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry) { - LOG_TRACE(Common_Filesystem, "%s", directory.c_str()); -#ifdef _WIN32 - // Find the first file in the directory. - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile(Common::UTF8ToTStr(directory + "\\*").c_str(), &ffd); - - if (hFind == INVALID_HANDLE_VALUE) - { - FindClose(hFind); - return false; - } - - // windows loop - do - { - const std::string virtualName(Common::TStrToUTF8(ffd.cFileName)); -#else - struct dirent dirent, *result = nullptr; - DIR *dirp = opendir(directory.c_str()); - if (!dirp) - return false; - - // non windows loop - while (!readdir_r(dirp, &dirent, &result) && result) - { - const std::string virtualName = result->d_name; -#endif + const auto callback = [&parent_entry](const std::string& directory, + const std::string& virtual_name) -> int { + FSTEntry entry; + int found_entries = 0; + entry.virtualName = virtual_name; + entry.physicalName = directory + DIR_SEP + virtual_name; - // check for "." and ".." - if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || - ((virtualName[0] == '.') && (virtualName[1] == '.') && - (virtualName[2] == '\0'))) - continue; + if (IsDirectory(entry.physicalName)) { + entry.isDirectory = true; + // is a directory, lets go inside + entry.size = ScanDirectoryTree(entry.physicalName, entry); + found_entries += (int)entry.size; + } else { // is a file + entry.isDirectory = false; + entry.size = GetSize(entry.physicalName); + } + ++found_entries; + // Push into the tree + parent_entry.children.push_back(entry); + return found_entries; + }; - std::string newPath = directory + DIR_SEP_CHR + virtualName; - if (IsDirectory(newPath)) - { - if (!DeleteDirRecursively(newPath)) - { - #ifndef _WIN32 - closedir(dirp); - #endif + return ScanDirectoryTreeAndCallback(directory, callback); +} - return false; - } - } - else - { - if (!FileUtil::Delete(newPath)) - { - #ifndef _WIN32 - closedir(dirp); - #endif - return false; +bool DeleteDirRecursively(const std::string &directory) +{ + const static auto callback = [](const std::string& directory, + const std::string& virtual_name) -> int { + std::string new_path = directory + DIR_SEP_CHR + virtual_name; + if (IsDirectory(new_path)) { + if (!DeleteDirRecursively(new_path)) { + return -2; } + } else if (!Delete(new_path)) { + return -2; } + return 0; + }; -#ifdef _WIN32 - } while (FindNextFile(hFind, &ffd) != 0); - FindClose(hFind); -#else + if (ScanDirectoryTreeAndCallback(directory, callback) == -2) { + return false; } - closedir(dirp); -#endif FileUtil::DeleteDir(directory); return true; @@ -861,8 +821,8 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam const std::string forbidden_characters = ".\"/\\[]:;=, "; // On a FAT32 partition, 8.3 names are stored as a 11 bytes array, filled with spaces. - short_name = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\0'}; - extension = {' ', ' ', ' ', '\0'}; + short_name = {{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\0'}}; + extension = {{' ', ' ', ' ', '\0'}}; std::string::size_type point = filename.rfind('.'); if (point == filename.size() - 1) diff --git a/src/common/file_util.h b/src/common/file_util.h index e71a9b2fa..3d617f573 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -6,6 +6,7 @@ #include <array> #include <fstream> +#include <functional> #include <cstddef> #include <cstdio> #include <string> @@ -96,9 +97,28 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename); // creates an empty file filename, returns true on success bool CreateEmptyFile(const std::string &filename); -// Scans the directory tree gets, starting from _Directory and adds the -// results into parentEntry. Returns the number of files+directories found -u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry); +/** + * Scans the directory tree, calling the callback for each file/directory found. + * The callback must return the number of files and directories which the provided path contains. + * If the callback's return value is -1, the callback loop is broken immediately. + * If the callback's return value is otherwise negative, the callback loop is broken immediately + * and the callback's return value is returned from this function (to allow for error handling). + * @param directory the parent directory to start scanning from + * @param callback The callback which will be called for each file/directory. It is called + * with the arguments (const std::string& directory, const std::string& virtual_name). + * The `directory `parameter is the path to the directory which contains the file/directory. + * The `virtual_name` parameter is the incomplete file path, without any directory info. + * @return the total number of files/directories found + */ +int ScanDirectoryTreeAndCallback(const std::string &directory, std::function<int(const std::string&, const std::string&)> callback); + +/** + * Scans the directory tree, storing the results. + * @param directory the parent directory to start scanning from + * @param parent_entry FSTEntry where the filesystem tree results will be stored. + * @return the total number of files/directories found + */ +int ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry); // deletes the given directory and anything under it. Returns true on success. bool DeleteDirRecursively(const std::string &directory); diff --git a/src/common/hash.cpp b/src/common/hash.cpp index 413e9c6f1..c49c2f60e 100644 --- a/src/common/hash.cpp +++ b/src/common/hash.cpp @@ -17,27 +17,11 @@ namespace Common { // Block read - if your platform needs to do endian-swapping or can only handle aligned reads, do // the conversion here - -static FORCE_INLINE u32 getblock32(const u32* p, int i) { - return p[i]; -} - static FORCE_INLINE u64 getblock64(const u64* p, int i) { return p[i]; } // Finalization mix - force all bits of a hash block to avalanche - -static FORCE_INLINE u32 fmix32(u32 h) { - h ^= h >> 16; - h *= 0x85ebca6b; - h ^= h >> 13; - h *= 0xc2b2ae35; - h ^= h >> 16; - - return h; -} - static FORCE_INLINE u64 fmix64(u64 k) { k ^= k >> 33; k *= 0xff51afd7ed558ccdllu; diff --git a/src/common/symbols.cpp b/src/common/symbols.cpp index f23e51c9d..db8340043 100644 --- a/src/common/symbols.cpp +++ b/src/common/symbols.cpp @@ -8,46 +8,43 @@ TSymbolsMap g_symbols; namespace Symbols { - bool HasSymbol(u32 _address) + bool HasSymbol(u32 address) { - return g_symbols.find(_address) != g_symbols.end(); + return g_symbols.find(address) != g_symbols.end(); } - void Add(u32 _address, const std::string& _name, u32 _size, u32 _type) + void Add(u32 address, const std::string& name, u32 size, u32 type) { - if (!HasSymbol(_address)) + if (!HasSymbol(address)) { TSymbol symbol; - symbol.address = _address; - symbol.name = _name; - symbol.size = _size; - symbol.type = _type; + symbol.address = address; + symbol.name = name; + symbol.size = size; + symbol.type = type; - g_symbols.insert(TSymbolsPair(_address, symbol)); + g_symbols.emplace(address, symbol); } } - TSymbol GetSymbol(u32 _address) + TSymbol GetSymbol(u32 address) { - TSymbolsMap::iterator foundSymbolItr; - TSymbol symbol; + const auto iter = g_symbols.find(address); - foundSymbolItr = g_symbols.find(_address); - if (foundSymbolItr != g_symbols.end()) - { - symbol = (*foundSymbolItr).second; - } + if (iter != g_symbols.end()) + return iter->second; - return symbol; + return {}; } - const std::string GetName(u32 _address) + + const std::string GetName(u32 address) { - return GetSymbol(_address).name; + return GetSymbol(address).name; } - void Remove(u32 _address) + void Remove(u32 address) { - g_symbols.erase(_address); + g_symbols.erase(address); } void Clear() diff --git a/src/common/symbols.h b/src/common/symbols.h index 6b62b011e..5ed16009c 100644 --- a/src/common/symbols.h +++ b/src/common/symbols.h @@ -12,15 +12,10 @@ struct TSymbol { - TSymbol() : - address(0), - size(0), - type(0) - {} - u32 address; + u32 address = 0; std::string name; - u32 size; - u32 type; + u32 size = 0; + u32 type = 0; }; typedef std::map<u32, TSymbol> TSymbolsMap; @@ -28,12 +23,12 @@ typedef std::pair<u32, TSymbol> TSymbolsPair; namespace Symbols { - bool HasSymbol(u32 _address); + bool HasSymbol(u32 address); - void Add(u32 _address, const std::string& _name, u32 _size, u32 _type); - TSymbol GetSymbol(u32 _address); - const std::string GetName(u32 _address); - void Remove(u32 _address); + void Add(u32 address, const std::string& name, u32 size, u32 type); + TSymbol GetSymbol(u32 address); + const std::string GetName(u32 address); + void Remove(u32 address); void Clear(); } |