Merge pull request #16399 from Gymnasiast/refactor/more-platform-functions-2

C++-ify most path handling
This commit is contained in:
Michael Steenbeek 2022-01-09 13:29:54 +01:00 committed by GitHub
commit 939ddb4813
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 159 additions and 371 deletions

View File

@ -173,10 +173,10 @@ namespace OpenRCT2::Ui
std::string pattern = desc.Filters[0].Pattern;
std::string defaultExtension = pattern.substr(pattern.find_last_of('.'));
const utf8* filename = Path::GetFileName(output.c_str());
const auto filename = Path::GetFileName(output.c_str());
// If there is no extension, append the pattern
const utf8* extension = Path::GetExtension(filename);
const auto extension = Path::GetExtension(filename);
result = output;
if (extension[0] == '\0' && !defaultExtension.empty())
{

View File

@ -194,7 +194,7 @@ void ShortcutManager::LoadUserBindings()
{
try
{
auto path = fs::u8path(_env->GetFilePath(PATHID::CONFIG_SHORTCUTS));
auto path = u8path(_env->GetFilePath(PATHID::CONFIG_SHORTCUTS));
if (fs::exists(path))
{
LoadUserBindings(path);
@ -204,7 +204,7 @@ void ShortcutManager::LoadUserBindings()
try
{
Console::WriteLine("Importing legacy shortcuts...");
auto legacyPath = fs::u8path(_env->GetFilePath(PATHID::CONFIG_SHORTCUTS_LEGACY));
auto legacyPath = u8path(_env->GetFilePath(PATHID::CONFIG_SHORTCUTS_LEGACY));
if (fs::exists(legacyPath))
{
LoadLegacyBindings(legacyPath);
@ -315,7 +315,7 @@ void ShortcutManager::SaveUserBindings()
{
try
{
auto path = fs::u8path(_env->GetFilePath(PATHID::CONFIG_SHORTCUTS));
auto path = u8path(_env->GetFilePath(PATHID::CONFIG_SHORTCUTS));
SaveUserBindings(path);
}
catch (const std::exception& e)

View File

@ -12,6 +12,7 @@
#include <openrct2-ui/windows/Window.h>
#include <openrct2/Context.h>
#include <openrct2/audio/audio.h>
#include <openrct2/core/File.h>
#include <openrct2/localisation/Formatter.h>
#include <openrct2/localisation/Localisation.h>
#include <openrct2/object/ObjectManager.h>
@ -442,7 +443,7 @@ static void WindowInstallTrackDesign(rct_window* w)
safe_strcat_path(destPath, _trackName.c_str(), sizeof(destPath));
path_append_extension(destPath, ".td6", sizeof(destPath));
if (Platform::FileExists(destPath))
if (File::Exists(destPath))
{
log_info("%s already exists, prompting user for a different track design name", destPath);
context_show_error(STR_UNABLE_TO_INSTALL_THIS_TRACK_DESIGN, STR_NONE, {});

View File

@ -226,7 +226,7 @@ static const char* GetFilterPatternByType(const int32_t type, const bool isSave)
static int32_t WindowLoadsaveGetDir(const int32_t type, char* path, size_t pathSize)
{
const char* last_save = GetLastDirectoryByType(type);
if (last_save != nullptr && platform_directory_exists(last_save))
if (last_save != nullptr && Path::DirectoryExists(last_save))
safe_strcpy(path, last_save, pathSize);
else
GetInitialDirectoryByType(type, path, pathSize);

View File

@ -25,6 +25,7 @@
#include <openrct2/audio/AudioMixer.h>
#include <openrct2/audio/audio.h>
#include <openrct2/config/Config.h>
#include <openrct2/core/File.h>
#include <openrct2/core/String.hpp>
#include <openrct2/drawing/IDrawingEngine.h>
#include <openrct2/localisation/Currency.h>
@ -1646,7 +1647,7 @@ private:
this->Invalidate();
break;
case WIDX_TITLE_MUSIC_DROPDOWN:
if ((dropdownIndex == 1 || dropdownIndex == 3) && !Platform::FileExists(context_get_path_legacy(PATH_ID_CSS50)))
if ((dropdownIndex == 1 || dropdownIndex == 3) && !File::Exists(context_get_path_legacy(PATH_ID_CSS50)))
{
context_show_error(STR_OPTIONS_MUSIC_ERR_CSS50_NOT_FOUND, STR_OPTIONS_MUSIC_ERR_CSS50_NOT_FOUND_HINT, {});
}

View File

@ -583,7 +583,7 @@ namespace OpenRCT2
{
if (String::Equals(Path::GetExtension(path), ".sea", true))
{
auto data = DecryptSea(fs::u8path(path));
auto data = DecryptSea(u8path(path));
auto ms = MemoryStream(data.data(), data.size(), MEMORY_ACCESS::READ);
if (!LoadParkFromStream(&ms, path, loadTitleScreenOnFail, asScenario))
{
@ -1208,7 +1208,7 @@ namespace OpenRCT2
auto dstDirectory = Path::GetDirectory(dst);
// Create the directory if necessary
if (!platform_directory_exists(dstDirectory.c_str()))
if (!Path::DirectoryExists(dstDirectory.c_str()))
{
Console::WriteLine("Creating directory '%s'", dstDirectory.c_str());
if (!platform_ensure_directory_exists(dstDirectory.c_str()))

View File

@ -23,6 +23,7 @@
#include "audio/audio.h"
#include "config/Config.h"
#include "core/Console.hpp"
#include "core/File.h"
#include "core/FileScanner.h"
#include "core/Path.hpp"
#include "entity/EntityRegistry.h"
@ -655,7 +656,7 @@ static void limit_autosave_count(const size_t numberOfFilesToKeep, bool processL
for (size_t i = 0; numAutosavesToDelete > 0; i++, numAutosavesToDelete--)
{
if (!platform_file_delete(autosaveFiles[i].data()))
if (!File::Delete(autosaveFiles[i].data()))
{
log_warning("Failed to delete autosave file: %s", autosaveFiles[i].data());
}
@ -697,9 +698,9 @@ void game_autosave()
safe_strcat(backupPath, fileExtension, sizeof(backupPath));
safe_strcat(backupPath, ".bak", sizeof(backupPath));
if (Platform::FileExists(path))
if (File::Exists(path))
{
platform_file_copy(path, backupPath, true);
File::Copy(path, backupPath, true);
}
if (!scenario_save(path, saveFlags))

View File

@ -17,6 +17,7 @@
# include "../OpenRCT2.h"
# include "../audio/audio.h"
# include "../core/Console.hpp"
# include "../core/File.h"
# include "../core/Imaging.h"
# include "../drawing/Drawing.h"
# include "../interface/Viewport.h"
@ -183,7 +184,7 @@ static int cmdline_for_bench_sprite_sort(int argc, const char** argv)
// Extract file names from argument list. If there is no such file, consider it benchmark option.
for (int i = 0; i < argc; i++)
{
if (Platform::FileExists(argv[i]))
if (File::Exists(argv[i]))
{
// Register benchmark for sv6 if valid
std::vector<RecordedPaintSession> sessions = extract_paint_session(argv[i]);

View File

@ -14,6 +14,7 @@
# include "../Context.h"
# include "../GameState.h"
# include "../OpenRCT2.h"
# include "../core/File.h"
# include "../platform/Platform2.h"
# include "../platform/platform.h"
@ -102,7 +103,7 @@ static int CmdlineForBenchSpriteSort(int argc, const char* const* argv)
// Extract file names from argument list. If there is no such file, consider it benchmark option.
for (int i = 0; i < argc; i++)
{
if (Platform::FileExists(argv[i]))
if (File::Exists(argv[i]))
{
// Register benchmark for sv6 if valid
benchmark::RegisterBenchmark(argv[i], BM_update, argv[i]);

View File

@ -13,6 +13,7 @@
#include "../Version.h"
#include "../config/Config.h"
#include "../core/Console.hpp"
#include "../core/File.h"
#include "../core/Guard.hpp"
#include "../core/Memory.hpp"
#include "../core/Path.hpp"
@ -354,7 +355,7 @@ static exitcode_t HandleCommandSetRCT2(CommandLineArgEnumerator* enumerator)
// Check if path exists
Console::WriteLine("Checking path...");
if (!platform_directory_exists(path))
if (!Path::DirectoryExists(path))
{
Console::Error::WriteLine("The path '%s' does not exist", path);
return EXITCODE_FAIL;
@ -367,7 +368,7 @@ static exitcode_t HandleCommandSetRCT2(CommandLineArgEnumerator* enumerator)
String::Set(pathG1Check, sizeof(pathG1Check), path);
Path::Append(pathG1Check, sizeof(pathG1Check), "Data");
Path::Append(pathG1Check, sizeof(pathG1Check), "g1.dat");
if (!Platform::FileExists(pathG1Check))
if (!File::Exists(pathG1Check))
{
Console::Error::WriteLine("RCT2 path not valid.");
Console::Error::WriteLine("Unable to find %s.", pathG1Check);

View File

@ -23,24 +23,40 @@
namespace File
{
bool Exists(const std::string& path)
bool Exists(std::string_view path)
{
return Platform::FileExists(path);
fs::path file = u8path(path);
log_verbose("Checking if file exists: %s", std::string(path).c_str());
return fs::exists(file);
}
bool Copy(const std::string& srcPath, const std::string& dstPath, bool overwrite)
bool Copy(std::string_view srcPath, std::string_view dstPath, bool overwrite)
{
return platform_file_copy(srcPath.c_str(), dstPath.c_str(), overwrite);
if (!overwrite && Exists(dstPath))
{
log_warning("File::Copy(): Not overwriting %s, because overwrite flag == false", std::string(dstPath).c_str());
return false;
}
return fs::copy_file(u8path(srcPath), u8path(dstPath));
}
bool Delete(const std::string& path)
bool Delete(std::string_view path)
{
return platform_file_delete(path.c_str());
return fs::remove(u8path(path));
}
bool Move(const std::string& srcPath, const std::string& dstPath)
bool Move(std::string_view srcPath, std::string_view dstPath)
{
return platform_file_move(srcPath.c_str(), dstPath.c_str());
try
{
fs::rename(u8path(srcPath), u8path(dstPath));
return true;
}
catch (const fs::filesystem_error&)
{
return false;
}
}
std::vector<uint8_t> ReadAllBytes(std::string_view path)
@ -111,13 +127,13 @@ namespace File
return lines;
}
void WriteAllBytes(const std::string& path, const void* buffer, size_t length)
void WriteAllBytes(std::string_view path, const void* buffer, size_t length)
{
auto fs = OpenRCT2::FileStream(path, OpenRCT2::FILE_MODE_WRITE);
fs.Write(buffer, length);
}
uint64_t GetLastModified(const std::string& path)
uint64_t GetLastModified(std::string_view path)
{
return Platform::GetLastModified(path);
}
@ -127,16 +143,3 @@ namespace File
return Platform::GetFileSize(path);
}
} // namespace File
bool writeentirefile(const utf8* path, const void* buffer, size_t length)
{
try
{
File::WriteAllBytes(String::ToStd(path), buffer, length);
return true;
}
catch (const std::exception&)
{
return false;
}
}

View File

@ -17,14 +17,14 @@
namespace File
{
bool Exists(const std::string& path);
bool Copy(const std::string& srcPath, const std::string& dstPath, bool overwrite);
bool Delete(const std::string& path);
bool Move(const std::string& srcPath, const std::string& dstPath);
bool Exists(std::string_view path);
bool Copy(std::string_view srcPath, std::string_view dstPath, bool overwrite);
bool Delete(std::string_view path);
bool Move(std::string_view srcPath, std::string_view dstPath);
std::vector<uint8_t> ReadAllBytes(std::string_view path);
std::string ReadAllText(std::string_view path);
std::vector<std::string> ReadAllLines(std::string_view path);
void WriteAllBytes(const std::string& path, const void* buffer, size_t length);
uint64_t GetLastModified(const std::string& path);
void WriteAllBytes(std::string_view path, const void* buffer, size_t length);
uint64_t GetLastModified(std::string_view path);
uint64_t GetSize(std::string_view path);
} // namespace File

View File

@ -110,7 +110,7 @@ namespace OpenRCT2
_fileSize = _filelengthi64(_fileno(_file));
#else
std::error_code ec;
_fileSize = fs::file_size(fs::u8path(path), ec);
_fileSize = fs::file_size(u8path(path), ec);
#endif
_ownsFilePtr = true;

View File

@ -57,3 +57,9 @@ namespace fs = ghc::filesystem;
#endif
#undef HAVE_STD_FILESYSTEM // Not needed any more, don't make it public.
#ifdef __ANDROID__
# define u8path(path) fs::u8path(std::string(path))
#else
# define u8path(path) fs::u8path(path)
#endif

View File

@ -54,135 +54,34 @@ namespace Path
return std::string(a) + PATH_SEPARATOR + std::string(b);
}
std::string GetDirectory(const std::string& path)
std::string GetDirectory(std::string_view path)
{
const utf8* directory = GetDirectory(path.c_str());
std::string result(directory);
Memory::Free(directory);
return result;
return u8path(path).parent_path().string();
}
utf8* GetDirectory(const utf8* path)
void CreateDirectory(std::string_view path)
{
size_t maxSize = String::SizeOf(path) + 1;
utf8* result = Memory::Allocate<utf8>(maxSize);
GetDirectory(result, maxSize, path);
size_t reducedSize = String::SizeOf(path) + 1;
result = Memory::Reallocate(result, reducedSize);
return result;
platform_ensure_directory_exists(std::string(path).c_str());
}
utf8* GetDirectory(utf8* buffer, size_t bufferSize, const utf8* path)
bool DirectoryExists(std::string_view path)
{
auto lastPathSepIndex = std::max(String::LastIndexOf(path, *PATH_SEPARATOR), String::LastIndexOf(path, '/'));
if (lastPathSepIndex < 0)
{
return String::Set(buffer, bufferSize, String::Empty);
}
size_t copyLength = std::min(lastPathSepIndex, static_cast<ptrdiff_t>(bufferSize - 1));
std::copy_n(path, copyLength, buffer);
buffer[copyLength] = '\0';
return buffer;
return fs::is_directory(u8path(path));
}
void CreateDirectory(const std::string& path)
std::string GetFileName(std::string_view path)
{
platform_ensure_directory_exists(path.c_str());
return u8path(path).filename().string();
}
bool DirectoryExists(const std::string& path)
std::string GetFileNameWithoutExtension(std::string_view path)
{
return platform_directory_exists(path.c_str());
return u8path(path).stem().string();
}
std::string GetFileName(const std::string& path)
std::string GetExtension(std::string_view path)
{
return GetFileName(path.c_str());
}
const utf8* GetFileName(const utf8* path)
{
const utf8* lastPathSeparator = nullptr;
for (const utf8* ch = path; *ch != '\0'; ch++)
{
if (*ch == *PATH_SEPARATOR || *ch == '/')
{
lastPathSeparator = ch;
}
}
return lastPathSeparator == nullptr ? path : lastPathSeparator + 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;
utf8* result = Memory::Allocate<utf8>(maxSize);
GetFileNameWithoutExtension(result, maxSize, path);
size_t reducedSize = String::SizeOf(path) + 1;
result = Memory::Reallocate(result, reducedSize);
return result;
}
utf8* GetFileNameWithoutExtension(utf8* buffer, size_t bufferSize, const utf8* path)
{
path = GetFileName(path);
const utf8* lastDot = nullptr;
const utf8* ch = path;
for (; *ch != '\0'; ch++)
{
if (*ch == '.')
{
lastDot = ch;
}
}
if (lastDot == nullptr)
{
return String::Set(buffer, bufferSize, path);
}
size_t truncatedLength = std::min<size_t>(bufferSize - 1, lastDot - path);
std::copy_n(path, truncatedLength, buffer);
buffer[truncatedLength] = '\0';
return buffer;
}
const std::string GetExtension(const std::string& path)
{
return fs::u8path(path).extension().string();
}
const utf8* GetExtension(const utf8* path)
{
const utf8* lastDot = nullptr;
const utf8* ch = GetFileName(path);
for (; *ch != '\0'; ch++)
{
if (*ch == '.')
{
lastDot = ch;
}
}
if (lastDot == nullptr)
{
// Return the null terminator, i.e. a blank extension
return ch;
}
// Return the extension including the dot
return lastDot;
return u8path(path).extension().string();
}
utf8* GetAbsolute(utf8* buffer, size_t bufferSize, const utf8* relativePath)
@ -190,23 +89,18 @@ namespace Path
return Platform::GetAbsolutePath(buffer, bufferSize, relativePath);
}
std::string GetAbsolute(const std::string& relative)
std::string GetAbsolute(std::string_view relative)
{
utf8 absolute[MAX_PATH];
return GetAbsolute(absolute, sizeof(absolute), relative.c_str());
return GetAbsolute(absolute, sizeof(absolute), std::string(relative).c_str());
}
bool Equals(const std::string& a, const std::string& b)
{
return String::Equals(a.c_str(), b.c_str());
}
bool Equals(const utf8* a, const utf8* b)
bool Equals(std::string_view a, std::string_view b)
{
return String::Equals(a, b, Platform::ShouldIgnoreCase());
}
std::string ResolveCasing(const std::string& path)
std::string ResolveCasing(std::string_view path)
{
return Platform::ResolveCasing(path, File::Exists(path));
}

View File

@ -23,22 +23,15 @@ namespace Path
return Combine(a, Combine(b, args...));
}
std::string GetDirectory(const std::string& path);
utf8* GetDirectory(const utf8* path);
utf8* GetDirectory(utf8* buffer, size_t bufferSize, const utf8* path);
void CreateDirectory(const std::string& path);
bool DirectoryExists(const std::string& path);
std::string GetFileName(const std::string& 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 std::string GetExtension(const std::string& path);
const utf8* GetExtension(const utf8* path);
std::string GetDirectory(std::string_view path);
void CreateDirectory(std::string_view path);
bool DirectoryExists(std::string_view path);
std::string GetFileName(std::string_view origPath);
std::string GetFileNameWithoutExtension(std::string_view path);
std::string GetExtension(std::string_view path);
utf8* GetAbsolute(utf8* buffer, size_t bufferSize, const utf8* relativePath);
std::string GetAbsolute(const std::string& relative);
bool Equals(const std::string& a, const std::string& b);
bool Equals(const utf8* a, const utf8* b);
std::string GetAbsolute(std::string_view relative);
bool Equals(std::string_view a, std::string_view b);
/**
* Checks if the given path is a file. If not, checks to see if
@ -46,5 +39,5 @@ namespace Path
* one found based on a straight forward character sort.
* Note: This will not resolve the case for Windows.
*/
std::string ResolveCasing(const std::string& path);
std::string ResolveCasing(std::string_view path);
} // namespace Path

View File

@ -17,6 +17,7 @@
#include "../actions/SetCheatAction.h"
#include "../audio/audio.h"
#include "../core/Console.hpp"
#include "../core/File.h"
#include "../core/Imaging.h"
#include "../drawing/Drawing.h"
#include "../drawing/X8DrawingEngine.h"
@ -147,7 +148,7 @@ static std::optional<std::string> screenshot_get_next_path()
for (int tries = 0; tries < 100; tries++)
{
auto path = pathComposer(tries);
if (!Platform::FileExists(path))
if (!File::Exists(path))
{
return path;
}
@ -769,7 +770,7 @@ static std::string ResolveFilenameForCapture(const fs::path& filename)
return *path;
}
auto screenshotDirectory = fs::u8path(screenshot_get_directory());
auto screenshotDirectory = u8path(screenshot_get_directory());
auto screenshotPath = fs::absolute(screenshotDirectory / filename);
// Check the filename isn't attempting to leave the screenshot directory for security

View File

@ -17,6 +17,7 @@
#include "../actions/LoadOrQuitAction.h"
#include "../actions/NetworkModifyGroupAction.h"
#include "../actions/PeepPickupAction.h"
#include "../core/File.h"
#include "../core/Guard.hpp"
#include "../core/Json.hpp"
#include "../entity/EntityList.h"
@ -277,7 +278,7 @@ bool NetworkBase::BeginClient(const std::string& host, uint16_t port)
utf8 keyPath[MAX_PATH];
network_get_private_key_path(keyPath, sizeof(keyPath), gConfigNetwork.player_name);
if (!Platform::FileExists(keyPath))
if (!File::Exists(keyPath))
{
Console::WriteLine("Generating key... This may take a while");
Console::WriteLine("Need to collect enough entropy from the system");
@ -1016,7 +1017,7 @@ void NetworkBase::LoadGroups()
safe_strcat_path(path, "groups.json", sizeof(path));
json_t jsonGroupConfig;
if (Platform::FileExists(path))
if (File::Exists(path))
{
try
{
@ -2127,7 +2128,7 @@ void NetworkBase::Client_Handle_TOKEN(NetworkConnection& connection, NetworkPack
{
utf8 keyPath[MAX_PATH];
network_get_private_key_path(keyPath, sizeof(keyPath), gConfigNetwork.player_name);
if (!Platform::FileExists(keyPath))
if (!File::Exists(keyPath))
{
log_error("Key file (%s) was not found. Restart client to re-generate it.", keyPath);
return;
@ -3842,7 +3843,7 @@ void network_send_password(const std::string& password)
auto& network = OpenRCT2::GetContext()->GetNetwork();
utf8 keyPath[MAX_PATH];
network_get_private_key_path(keyPath, sizeof(keyPath), gConfigNetwork.player_name);
if (!Platform::FileExists(keyPath))
if (!File::Exists(keyPath))
{
log_error("Private key %s missing! Restart the game to generate it.", keyPath);
return;

View File

@ -12,6 +12,7 @@
# include "NetworkUser.h"
# include "../core/Console.hpp"
# include "../core/File.h"
# include "../core/Guard.hpp"
# include "../core/Json.hpp"
# include "../core/Path.hpp"
@ -80,7 +81,7 @@ void NetworkUserManager::Load()
utf8 path[MAX_PATH];
GetStorePath(path, sizeof(path));
if (Platform::FileExists(path))
if (File::Exists(path))
{
DisposeUsers();
@ -114,7 +115,7 @@ void NetworkUserManager::Save()
json_t jsonUsers;
try
{
if (Platform::FileExists(path))
if (File::Exists(path))
{
jsonUsers = Json::ReadFromFile(path);
}

View File

@ -14,6 +14,7 @@
# include "../Context.h"
# include "../PlatformEnvironment.h"
# include "../config/Config.h"
# include "../core/File.h"
# include "../core/FileStream.h"
# include "../core/Guard.hpp"
# include "../core/Http.h"
@ -162,7 +163,7 @@ std::vector<ServerListEntry> ServerList::ReadFavourites() const
{
auto env = GetContext()->GetPlatformEnvironment();
auto path = env->GetFilePath(PATHID::NETWORK_SERVERS);
if (Platform::FileExists(path))
if (File::Exists(path))
{
auto fs = FileStream(path, FILE_MODE_OPEN);
auto numEntries = fs.ReadValue<uint32_t>();

View File

@ -25,6 +25,8 @@
# include <fontconfig/fontconfig.h>
# endif // NO_TTF
# include "../config/Config.h"
# include "../core/File.h"
# include "../core/Path.hpp"
# include "../localisation/Language.h"
# include "../localisation/StringIds.h"
# include "../util/Util.h"
@ -70,7 +72,7 @@ bool platform_get_steam_path(utf8* outPath, size_t outSize)
{
safe_strcpy(steamPath, localSharePath, sizeof(steamPath));
safe_strcat_path(steamPath, "Steam/ubuntu12_32/steamapps/content", sizeof(steamPath));
if (platform_directory_exists(steamPath))
if (Path::DirectoryExists(steamPath))
{
safe_strcpy(outPath, steamPath, outSize);
return true;
@ -82,7 +84,7 @@ bool platform_get_steam_path(utf8* outPath, size_t outSize)
{
safe_strcpy(steamPath, homeDir, sizeof(steamPath));
safe_strcat_path(steamPath, ".local/share/Steam/ubuntu12_32/steamapps/content", sizeof(steamPath));
if (platform_directory_exists(steamPath))
if (Path::DirectoryExists(steamPath))
{
safe_strcpy(outPath, steamPath, outSize);
return true;
@ -91,7 +93,7 @@ bool platform_get_steam_path(utf8* outPath, size_t outSize)
std::fill_n(steamPath, sizeof(steamPath), 0x00);
safe_strcpy(steamPath, homeDir, sizeof(steamPath));
safe_strcat_path(steamPath, ".steam/steam/ubuntu12_32/steamapps/content", sizeof(steamPath));
if (platform_directory_exists(steamPath))
if (Path::DirectoryExists(steamPath))
{
safe_strcpy(outPath, steamPath, outSize);
return true;

View File

@ -63,7 +63,7 @@ namespace Platform
for (auto searchLocation : searchLocations)
{
log_verbose("Looking for OpenRCT2 doc path at %s", searchLocation);
if (platform_directory_exists(searchLocation))
if (Path::DirectoryExists(searchLocation))
{
return searchLocation;
}

View File

@ -16,6 +16,7 @@
# include "../core/String.hpp"
# include "Platform2.h"
# include <cerrno>
# include <clocale>
# include <cstdlib>
# include <cstring>
@ -24,6 +25,8 @@
# include <pwd.h>
# include <sys/stat.h>
# define FILE_BUFFER_SIZE 4096
namespace Platform
{
uint32_t GetTicks()
@ -31,9 +34,9 @@ namespace Platform
return platform_get_ticks();
}
std::string GetEnvironmentVariable(const std::string& name)
std::string GetEnvironmentVariable(std::string_view name)
{
return String::ToStd(getenv(name.c_str()));
return String::ToStd(getenv(std::string(name).c_str()));
}
std::string GetEnvironmentPath(const char* name)
@ -106,16 +109,16 @@ namespace Platform
return false;
}
bool FindApp(const std::string& app, std::string* output)
bool FindApp(std::string_view app, std::string* output)
{
return Execute(String::StdFormat("which %s 2> /dev/null", app.c_str()), output) == 0;
return Execute(String::StdFormat("which %s 2> /dev/null", std::string(app).c_str()), output) == 0;
}
int32_t Execute(const std::string& command, std::string* output)
int32_t Execute(std::string_view command, std::string* output)
{
# ifndef __EMSCRIPTEN__
log_verbose("executing \"%s\"...", command.c_str());
FILE* fpipe = popen(command.c_str(), "r");
log_verbose("executing \"%s\"...", std::string(command).c_str());
FILE* fpipe = popen(std::string(command).c_str(), "r");
if (fpipe == nullptr)
{
return -1;
@ -161,13 +164,13 @@ namespace Platform
# endif // __EMSCRIPTEN__
}
uint64_t GetLastModified(const std::string& path)
uint64_t GetLastModified(std::string_view path)
{
uint64_t lastModified = 0;
struct stat statInfo
{
};
if (stat(path.c_str(), &statInfo) == 0)
if (stat(std::string(path).c_str(), &statInfo) == 0)
{
lastModified = statInfo.st_mtime;
}
@ -210,7 +213,7 @@ namespace Platform
return buffer;
}
std::string ResolveCasing(const std::string& path, bool fileExists)
std::string ResolveCasing(std::string_view path, bool fileExists)
{
std::string result;
if (fileExists)

View File

@ -62,7 +62,7 @@ namespace Platform
return platform_get_ticks();
}
std::string GetEnvironmentVariable(const std::string& name)
std::string GetEnvironmentVariable(std::string_view name)
{
std::wstring result;
auto wname = String::ToWideChar(name);
@ -526,19 +526,19 @@ namespace Platform
return false;
}
bool FindApp(const std::string& app, std::string* output)
bool FindApp(std::string_view app, std::string* output)
{
log_warning("FindApp() not implemented for Windows!");
return false;
}
int32_t Execute(const std::string& command, std::string* output)
int32_t Execute(std::string_view command, std::string* output)
{
log_warning("Execute() not implemented for Windows!");
return -1;
}
uint64_t GetLastModified(const std::string& path)
uint64_t GetLastModified(std::string_view path)
{
uint64_t lastModified = 0;
auto pathW = String::ToWideChar(path);
@ -597,14 +597,14 @@ namespace Platform
return buffer;
}
std::string ResolveCasing(const std::string& path, bool fileExists)
std::string ResolveCasing(std::string_view path, bool fileExists)
{
std::string result;
if (fileExists)
{
// Windows is case insensitive so it will exist and that is all that matters
// for now. We can properly resolve the casing if we ever need to.
result = path;
result = std::string(path);
}
return result;
}

View File

@ -28,19 +28,19 @@ enum class SPECIAL_FOLDER
namespace Platform
{
uint32_t GetTicks();
std::string GetEnvironmentVariable(const std::string& name);
std::string GetEnvironmentVariable(std::string_view name);
std::string GetFolderPath(SPECIAL_FOLDER folder);
std::string GetInstallPath();
std::string GetDocsPath();
std::string GetCurrentExecutablePath();
std::string GetCurrentExecutableDirectory();
bool ShouldIgnoreCase();
bool FileExists(const std::string path);
bool IsPathSeparator(char c);
utf8* GetAbsolutePath(utf8* buffer, size_t bufferSize, const utf8* relativePath);
uint64_t GetLastModified(const std::string& path);
uint64_t GetLastModified(std::string_view path);
uint64_t GetFileSize(std::string_view path);
std::string ResolveCasing(const std::string& path, bool fileExists);
std::string ResolveCasing(std::string_view path, bool fileExists);
std::string SanitiseFilename(std::string_view originalName);
uint16_t GetLocaleLanguage();
CurrencyType GetLocaleCurrency();
@ -48,15 +48,13 @@ namespace Platform
rct2_time GetTimeLocal();
rct2_date GetDateLocal();
bool FindApp(const std::string& app, std::string* output);
int32_t Execute(const std::string& command, std::string* output = nullptr);
bool FindApp(std::string_view app, std::string* output);
int32_t Execute(std::string_view command, std::string* output = nullptr);
bool OriginalGameDataExists(std::string_view path);
std::string GetUsername();
std::string SanitiseFilename(std::string_view originalName);
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__)
std::string GetEnvironmentPath(const char* name);
std::string GetHomePath();

View File

@ -38,18 +38,8 @@
// The name of the mutex used to prevent multiple instances of the game from running
# define SINGLE_INSTANCE_MUTEX_NAME "openrct2.lock"
# define FILE_BUFFER_SIZE 4096
static utf8 _userDataDirectoryPath[MAX_PATH] = { 0 };
bool platform_directory_exists(const utf8* path)
{
struct stat dirinfo;
int32_t result = stat(path, &dirinfo);
log_verbose("checking dir %s, result = %d, is_dir = %d", path, result, S_ISDIR(dirinfo.st_mode));
return result == 0 && S_ISDIR(dirinfo.st_mode);
}
// Implement our own version of getumask(), as it is documented being
// "a vaporware GNU extension".
static mode_t openrct2_getumask()
@ -101,7 +91,7 @@ bool platform_ensure_directory_exists(const utf8* path)
bool platform_directory_delete(const utf8* path)
{
return fs::remove_all(fs::u8path(path)) > 0;
return fs::remove_all(u8path(path)) > 0;
}
std::string platform_get_absolute_path(const utf8* relative_path, const utf8* base_path)
@ -174,78 +164,6 @@ int32_t platform_get_drives()
return 0;
}
bool platform_file_copy(const utf8* srcPath, const utf8* dstPath, bool overwrite)
{
log_verbose("Copying %s to %s", srcPath, dstPath);
FILE* dstFile;
if (overwrite)
{
dstFile = fopen(dstPath, "wb");
}
else
{
// Portability note: check your libc's support for "wbx"
dstFile = fopen(dstPath, "wbx");
}
if (dstFile == nullptr)
{
if (errno == EEXIST)
{
log_warning("platform_file_copy: Not overwriting %s, because overwrite flag == false", dstPath);
return false;
}
log_error("Could not open destination file %s for copying", dstPath);
return false;
}
// Open both files and check whether they are opened correctly
FILE* srcFile = fopen(srcPath, "rb");
if (srcFile == nullptr)
{
fclose(dstFile);
log_error("Could not open source file %s for copying", srcPath);
return false;
}
size_t amount_read = 0;
size_t file_offset = 0;
// Copy file in FILE_BUFFER_SIZE-d chunks
char* buffer = static_cast<char*>(malloc(FILE_BUFFER_SIZE));
while ((amount_read = fread(buffer, FILE_BUFFER_SIZE, 1, srcFile)))
{
fwrite(buffer, amount_read, 1, dstFile);
file_offset += amount_read;
}
// Finish the left-over data from file, which may not be a full
// FILE_BUFFER_SIZE-d chunk.
fseek(srcFile, file_offset, SEEK_SET);
amount_read = fread(buffer, 1, FILE_BUFFER_SIZE, srcFile);
fwrite(buffer, amount_read, 1, dstFile);
fclose(srcFile);
fclose(dstFile);
free(buffer);
return true;
}
bool platform_file_move(const utf8* srcPath, const utf8* dstPath)
{
return rename(srcPath, dstPath) == 0;
}
bool platform_file_delete(const utf8* path)
{
int32_t ret = unlink(path);
return ret == 0;
}
time_t platform_file_get_modified_time(const utf8* path)
{
struct stat buf;

View File

@ -19,6 +19,7 @@
#include "../Game.h"
#include "../OpenRCT2.h"
#include "../config/Config.h"
#include "../core/File.h"
#include "../core/FileSystem.hpp"
#include "../core/Path.hpp"
#include "../core/String.hpp"
@ -113,17 +114,10 @@ namespace Platform
return outTime;
}
bool FileExists(const std::string path)
{
fs::path file = fs::u8path(path);
log_verbose("Checking if file exists: %s", path.c_str());
return fs::exists(file);
}
bool OriginalGameDataExists(std::string_view path)
{
std::string combinedPath = Path::ResolveCasing(Path::Combine(path, "Data", "g1.dat"));
return Platform::FileExists(combinedPath);
return File::Exists(combinedPath);
}
std::string SanitiseFilename(std::string_view originalName)

View File

@ -25,6 +25,7 @@
# include "../OpenRCT2.h"
# include "../Version.h"
# include "../config/Config.h"
# include "../core/Path.hpp"
# include "../core/String.hpp"
# include "../localisation/Date.h"
# include "../localisation/Language.h"
@ -59,16 +60,9 @@
# define swprintf_s(a, b, c, d, ...) swprintf(a, b, c, ##__VA_ARGS__)
# endif
bool platform_directory_exists(const utf8* path)
{
auto wPath = String::ToWideChar(path);
DWORD dwAttrib = GetFileAttributesW(wPath.c_str());
return dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
bool platform_ensure_directory_exists(const utf8* path)
{
if (platform_directory_exists(path))
if (Path::DirectoryExists(path))
return 1;
auto wPath = String::ToWideChar(path);
@ -122,29 +116,6 @@ int32_t platform_get_drives()
return GetLogicalDrives();
}
bool platform_file_copy(const utf8* srcPath, const utf8* dstPath, bool overwrite)
{
auto wSrcPath = String::ToWideChar(srcPath);
auto wDstPath = String::ToWideChar(dstPath);
auto success = CopyFileW(wSrcPath.c_str(), wDstPath.c_str(), overwrite ? FALSE : TRUE);
return success != FALSE;
}
bool platform_file_move(const utf8* srcPath, const utf8* dstPath)
{
auto wSrcPath = String::ToWideChar(srcPath);
auto wDstPath = String::ToWideChar(dstPath);
auto success = MoveFileW(wSrcPath.c_str(), wDstPath.c_str());
return success != FALSE;
}
bool platform_file_delete(const utf8* path)
{
auto wPath = String::ToWideChar(path);
auto success = DeleteFileW(wPath.c_str());
return success != FALSE;
}
bool platform_get_steam_path(utf8* outPath, size_t outSize)
{
wchar_t* wSteamPath;

View File

@ -10,6 +10,7 @@
#if defined(__APPLE__) && defined(__MACH__)
# include "../config/Config.h"
# include "../core/Path.hpp"
# include "../localisation/Language.h"
# include "../util/Util.h"
# include "platform.h"
@ -69,7 +70,7 @@ bool platform_get_steam_path(utf8* outPath, size_t outSize)
safe_strcpy(steamPath, homeDir, sizeof(steamPath));
safe_strcat_path(
steamPath, "Library/Application Support/Steam/Steam.AppBundle/Steam/Contents/MacOS/steamapps", sizeof(steamPath));
if (platform_directory_exists(steamPath))
if (Path::DirectoryExists(steamPath))
{
safe_strcpy(outPath, steamPath, outSize);
return true;

View File

@ -87,7 +87,6 @@ void platform_toggle_windowed_mode();
void platform_refresh_video(bool recreate_window);
// Platform specific definitions
bool platform_directory_exists(const utf8* path);
time_t platform_file_get_modified_time(const utf8* path);
bool platform_ensure_directory_exists(const utf8* path);
bool platform_directory_delete(const utf8* path);
@ -96,10 +95,6 @@ bool platform_lock_single_instance();
// Returns the bitmask of the GetLogicalDrives function for windows, 0 for other systems
int32_t platform_get_drives();
bool platform_file_copy(const utf8* srcPath, const utf8* dstPath, bool overwrite);
bool platform_file_move(const utf8* srcPath, const utf8* dstPath);
bool platform_file_delete(const utf8* path);
uint32_t platform_get_ticks();
void platform_sleep(uint32_t ms);
void platform_get_user_directory(utf8* outPath, const utf8* subDirectory, size_t outSize);

View File

@ -129,7 +129,7 @@ namespace RCT1
public:
ParkLoadResult Load(const utf8* path) override
{
const utf8* extension = Path::GetExtension(path);
const auto extension = Path::GetExtension(path);
if (String::Equals(extension, ".sc4", true))
{
return LoadScenario(path);

View File

@ -40,7 +40,7 @@ namespace RCT1
bool Load(const utf8* path) override
{
const utf8* extension = Path::GetExtension(path);
const auto extension = Path::GetExtension(path);
if (String::Equals(extension, ".td4", true))
{
_name = GetNameFromTrackPath(path);

View File

@ -105,7 +105,7 @@ namespace RCT2
ParkLoadResult Load(const utf8* path) override
{
const utf8* extension = Path::GetExtension(path);
const auto extension = Path::GetExtension(path);
if (String::Equals(extension, ".sc6", true))
{
return LoadScenario(path);
@ -408,7 +408,7 @@ namespace RCT2
if (_s6.header.type == S6_TYPE_SCENARIO)
{
// _s6.scenario_filename is wrong for some RCT2 expansion scenarios, so we use the real filename
gScenarioFileName = String::ToStd(Path::GetFileName(_s6Path));
gScenarioFileName = Path::GetFileName(_s6Path);
}
else
{

View File

@ -44,7 +44,7 @@ namespace RCT2
bool Load(const utf8* path) override
{
const utf8* extension = Path::GetExtension(path);
const auto extension = Path::GetExtension(path);
if (String::Equals(extension, ".td6", true))
{
_name = GetNameFromTrackPath(path);

View File

@ -176,7 +176,7 @@ private:
{
if (String::Equals(Path::GetExtension(path), ".sea", true))
{
auto data = DecryptSea(fs::u8path(path));
auto data = DecryptSea(u8path(path));
auto ms = std::make_unique<MemoryStream>();
// Need to copy the data into MemoryStream as the overload will borrow instead of copy.
ms->Write(data.data(), data.size());
@ -285,7 +285,7 @@ private:
if (String::IsNullOrEmpty(s6Info->name))
{
// If the scenario doesn't have a name, set it to the filename
String::Set(entry.name, sizeof(entry.name), Path::GetFileNameWithoutExtension(entry.path));
String::Set(entry.name, sizeof(entry.name), Path::GetFileNameWithoutExtension(entry.path).c_str());
}
else
{
@ -387,7 +387,7 @@ public:
{
for (const auto& scenario : _scenarios)
{
const utf8* scenarioFilename = Path::GetFileName(scenario.path);
const auto scenarioFilename = Path::GetFileName(scenario.path);
// Note: this is always case insensitive search for cross platform consistency
if (String::Equals(filename, scenarioFilename, true))
@ -439,8 +439,8 @@ public:
// Check if this is an RCTC scenario that corresponds to a known RCT1/2 scenario or vice versa, see #12626
if (scenario == nullptr)
{
const std::string scenarioBaseName = String::ToStd(Path::GetFileNameWithoutExtension(scenarioFileName));
const std::string scenarioExtension = String::ToStd(Path::GetExtension(scenarioFileName));
const std::string scenarioBaseName = Path::GetFileNameWithoutExtension(scenarioFileName);
const std::string scenarioExtension = Path::GetExtension(scenarioFileName);
if (String::Equals(scenarioExtension, ".sea", true))
{
@ -550,7 +550,7 @@ private:
if (!String::Equals(filename, ""))
{
auto existingEntry = GetByFilename(filename);
auto existingEntry = GetByFilename(filename.c_str());
if (existingEntry != nullptr)
{
std::string conflictPath;
@ -601,7 +601,7 @@ private:
void LoadScores()
{
std::string path = _env->GetFilePath(PATHID::SCORES);
if (!Platform::FileExists(path))
if (!File::Exists(path))
{
return;
}
@ -648,7 +648,7 @@ private:
void LoadLegacyScores(const std::string& path)
{
if (!Platform::FileExists(path))
if (!File::Exists(path))
{
return;
}

View File

@ -64,7 +64,7 @@ namespace OpenRCT2::Scripting
try
{
CaptureOptions captureOptions;
captureOptions.Filename = fs::u8path(AsOrDefault(options["filename"], ""));
captureOptions.Filename = u8path(AsOrDefault(options["filename"], ""));
captureOptions.Rotation = options["rotation"].as_int() & 3;
captureOptions.Zoom = ZoomLevel(options["zoom"].as_int());
captureOptions.Transparent = AsOrDefault(options["transparent"], false);

View File

@ -87,7 +87,7 @@ std::unique_ptr<TitleSequence> LoadTitleSequence(const std::string& path)
auto commands = LegacyScriptRead(script, saves);
auto seq = CreateTitleSequence();
seq->Name = Path::GetFileNameWithoutExtension(std::string(path));
seq->Name = Path::GetFileNameWithoutExtension(path);
seq->Path = path;
seq->Saves = saves;
seq->Commands = commands;

View File

@ -13,6 +13,7 @@
#include "../OpenRCT2.h"
#include "../PlatformEnvironment.h"
#include "../core/Collections.hpp"
#include "../core/File.h"
#include "../core/FileScanner.h"
#include "../core/Memory.hpp"
#include "../core/Path.hpp"
@ -85,7 +86,7 @@ namespace TitleSequenceManager
const utf8* path = item->Path.c_str();
if (item->IsZip)
{
platform_file_delete(path);
File::Delete(path);
}
else
{
@ -103,11 +104,11 @@ namespace TitleSequenceManager
if (item->IsZip)
{
newPath += TITLE_SEQUENCE_EXTENSION;
platform_file_move(oldPath.c_str(), newPath.c_str());
File::Move(oldPath, newPath);
}
else
{
platform_file_move(oldPath.c_str(), newPath.c_str());
File::Move(oldPath, newPath);
}
item->Name = newName;
@ -124,7 +125,7 @@ namespace TitleSequenceManager
const auto& srcPath = item->Path;
std::string dstPath = GetNewTitleSequencePath(std::string(name), item->IsZip);
if (!platform_file_copy(srcPath.c_str(), dstPath.c_str(), true))
if (!File::Copy(srcPath, dstPath, true))
{
return SIZE_MAX;
}
@ -273,7 +274,7 @@ namespace TitleSequenceManager
{
for (const auto& pseq : TitleSequenceManager::PredefinedSequences)
{
auto predefinedName = Path::GetFileNameWithoutExtension(std::string(pseq.Filename));
auto predefinedName = Path::GetFileNameWithoutExtension(pseq.Filename);
if (String::Equals(name, predefinedName, true))
{
return true;

View File

@ -31,7 +31,6 @@ void path_set_extension(utf8* path, const utf8* newExtension, size_t size);
void path_append_extension(utf8* path, const utf8* newExtension, size_t size);
void path_remove_extension(utf8* path);
void path_end_with_separator(utf8* path, size_t size);
bool writeentirefile(const utf8* path, const void* buffer, size_t length);
bool sse41_available();
bool avx2_available();