diff --git a/src/openrct2/core/FileScanner.cpp b/src/openrct2/core/FileScanner.cpp index e5cdc3a933..886c59df4f 100644 --- a/src/openrct2/core/FileScanner.cpp +++ b/src/openrct2/core/FileScanner.cpp @@ -375,6 +375,11 @@ private: #endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +IFileScanner * Path::ScanDirectory(const std::string &pattern, bool recurse) +{ + return Path::ScanDirectory(pattern.c_str(), recurse); +} + IFileScanner * Path::ScanDirectory(const utf8 * pattern, bool recurse) { #ifdef __WINDOWS__ diff --git a/src/openrct2/core/FileScanner.h b/src/openrct2/core/FileScanner.h index 54d525eeef..df4f0ce1a9 100644 --- a/src/openrct2/core/FileScanner.h +++ b/src/openrct2/core/FileScanner.h @@ -47,6 +47,15 @@ struct QueryDirectoryResult namespace Path { + /** + * Scans a directory and optionally sub directories for files that matches the + * given pattern and returns an enumerator. + * @param pattern The path followed by a semi-colon delimited list of wildcard patterns. + * @param recurse Whether to scan sub directories or not. + * @returns A new FileScanner, this must be deleted when no longer needed. + */ + IFileScanner * ScanDirectory(const std::string &pattern, bool recurse); + /** * Scans a directory and optionally sub directories for files that matches the * given pattern and returns an enumerator. diff --git a/src/openrct2/core/Path.cpp b/src/openrct2/core/Path.cpp index d36c4bd4ee..c9d0d5dcbf 100644 --- a/src/openrct2/core/Path.cpp +++ b/src/openrct2/core/Path.cpp @@ -29,6 +29,14 @@ extern "C" namespace Path { + std::string Append(const std::string &a, const std::string &b) + { + utf8 buffer[MAX_PATH]; + String::Set(buffer, sizeof(buffer), a.c_str()); + Path::Append(buffer, sizeof(buffer), b.c_str()); + return std::string(buffer); + } + utf8 * Append(utf8 * buffer, size_t bufferSize, const utf8 * src) { return safe_strcat_path(buffer, src, bufferSize); @@ -81,6 +89,14 @@ namespace Path lastPathSeperator + 1; } + std::string GetFileNameWithoutExtension(const std::string &path) + { + utf8 * cstr = GetFileNameWithoutExtension(path.c_str()); + std::string result = String::ToStd(cstr); + Memory::Free(cstr); + return result; + } + utf8 * GetFileNameWithoutExtension(const utf8 * path) { size_t maxSize = String::SizeOf(path) + 1; diff --git a/src/openrct2/core/Path.hpp b/src/openrct2/core/Path.hpp index 9d72aef2d2..fd0fd59c50 100644 --- a/src/openrct2/core/Path.hpp +++ b/src/openrct2/core/Path.hpp @@ -23,10 +23,12 @@ extern "C" namespace Path { + std::string Append(const std::string &a, const std::string &b); utf8 * Append(utf8 * buffer, size_t bufferSize, const utf8 * src); utf8 * GetDirectory(const utf8 * path); utf8 * GetDirectory(utf8 * buffer, size_t bufferSize, const utf8 * path); const utf8 * GetFileName(const utf8 * path); + std::string GetFileNameWithoutExtension(const std::string &path); utf8 * GetFileNameWithoutExtension(const utf8 * path); utf8 * GetFileNameWithoutExtension(utf8 * buffer, size_t bufferSize, const utf8 * path); const utf8 * GetExtension(const utf8 * path); diff --git a/src/openrct2/core/String.cpp b/src/openrct2/core/String.cpp index 9dba13984c..29045d373c 100644 --- a/src/openrct2/core/String.cpp +++ b/src/openrct2/core/String.cpp @@ -50,6 +50,26 @@ namespace String return str == nullptr || str[0] == '\0'; } + sint32 Compare(const std::string &a, const std::string &b, bool ignoreCase = false) + { + return Compare(a.c_str(), b.c_str(), ignoreCase); + } + + sint32 Compare(const utf8 * a, const utf8 * b, bool ignoreCase = false) + { + if (a == b) return true; + if (a == nullptr || b == nullptr) return false; + + if (ignoreCase) + { + return _stricmp(a, b); + } + else + { + return strcmp(a, b); + } + } + bool Equals(const utf8 * a, const utf8 * b, bool ignoreCase) { if (a == b) return true; @@ -247,6 +267,11 @@ namespace String return buffer; } + utf8 * Duplicate(const std::string &src) + { + return String::Duplicate(src.c_str()); + } + utf8 * Duplicate(const utf8 * src) { utf8 * result = nullptr; diff --git a/src/openrct2/core/String.hpp b/src/openrct2/core/String.hpp index 65d94e9c6b..ad049a8b03 100644 --- a/src/openrct2/core/String.hpp +++ b/src/openrct2/core/String.hpp @@ -27,6 +27,8 @@ namespace String std::string StdFormat(const utf8 * format, ...); bool IsNullOrEmpty(const utf8 * str); + sint32 Compare(const std::string &a, const std::string &b, bool ignoreCase = false); + sint32 Compare(const utf8 * a, const utf8 * b, bool ignoreCase = false); bool Equals(const utf8 * a, const utf8 * b, bool ignoreCase = false); bool StartsWith(const utf8 * str, const utf8 * match, bool ignoreCase = false); size_t LastIndexOf(const utf8 * str, utf8 match); @@ -48,6 +50,7 @@ namespace String utf8 * Format(const utf8 * format, ...); utf8 * Format_VA(const utf8 * format, va_list args); utf8 * AppendFormat(utf8 * buffer, size_t bufferSize, const utf8 * format, ...); + utf8 * Duplicate(const std::string &src); utf8 * Duplicate(const utf8 * src); /** diff --git a/src/openrct2/ride/TrackDesignRepository.cpp b/src/openrct2/ride/TrackDesignRepository.cpp index 5f1e6b9818..3bd7c7177d 100644 --- a/src/openrct2/ride/TrackDesignRepository.cpp +++ b/src/openrct2/ride/TrackDesignRepository.cpp @@ -110,8 +110,8 @@ public: (entry == nullptr || String::Equals(item.ObjectEntry.c_str(), entry, true))) { track_design_file_ref ref; - ref.name = GetNameFromTrackPath(item.Path.c_str()); - ref.path = String::Duplicate(item.Path.c_str()); + ref.name = String::Duplicate(GetNameFromTrackPath(item.Path)); + ref.path = String::Duplicate(item.Path); refs.push_back(ref); } } @@ -228,10 +228,7 @@ private: void Scan(const std::string &directory, uint32 flags = 0) { - utf8 pattern[MAX_PATH]; - String::Set(pattern, sizeof(pattern), directory.c_str()); - Path::Append(pattern, sizeof(pattern), "*.td4;*.td6"); - + std::string pattern = Path::Append(directory, "*.td4;*.td6"); IFileScanner * scanner = Path::ScanDirectory(pattern, true); while (scanner->Next()) { @@ -241,14 +238,14 @@ private: delete scanner; } - void AddTrack(const utf8 * path, uint32 flags = 0) + void AddTrack(const std::string path, uint32 flags = 0) { - rct_track_td6 * td6 = track_design_open(path); + rct_track_td6 * td6 = track_design_open(path.c_str()); if (td6 != nullptr) { TrackRepositoryItem item; - item.Name = std::string(GetNameFromTrackPath(path)); - item.Path = std::string(path); + item.Name = GetNameFromTrackPath(path); + item.Path = path; item.RideType = td6->type; item.ObjectEntry = std::string(td6->vehicle_object.name, 8); item.Flags = flags; @@ -266,10 +263,7 @@ private: { return a.RideType < b.RideType; } - - const utf8 * nameA = a.Name.c_str(); - const utf8 * nameB = b.Name.c_str(); - return _stricmp(nameA, nameB) < 0; + return String::Compare(a.Name, b.Name) < 0; }); } @@ -369,12 +363,9 @@ private: } public: - static utf8 * GetNameFromTrackPath(const utf8 * path) + static std::string GetNameFromTrackPath(const std::string &path) { - utf8 * name = Memory::Allocate(MAX_PATH); - Path::GetFileNameWithoutExtension(name, MAX_PATH, path); - name = Memory::ReallocateArray(name, String::SizeOf(name) + 1); - return name; + return Path::GetFileNameWithoutExtension(path); } }; @@ -431,6 +422,6 @@ extern "C" utf8 * track_repository_get_name_from_path(const utf8 * path) { - return TrackDesignRepository::GetNameFromTrackPath(path); + return String::Duplicate(TrackDesignRepository::GetNameFromTrackPath(path)); } }