Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use u8string in Path/File; replace Path::Append with Path::Combine #16521

Merged
merged 2 commits into from Jan 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/openrct2/Context.cpp
Expand Up @@ -779,10 +779,9 @@ namespace OpenRCT2
"install directory does not exist or invalid directory selected, %s", gConfigGeneral.rct2_path.c_str());
if (!config_find_or_browse_install_directory())
{
utf8 path[MAX_PATH];
config_get_default_path(path, sizeof(path));
auto path = config_get_default_path();
Console::Error::WriteLine(
"An RCT2 install directory must be specified! Please edit \"game_path\" in %s.\n", path);
"An RCT2 install directory must be specified! Please edit \"game_path\" in %s.\n", path.c_str());
return std::string();
}
}
Expand Down
9 changes: 3 additions & 6 deletions src/openrct2/cmdline/RootCommands.cpp
Expand Up @@ -356,14 +356,11 @@ static exitcode_t HandleCommandSetRCT2(CommandLineArgEnumerator* enumerator)
// Check if g1.dat exists (naive but good check)
Console::WriteLine("Checking g1.dat...");

utf8 pathG1Check[MAX_PATH];
String::Set(pathG1Check, sizeof(pathG1Check), path.c_str());
Path::Append(pathG1Check, sizeof(pathG1Check), "Data");
Path::Append(pathG1Check, sizeof(pathG1Check), "g1.dat");
auto pathG1Check = Path::Combine(path, "Data", "g1.dat");
if (!File::Exists(pathG1Check))
{
Console::Error::WriteLine("RCT2 path not valid.");
Console::Error::WriteLine("Unable to find %s.", pathG1Check);
Console::Error::WriteLine("Unable to find %s.", pathG1Check.c_str());
return EXITCODE_FAIL;
}

Expand All @@ -372,7 +369,7 @@ static exitcode_t HandleCommandSetRCT2(CommandLineArgEnumerator* enumerator)
auto configPath = env->GetFilePath(OpenRCT2::PATHID::CONFIG);
config_set_defaults();
config_open(configPath.c_str());
gConfigGeneral.rct2_path = std::string(path);
gConfigGeneral.rct2_path = path;
if (config_save(configPath.c_str()))
{
Console::WriteFormat("Updating RCT2 path to '%s'.", path.c_str());
Expand Down
11 changes: 5 additions & 6 deletions src/openrct2/config/Config.cpp
Expand Up @@ -802,17 +802,16 @@ void config_release()
SafeFree(gConfigFonts.font_name);
}

void config_get_default_path(utf8* outPath, size_t size)
u8string config_get_default_path()
{
platform_get_user_directory(outPath, nullptr, size);
Path::Append(outPath, size, "config.ini");
auto env = GetContext()->GetPlatformEnvironment();
return Path::Combine(env->GetDirectoryPath(DIRBASE::USER), "config.ini");
}

bool config_save_default()
{
utf8 path[MAX_PATH];
config_get_default_path(path, sizeof(path));
return config_save(path);
auto path = config_get_default_path();
return config_save(path.c_str());
}

bool config_find_or_browse_install_directory()
Expand Down
2 changes: 1 addition & 1 deletion src/openrct2/config/Config.h
Expand Up @@ -248,7 +248,7 @@ extern PluginConfiguration gConfigPlugin;

bool config_open(const utf8* path);
bool config_save(const utf8* path);
void config_get_default_path(utf8* outPath, size_t size);
u8string config_get_default_path();
void config_set_defaults();
void config_release();
bool config_save_default();
Expand Down
41 changes: 18 additions & 23 deletions src/openrct2/core/File.cpp
Expand Up @@ -23,20 +23,20 @@

namespace File
{
bool Exists(std::string_view path)
bool Exists(u8string_view path)
{
fs::path file = u8path(path);
log_verbose("Checking if file exists: %s", std::string(path).c_str());
log_verbose("Checking if file exists: %s", u8string(path).c_str());
std::error_code ec;
const auto result = fs::exists(file, ec);
return result && ec.value() == 0;
}

bool Copy(std::string_view srcPath, std::string_view dstPath, bool overwrite)
bool Copy(u8string_view srcPath, u8string_view dstPath, bool overwrite)
{
if (!overwrite && Exists(dstPath))
{
log_warning("File::Copy(): Not overwriting %s, because overwrite flag == false", std::string(dstPath).c_str());
log_warning("File::Copy(): Not overwriting %s, because overwrite flag == false", u8string(dstPath).c_str());
return false;
}

Expand All @@ -45,39 +45,34 @@ namespace File
return result && ec.value() == 0;
}

bool Delete(std::string_view path)
bool Delete(u8string_view path)
{
std::error_code ec;
const auto result = fs::remove(u8path(path), ec);
return result && ec.value() == 0;
}

bool Move(std::string_view srcPath, std::string_view dstPath)
bool Move(u8string_view srcPath, u8string_view dstPath)
{
std::error_code ec;
fs::rename(u8path(srcPath), u8path(dstPath), ec);
return ec.value() == 0;
}

std::vector<uint8_t> ReadAllBytes(std::string_view path)
std::vector<uint8_t> ReadAllBytes(u8string_view path)
{
#if defined(_WIN32) && !defined(__MINGW32__)
auto pathW = String::ToWideChar(path);
std::ifstream fs(pathW, std::ios::in | std::ios::binary);
#else
std::ifstream fs(std::string(path), std::ios::in | std::ios::binary);
#endif
std::ifstream fs(u8path(u8string(path)), std::ios::in | std::ios::binary);
if (!fs.is_open())
{
throw IOException("Unable to open " + std::string(path));
throw IOException("Unable to open " + u8string(path));
}

std::vector<uint8_t> result;
auto fsize = Platform::GetFileSize(path);
if (fsize > SIZE_MAX)
{
std::string message = String::StdFormat(
"'%s' exceeds maximum length of %lld bytes.", std::string(path).c_str(), SIZE_MAX);
u8string message = String::StdFormat(
"'%s' exceeds maximum length of %lld bytes.", u8string(path).c_str(), SIZE_MAX);
throw IOException(message);
}
else
Expand All @@ -89,18 +84,18 @@ namespace File
return result;
}

std::string ReadAllText(std::string_view path)
u8string ReadAllText(u8string_view path)
{
auto bytes = ReadAllBytes(path);
// TODO skip BOM
std::string result(bytes.size(), 0);
u8string result(bytes.size(), 0);
std::copy(bytes.begin(), bytes.end(), result.begin());
return result;
}

std::vector<std::string> ReadAllLines(std::string_view path)
std::vector<u8string> ReadAllLines(u8string_view path)
{
std::vector<std::string> lines;
std::vector<u8string> lines;
auto data = ReadAllBytes(path);
auto lineStart = reinterpret_cast<const char*>(data.data());
auto ch = lineStart;
Expand All @@ -127,18 +122,18 @@ namespace File
return lines;
}

void WriteAllBytes(std::string_view path, const void* buffer, size_t length)
void WriteAllBytes(u8string_view path, const void* buffer, size_t length)
{
auto fs = OpenRCT2::FileStream(path, OpenRCT2::FILE_MODE_WRITE);
fs.Write(buffer, length);
}

uint64_t GetLastModified(std::string_view path)
uint64_t GetLastModified(u8string_view path)
{
return Platform::GetLastModified(path);
}

uint64_t GetSize(std::string_view path)
uint64_t GetSize(u8string_view path)
{
return Platform::GetFileSize(path);
}
Expand Down
21 changes: 11 additions & 10 deletions src/openrct2/core/File.h
Expand Up @@ -10,21 +10,22 @@
#pragma once

#include "../common.h"
#include "../core/String.hpp"

#include <string>
#include <string_view>
#include <vector>

namespace File
{
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(std::string_view path, const void* buffer, size_t length);
uint64_t GetLastModified(std::string_view path);
uint64_t GetSize(std::string_view path);
bool Exists(u8string_view path);
bool Copy(u8string_view srcPath, u8string_view dstPath, bool overwrite);
bool Delete(u8string_view path);
bool Move(u8string_view srcPath, u8string_view dstPath);
std::vector<uint8_t> ReadAllBytes(u8string_view path);
u8string ReadAllText(u8string_view path);
std::vector<u8string> ReadAllLines(u8string_view path);
void WriteAllBytes(u8string_view path, const void* buffer, size_t length);
uint64_t GetLastModified(u8string_view path);
uint64_t GetSize(u8string_view path);
} // namespace File
18 changes: 5 additions & 13 deletions src/openrct2/core/FileScanner.cpp
Expand Up @@ -141,17 +141,14 @@ class FileScannerBase : public IFileScanner
{
if (_recurse)
{
utf8 childPath[MAX_PATH];
String::Set(childPath, sizeof(childPath), state->Path.c_str());
Path::Append(childPath, sizeof(childPath), child->Name.c_str());

auto childPath = Path::Combine(state->Path, child->Name);
PushState(childPath);
}
}
else if (PatternMatch(child->Name))
{
String::Set(_currentPath, MAX_PATH, state->Path.c_str());
Path::Append(_currentPath, MAX_PATH, child->Name.c_str());
auto path = Path::Combine(state->Path, child->Name);
String::Set(_currentPath, MAX_PATH, path.c_str());

_currentFileInfo->Name = child->Name.c_str();
_currentFileInfo->Size = child->Size;
Expand Down Expand Up @@ -315,15 +312,12 @@ class FileScannerUnix final : public FileScannerBase
result.Type = DIRECTORY_CHILD_TYPE::DC_FILE;

// Get the full path of the file
size_t pathSize = String::SizeOf(directory) + 1 + String::SizeOf(node->d_name) + 1;
utf8* path = Memory::Allocate<utf8>(pathSize);
String::Set(path, pathSize, directory);
Path::Append(path, pathSize, node->d_name);
auto path = Path::Combine(directory, node->d_name);

struct stat statInfo
{
};
int32_t statRes = stat(path, &statInfo);
int32_t statRes = stat(path.c_str(), &statInfo);
if (statRes != -1)
{
result.Size = statInfo.st_size;
Expand All @@ -334,8 +328,6 @@ class FileScannerUnix final : public FileScannerBase
result.Type = DIRECTORY_CHILD_TYPE::DC_DIRECTORY;
}
}

Memory::Free(path);
}
return result;
}
Expand Down
41 changes: 18 additions & 23 deletions src/openrct2/core/Path.cpp
Expand Up @@ -23,86 +23,81 @@

namespace Path
{
utf8* Append(utf8* buffer, size_t bufferSize, const utf8* src)
{
return safe_strcat_path(buffer, src, bufferSize);
}

std::string Combine(std::string_view a, std::string_view b)
u8string Combine(u8string_view a, u8string_view b)
{
if (a.empty())
return std::string(b);
return u8string(b);
if (b.empty())
return std::string(a);
return u8string(a);
auto aEnd = a.back();
auto bBegin = b.front();
if (Platform::IsPathSeparator(aEnd))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Future refactor to replace this function with return (fs::path(u8path(a)) / fs::path(u8path(b))).u8string()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm just reading all the in's and out's of fs::path /operator and it might not be as simple as that. Will need to check all calling sites to ensure above change makes sense.

{
if (Platform::IsPathSeparator(bBegin))
{
return std::string(a) + std::string(b.substr(1));
return u8string(a) + u8string(b.substr(1));
}

return std::string(a) + std::string(b);
return u8string(a) + u8string(b);
}

if (Platform::IsPathSeparator(bBegin))
{
return std::string(a) + std::string(b);
return u8string(a) + u8string(b);
}

return std::string(a) + PATH_SEPARATOR + std::string(b);
return u8string(a) + PATH_SEPARATOR + u8string(b);
}

std::string GetDirectory(std::string_view path)
u8string GetDirectory(u8string_view path)
{
return u8path(path).parent_path().u8string();
}

void CreateDirectory(std::string_view path)
void CreateDirectory(u8string_view path)
{
platform_ensure_directory_exists(std::string(path).c_str());
platform_ensure_directory_exists(u8string(path).c_str());
}

bool DirectoryExists(std::string_view path)
bool DirectoryExists(u8string_view path)
{
std::error_code ec;
const auto result = fs::is_directory(u8path(path), ec);
return result && ec.value() == 0;
}

std::string GetFileName(std::string_view path)
u8string GetFileName(u8string_view path)
{
return u8path(path).filename().u8string();
}

std::string GetFileNameWithoutExtension(std::string_view path)
u8string GetFileNameWithoutExtension(u8string_view path)
{
return u8path(path).stem().u8string();
}

std::string GetExtension(std::string_view path)
u8string GetExtension(u8string_view path)
{
return u8path(path).extension().u8string();
}

std::string GetAbsolute(std::string_view relative)
u8string GetAbsolute(u8string_view relative)
{
std::error_code ec;
return fs::absolute(u8path(relative), ec).u8string();
}

bool Equals(std::string_view a, std::string_view b)
bool Equals(u8string_view a, u8string_view b)
{
return String::Equals(a, b, Platform::ShouldIgnoreCase());
}

std::string ResolveCasing(std::string_view path)
u8string ResolveCasing(u8string_view path)
{
return Platform::ResolveCasing(path, File::Exists(path));
}

bool DeleteDirectory(std::string_view path)
bool DeleteDirectory(u8string_view path)
{
std::error_code ec;
const auto result = fs::remove_all(u8path(path), ec);
Expand Down