mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-21 21:55:38 +00:00
Complete UTF-16 (Unicode) support added for Windows.
ROM names with Unicode characters are supported, as well as running ES from a directory that has Unicode characters in its name.
This commit is contained in:
parent
adb5cb6664
commit
31da561695
2
NEWS.md
2
NEWS.md
|
@ -13,7 +13,7 @@ v1.0.0
|
|||
* Full navigation sound support, configurable per theme
|
||||
* New default theme rbsimple-DE bundled with the software, this theme is largely based on recalbox-multi by the Recalbox community
|
||||
* Added extensive es_systems.cfg templates for Unix and Windows
|
||||
* Updated the application to compile and work on Microsoft Windows
|
||||
* Updated the application to compile and work on Microsoft Windows, including full UTF-16 (Unicode) support
|
||||
* Seamless (almost) launch of games without showing the desktop when starting and returning from RetroArch and other emulators
|
||||
* Per-game launch command override, so that different cores or emulators can be used on a per-game basis (saved to gamelist.xml)
|
||||
* Core location can be defined relative to the emulator binary using the %EMUPATH% varible in es_systems.cfg (mostly useful for Windows)
|
||||
|
|
|
@ -128,10 +128,15 @@ void CollectionSystemManager::saveCustomCollection(SystemData* sys)
|
|||
CollectionSystemData sysData = mCustomCollectionSystemsData.at(name);
|
||||
if (sysData.needsSave) {
|
||||
std::ofstream configFile;
|
||||
#ifdef _WIN64
|
||||
configFile.open(Utils::String::
|
||||
stringToWideString(getCustomCollectionConfigPath(name)).c_str());
|
||||
#else
|
||||
configFile.open(getCustomCollectionConfigPath(name));
|
||||
#endif
|
||||
for (std::unordered_map<std::string, FileData*>::const_iterator
|
||||
iter = games.cbegin(); iter != games.cend(); ++iter) {
|
||||
std::string path = iter->first;
|
||||
std::string path = iter->first;
|
||||
// If the ROM path of the game begins with the path from the setting
|
||||
// ROMDirectory (or the default ROM directory), then replace it with %ROMPATH%.
|
||||
if (path.find(rompath) == 0)
|
||||
|
@ -143,7 +148,7 @@ void CollectionSystemManager::saveCustomCollection(SystemData* sys)
|
|||
}
|
||||
}
|
||||
else {
|
||||
LOG(LogError) << "Couldn't find collection to save! " << name;
|
||||
LOG(LogError) << "Error - Couldn't find collection to save! " << name;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -838,7 +843,7 @@ void CollectionSystemManager::populateAutoCollection(CollectionSystemData* sysDa
|
|||
sysData->isPopulated = true;
|
||||
}
|
||||
|
||||
// Populate a custom collection system
|
||||
// Populate a custom collection system.
|
||||
void CollectionSystemManager::populateCustomCollection(CollectionSystemData* sysData)
|
||||
{
|
||||
SystemData* newSys = sysData->system;
|
||||
|
@ -856,7 +861,11 @@ void CollectionSystemManager::populateCustomCollection(CollectionSystemData* sys
|
|||
FileFilterIndex* index = newSys->getIndex();
|
||||
|
||||
// Get configuration for this custom collection.
|
||||
#if _WIN64
|
||||
std::ifstream input(Utils::String::stringToWideString(path).c_str());
|
||||
#else
|
||||
std::ifstream input(path);
|
||||
#endif
|
||||
|
||||
// Get all files map.
|
||||
std::unordered_map<std::string,FileData*>
|
||||
|
@ -970,7 +979,11 @@ std::vector<std::string> CollectionSystemManager::getSystemsFromConfig()
|
|||
return systems;
|
||||
|
||||
pugi::xml_document doc;
|
||||
#ifdef _WIN64
|
||||
pugi::xml_parse_result res = doc.load_file(Utils::String::stringToWideString(path).c_str());
|
||||
#else
|
||||
pugi::xml_parse_result res = doc.load_file(path.c_str());
|
||||
#endif
|
||||
|
||||
if (!res)
|
||||
return systems;
|
||||
|
|
|
@ -465,7 +465,7 @@ void FileData::launchGame(Window* window)
|
|||
command = Utils::String::replace(command, "%ROM_RAW%", rom_raw);
|
||||
|
||||
#ifdef _WIN64
|
||||
std::wstring commandWide = Utils::String::charToWideChar(command);
|
||||
std::wstring commandWide = Utils::String::stringToWideString(command);
|
||||
#endif
|
||||
|
||||
Scripting::fireEvent("game-start", rom, basename);
|
||||
|
@ -494,7 +494,7 @@ void FileData::launchGame(Window* window)
|
|||
std::wstring emuExecutableWide;
|
||||
std::wstring emuPathWide;
|
||||
|
||||
emuExecutableWide = Utils::String::charToWideChar(emuExecutable);
|
||||
emuExecutableWide = Utils::String::stringToWideString(emuExecutable);
|
||||
|
||||
// Search for the emulator using the PATH environmental variable.
|
||||
DWORD size = SearchPathW(nullptr, emuExecutableWide.c_str(), L".exe", 0, nullptr, nullptr);
|
||||
|
@ -525,7 +525,7 @@ void FileData::launchGame(Window* window)
|
|||
LOG(LogInfo) << "Expanded emulator launch command:";
|
||||
|
||||
#ifdef _WIN64
|
||||
LOG(LogInfo) << Utils::String::wideCharToChar(commandWide);
|
||||
LOG(LogInfo) << Utils::String::wideStringToString(commandWide);
|
||||
exitCode = launchEmulatorWindows(commandWide);
|
||||
#else
|
||||
LOG(LogInfo) << command;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <chrono>
|
||||
|
||||
#include "utils/FileSystemUtil.h"
|
||||
#include "utils/StringUtil.h"
|
||||
#include "FileData.h"
|
||||
#include "FileFilterIndex.h"
|
||||
#include "Log.h"
|
||||
|
@ -93,7 +94,12 @@ void parseGamelist(SystemData* system)
|
|||
LOG(LogInfo) << "Parsing XML file \"" << xmlpath << "\"...";
|
||||
|
||||
pugi::xml_document doc;
|
||||
#ifdef _WIN64
|
||||
pugi::xml_parse_result result =
|
||||
doc.load_file(Utils::String::stringToWideString(xmlpath).c_str());
|
||||
#else
|
||||
pugi::xml_parse_result result = doc.load_file(xmlpath.c_str());
|
||||
#endif
|
||||
|
||||
if (!result) {
|
||||
LOG(LogError) << "Error parsing XML file \"" << xmlpath <<
|
||||
|
@ -189,7 +195,12 @@ void updateGamelist(SystemData* system)
|
|||
|
||||
if (Utils::FileSystem::exists(xmlReadPath)) {
|
||||
// Parse an existing file first.
|
||||
#ifdef _WIN64
|
||||
pugi::xml_parse_result result =
|
||||
doc.load_file(Utils::String::stringToWideString(xmlReadPath).c_str());
|
||||
#else
|
||||
pugi::xml_parse_result result = doc.load_file(xmlReadPath.c_str());
|
||||
#endif
|
||||
|
||||
if (!result) {
|
||||
LOG(LogError) << "Error parsing XML file \"" << xmlReadPath << "\"!\n " <<
|
||||
|
@ -264,7 +275,11 @@ void updateGamelist(SystemData* system)
|
|||
LOG(LogInfo) << "Added/Updated " << numUpdated <<
|
||||
" entities in '" << xmlReadPath << "'";
|
||||
|
||||
#ifdef _WIN64
|
||||
if (!doc.save_file(Utils::String::stringToWideString(xmlWritePath).c_str())) {
|
||||
#else
|
||||
if (!doc.save_file(xmlWritePath.c_str())) {
|
||||
#endif
|
||||
LOG(LogError) << "Error saving gamelist.xml to \"" <<
|
||||
xmlWritePath << "\" (for system " << system->getName() << ")!";
|
||||
}
|
||||
|
|
|
@ -226,7 +226,11 @@ bool SystemData::loadConfig()
|
|||
}
|
||||
|
||||
pugi::xml_document doc;
|
||||
#ifdef _WIN64
|
||||
pugi::xml_parse_result res = doc.load_file(Utils::String::stringToWideString(path).c_str());
|
||||
#else
|
||||
pugi::xml_parse_result res = doc.load_file(path.c_str());
|
||||
#endif
|
||||
|
||||
if (!res) {
|
||||
LOG(LogError) << "Error - Could not parse es_systems.cfg";
|
||||
|
|
|
@ -21,8 +21,7 @@ class FileData;
|
|||
class FileFilterIndex;
|
||||
class ThemeData;
|
||||
|
||||
struct SystemEnvironmentData
|
||||
{
|
||||
struct SystemEnvironmentData {
|
||||
std::string mStartPath;
|
||||
std::vector<std::string> mSearchExtensions;
|
||||
std::string mLaunchCommand;
|
||||
|
@ -32,7 +31,8 @@ struct SystemEnvironmentData
|
|||
class SystemData
|
||||
{
|
||||
public:
|
||||
SystemData(const std::string& name,
|
||||
SystemData(
|
||||
const std::string& name,
|
||||
const std::string& fullName,
|
||||
SystemEnvironmentData* envData,
|
||||
const std::string& themeFolder,
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "guis/GuiDetectDevice.h"
|
||||
#include "guis/GuiMsgBox.h"
|
||||
#include "utils/FileSystemUtil.h"
|
||||
#include "utils/StringUtil.h"
|
||||
#include "views/ViewController.h"
|
||||
#include "CollectionSystemManager.h"
|
||||
#include "EmulationStation.h"
|
||||
|
@ -342,8 +343,7 @@ bool loadSystemConfigFile(std::string& errorMsg)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (SystemData::sSystemVector.size() == 0)
|
||||
{
|
||||
if (SystemData::sSystemVector.size() == 0) {
|
||||
LOG(LogError) << "Error - No systems found, does at least one system have a game present? "
|
||||
"(Check that the file extensions are supported.)";
|
||||
errorMsg = "THE SYSTEMS CONFIGURATION FILE EXISTS, BUT NO\n"
|
||||
|
@ -354,7 +354,12 @@ bool loadSystemConfigFile(std::string& errorMsg)
|
|||
"THE GAME SYSTEMS SUBDIRECTORIES ALSO NEED TO\n"
|
||||
"MATCH THE PLATFORM TAGS IN ES_SYSTEMS.CFG.\n"
|
||||
"THIS IS THE CURRENTLY CONFIGURED ROM DIRECTORY:\n";
|
||||
#ifdef _WIN64
|
||||
errorMsg += Utils::String::replace(FileData::getROMDirectory(), "/", "\\");
|
||||
#else
|
||||
errorMsg += FileData::getROMDirectory();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "scrapers/Scraper.h"
|
||||
|
||||
#include "utils/StringUtil.h"
|
||||
#include "FileData.h"
|
||||
#include "GamesDBJSONScraper.h"
|
||||
#include "ScreenScraper.h"
|
||||
|
@ -231,7 +232,12 @@ MDResolveHandle::MDResolveHandle(const ScraperSearchResult& result,
|
|||
if(it->existingMediaFile != "")
|
||||
Utils::FileSystem::removeFile(it->existingMediaFile);
|
||||
|
||||
#ifdef _WIN64
|
||||
std::ofstream stream(Utils::String::stringToWideString(filePath).c_str(),
|
||||
std::ios_base::out | std::ios_base::binary);
|
||||
#else
|
||||
std::ofstream stream(filePath, std::ios_base::out | std::ios_base::binary);
|
||||
#endif
|
||||
if (stream.bad()) {
|
||||
setError("Failed to open image path to write. Permission error? Disk full?");
|
||||
return;
|
||||
|
@ -331,7 +337,12 @@ void ImageDownloadHandle::update()
|
|||
if(mExistingMediaFile != "")
|
||||
Utils::FileSystem::removeFile(mExistingMediaFile);
|
||||
|
||||
#ifdef _WIN64
|
||||
std::ofstream stream(Utils::String::stringToWideString(mSavePath).c_str(),
|
||||
std::ios_base::out | std::ios_base::binary);
|
||||
#else
|
||||
std::ofstream stream(mSavePath, std::ios_base::out | std::ios_base::binary);
|
||||
#endif
|
||||
if (stream.bad()) {
|
||||
setError("Failed to open image path to write. Permission error? Disk full?");
|
||||
return;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "InputManager.h"
|
||||
|
||||
#include "utils/FileSystemUtil.h"
|
||||
#include "utils/StringUtil.h"
|
||||
#include "CECInput.h"
|
||||
#include "Log.h"
|
||||
#include "Platform.h"
|
||||
|
@ -83,7 +84,7 @@ void InputManager::init()
|
|||
loadInputConfig(mKeyboardInputConfig);
|
||||
|
||||
SDL_USER_CECBUTTONDOWN = SDL_RegisterEvents(2);
|
||||
SDL_USER_CECBUTTONUP = SDL_USER_CECBUTTONDOWN + 1;
|
||||
SDL_USER_CECBUTTONUP = SDL_USER_CECBUTTONDOWN + 1;
|
||||
CECInput::init();
|
||||
mCECInputConfig = new InputConfig(DEVICE_CEC, "CEC", CEC_GUID_STRING);
|
||||
loadInputConfig(mCECInputConfig);
|
||||
|
@ -302,7 +303,11 @@ bool InputManager::loadInputConfig(InputConfig* config)
|
|||
return false;
|
||||
|
||||
pugi::xml_document doc;
|
||||
#ifdef _WIN64
|
||||
pugi::xml_parse_result res = doc.load_file(Utils::String::stringToWideString(path).c_str());
|
||||
#else
|
||||
pugi::xml_parse_result res = doc.load_file(path.c_str());
|
||||
#endif
|
||||
|
||||
if (!res) {
|
||||
LOG(LogError) << "Error parsing input config: " << res.description();
|
||||
|
@ -362,7 +367,12 @@ void InputManager::writeDeviceConfig(InputConfig* config)
|
|||
|
||||
if (Utils::FileSystem::exists(path)) {
|
||||
// Merge files.
|
||||
#ifdef _WIN64
|
||||
pugi::xml_parse_result result =
|
||||
doc.load_file(Utils::String::stringToWideString(path).c_str());
|
||||
#else
|
||||
pugi::xml_parse_result result = doc.load_file(path.c_str());
|
||||
#endif
|
||||
if (!result) {
|
||||
LOG(LogError) << "Error parsing input config: " << result.description();
|
||||
}
|
||||
|
@ -400,7 +410,12 @@ void InputManager::writeDeviceConfig(InputConfig* config)
|
|||
root = doc.append_child("inputList");
|
||||
|
||||
config->writeToXML(root);
|
||||
|
||||
#ifdef _WIN64
|
||||
doc.save_file(Utils::String::stringToWideString(path).c_str());
|
||||
#else
|
||||
doc.save_file(path.c_str());
|
||||
#endif
|
||||
|
||||
Scripting::fireEvent("config-changed");
|
||||
Scripting::fireEvent("controls-changed");
|
||||
|
@ -417,7 +432,13 @@ void InputManager::doOnFinish()
|
|||
pugi::xml_document doc;
|
||||
|
||||
if (Utils::FileSystem::exists(path)) {
|
||||
#ifdef _WIN64
|
||||
pugi::xml_parse_result result =
|
||||
doc.load_file(Utils::String::stringToWideString(path).c_str());
|
||||
#else
|
||||
pugi::xml_parse_result result = doc.load_file(path.c_str());
|
||||
#endif
|
||||
|
||||
if (!result) {
|
||||
LOG(LogError) << "Error parsing input config: " << result.description();
|
||||
}
|
||||
|
|
|
@ -7,13 +7,15 @@
|
|||
#include "Log.h"
|
||||
|
||||
#include "utils/FileSystemUtil.h"
|
||||
#include "utils/StringUtil.h"
|
||||
#include "Platform.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
|
||||
LogLevel Log::reportingLevel = LogInfo;
|
||||
FILE* Log::file = nullptr; // fopen(getLogPath().c_str(), "w");
|
||||
std::ofstream file;
|
||||
|
||||
LogLevel Log::getReportingLevel()
|
||||
{
|
||||
|
@ -32,15 +34,19 @@ void Log::setReportingLevel(LogLevel level)
|
|||
|
||||
void Log::init()
|
||||
{
|
||||
remove((getLogPath() + ".bak").c_str());
|
||||
// Rename previous log file.
|
||||
rename(getLogPath().c_str(), (getLogPath() + ".bak").c_str());
|
||||
Utils::FileSystem::removeFile(getLogPath() + ".bak");
|
||||
// Rename the previous log file.
|
||||
Utils::FileSystem::renameFile(getLogPath(), getLogPath() + ".bak", true);
|
||||
return;
|
||||
}
|
||||
|
||||
void Log::open()
|
||||
{
|
||||
file = fopen(getLogPath().c_str(), "w");
|
||||
#ifdef _WIN64
|
||||
file.open(Utils::String::stringToWideString(getLogPath()).c_str());
|
||||
#else
|
||||
file.open(getLogPath().c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
std::ostringstream& Log::get(LogLevel level)
|
||||
|
@ -54,36 +60,30 @@ std::ostringstream& Log::get(LogLevel level)
|
|||
|
||||
void Log::flush()
|
||||
{
|
||||
fflush(getOutput());
|
||||
file.flush();
|
||||
}
|
||||
|
||||
void Log::close()
|
||||
{
|
||||
fclose(file);
|
||||
file = nullptr;
|
||||
}
|
||||
|
||||
FILE* Log::getOutput()
|
||||
{
|
||||
return file;
|
||||
file.close();
|
||||
}
|
||||
|
||||
Log::~Log()
|
||||
{
|
||||
os << std::endl;
|
||||
|
||||
if (getOutput() == nullptr) {
|
||||
// not open yet, print to stdout
|
||||
if (!file.is_open()) {
|
||||
// Not open yet, print to stdout.
|
||||
std::cerr << "ERROR - tried to write to log file before it was open! "
|
||||
"The following won't be logged:\n";
|
||||
std::cerr << os.str();
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(getOutput(), "%s", os.str().c_str());
|
||||
file << os.str();
|
||||
|
||||
// If it's an error, also print to console.
|
||||
// Print all messages if using --debug.
|
||||
if (messageLevel == LogError || reportingLevel >= LogDebug)
|
||||
fprintf(stderr, "%s", os.str().c_str());
|
||||
std::cerr << os.str();
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ enum LogLevel {
|
|||
class Log
|
||||
{
|
||||
public:
|
||||
//Log();
|
||||
~Log();
|
||||
std::ostringstream& get(LogLevel level = LogInfo);
|
||||
|
||||
|
@ -40,11 +39,9 @@ public:
|
|||
|
||||
protected:
|
||||
std::ostringstream os;
|
||||
static FILE* file;
|
||||
|
||||
private:
|
||||
static LogLevel reportingLevel;
|
||||
static FILE* getOutput();
|
||||
LogLevel messageLevel;
|
||||
};
|
||||
|
||||
|
|
|
@ -50,7 +50,12 @@ MameNames::MameNames()
|
|||
LOG(LogInfo) << "Parsing XML file \"" << xmlpath << "\"...";
|
||||
|
||||
pugi::xml_document doc;
|
||||
#ifdef _WIN64
|
||||
pugi::xml_parse_result result =
|
||||
doc.load_file(Utils::String::stringToWideString(xmlpath).c_str());
|
||||
#else
|
||||
pugi::xml_parse_result result = doc.load_file(xmlpath.c_str());
|
||||
#endif
|
||||
|
||||
if (!result) {
|
||||
LOG(LogError) << "Error parsing XML file \"" << xmlpath << "\"!\n "
|
||||
|
@ -75,7 +80,11 @@ MameNames::MameNames()
|
|||
|
||||
LOG(LogInfo) << "Parsing XML file \"" << xmlpath << "\"...";
|
||||
|
||||
#ifdef _WIN64
|
||||
result = doc.load_file(Utils::String::stringToWideString(xmlpath).c_str());
|
||||
#else
|
||||
result = doc.load_file(xmlpath.c_str());
|
||||
#endif
|
||||
|
||||
if (!result) {
|
||||
LOG(LogError) << "Error parsing XML file \"" << xmlpath << "\"!\n "
|
||||
|
@ -97,7 +106,11 @@ MameNames::MameNames()
|
|||
|
||||
LOG(LogInfo) << "Parsing XML file \"" << xmlpath << "\"...";
|
||||
|
||||
#ifdef _WIN64
|
||||
result = doc.load_file(Utils::String::stringToWideString(xmlpath).c_str());
|
||||
#else
|
||||
result = doc.load_file(xmlpath.c_str());
|
||||
#endif
|
||||
|
||||
if (!result) {
|
||||
LOG(LogError) << "Error parsing XML file \"" << xmlpath << "\"!\n "
|
||||
|
|
|
@ -50,7 +50,7 @@ int runSystemCommand(const std::string& cmd_utf8)
|
|||
#ifdef _WIN64
|
||||
// On Windows we use _wsystem to support non-ASCII paths
|
||||
// which requires converting from UTF-8 to a wstring.
|
||||
std::wstring wchar_str = Utils::String::charToWideChar(cmd_utf8);
|
||||
std::wstring wchar_str = Utils::String::stringToWideString(cmd_utf8);
|
||||
return _wsystem(wchar_str.c_str());
|
||||
#else
|
||||
return system(cmd_utf8.c_str());
|
||||
|
@ -111,7 +111,7 @@ int launchEmulatorWindows(const std::wstring& cmd_utf16)
|
|||
|
||||
errorCode = GetLastError();
|
||||
|
||||
std::string errorMessage = Utils::String::wideCharToChar(pBuffer);
|
||||
std::string errorMessage = Utils::String::wideStringToString(pBuffer);
|
||||
// Remove trailing newline from the error message.
|
||||
if (errorMessage.back() == '\n');
|
||||
errorMessage.pop_back();
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "Settings.h"
|
||||
|
||||
#include "utils/FileSystemUtil.h"
|
||||
#include "utils/StringUtil.h"
|
||||
#include "Log.h"
|
||||
#include "Scripting.h"
|
||||
#include "Platform.h"
|
||||
|
@ -268,7 +269,11 @@ void Settings::saveFile()
|
|||
node.append_attribute("value").set_value(iter->second.c_str());
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
doc.save_file(Utils::String::stringToWideString(path).c_str());
|
||||
#else
|
||||
doc.save_file(path.c_str());
|
||||
#endif
|
||||
|
||||
Scripting::fireEvent("config-changed");
|
||||
Scripting::fireEvent("settings-changed");
|
||||
|
@ -283,7 +288,11 @@ void Settings::loadFile()
|
|||
return;
|
||||
|
||||
pugi::xml_document doc;
|
||||
#ifdef _WIN64
|
||||
pugi::xml_parse_result result = doc.load_file(Utils::String::stringToWideString(path).c_str());
|
||||
#else
|
||||
pugi::xml_parse_result result = doc.load_file(path.c_str());
|
||||
#endif
|
||||
if (!result) {
|
||||
LOG(LogError) << "Error - Could not parse Settings file!\n " << result.description();
|
||||
return;
|
||||
|
|
|
@ -260,7 +260,11 @@ void ThemeData::loadFile(std::map<std::string, std::string> sysDataMap, const st
|
|||
mVariables.insert(sysDataMap.cbegin(), sysDataMap.cend());
|
||||
|
||||
pugi::xml_document doc;
|
||||
#ifdef _WIN64
|
||||
pugi::xml_parse_result res = doc.load_file(Utils::String::stringToWideString(path).c_str());
|
||||
#else
|
||||
pugi::xml_parse_result res = doc.load_file(path.c_str());
|
||||
#endif
|
||||
if (!res)
|
||||
throw error << "XML parsing error: \n " << res.description();
|
||||
|
||||
|
@ -302,7 +306,12 @@ void ThemeData::parseIncludes(const pugi::xml_node& root)
|
|||
mPaths.push_back(path);
|
||||
|
||||
pugi::xml_document includeDoc;
|
||||
#ifdef _WIN64
|
||||
pugi::xml_parse_result result =
|
||||
includeDoc.load_file(Utils::String::stringToWideString(path).c_str());
|
||||
#else
|
||||
pugi::xml_parse_result result = includeDoc.load_file(path.c_str());
|
||||
#endif
|
||||
if (!result)
|
||||
throw error << "Error parsing file: \n " << result.description();
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "ResourceManager.h"
|
||||
|
||||
#include "utils/FileSystemUtil.h"
|
||||
#include "utils/StringUtil.h"
|
||||
#include "Log.h"
|
||||
#include "Platform.h"
|
||||
#include "Scripting.h"
|
||||
|
@ -88,7 +89,11 @@ const ResourceData ResourceManager::getFileData(const std::string& path) const
|
|||
|
||||
ResourceData ResourceManager::loadFile(const std::string& path) const
|
||||
{
|
||||
#ifdef _WIN64
|
||||
std::ifstream stream(Utils::String::stringToWideString(path).c_str(), std::ios::binary);
|
||||
#else
|
||||
std::ifstream stream(path, std::ios::binary);
|
||||
#endif
|
||||
|
||||
stream.seekg(0, stream.end);
|
||||
size_t size = (size_t)stream.tellg();
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include "utils/FileSystemUtil.h"
|
||||
|
||||
#include "utils/StringUtil.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
@ -16,14 +18,8 @@
|
|||
#include <string.h>
|
||||
|
||||
#if defined(_WIN64)
|
||||
// Because windows...
|
||||
#include <direct.h>
|
||||
#include <Windows.h>
|
||||
#define getcwd _getcwd
|
||||
#define mkdir(x,y) _mkdir(x)
|
||||
#define snprintf _snprintf
|
||||
#define stat64 _stat64
|
||||
#define unlink _unlink
|
||||
//#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
|
||||
//#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
|
||||
#else
|
||||
|
@ -49,21 +45,6 @@ namespace Utils
|
|||
static std::string homePath = "";
|
||||
static std::string exePath = "";
|
||||
|
||||
#if defined(_WIN64)
|
||||
static std::string convertFromWideString(const std::wstring wstring)
|
||||
{
|
||||
int numBytes = WideCharToMultiByte(CP_UTF8, 0, wstring.c_str(),
|
||||
(int)wstring.length(), nullptr, 0, nullptr, nullptr);
|
||||
std::string string;
|
||||
|
||||
string.resize(numBytes);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wstring.c_str(), (int)wstring.length(),
|
||||
(char*)string.c_str(), numBytes, nullptr, nullptr);
|
||||
|
||||
return std::string(string);
|
||||
}
|
||||
#endif
|
||||
|
||||
stringList getDirContent(const std::string& _path, const bool _recursive)
|
||||
{
|
||||
std::string path = getGenericPath(_path);
|
||||
|
@ -74,14 +55,13 @@ namespace Utils
|
|||
|
||||
#if defined(_WIN64)
|
||||
WIN32_FIND_DATAW findData;
|
||||
std::string wildcard = path + "/*";
|
||||
HANDLE hFind = FindFirstFileW(std::wstring(wildcard.begin(),
|
||||
wildcard.end()).c_str(), &findData);
|
||||
std::wstring wildcard = Utils::String::stringToWideString(path) + L"/*";
|
||||
HANDLE hFind = FindFirstFileW(wildcard.c_str(), &findData);
|
||||
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
// Loop over all files in the directory.
|
||||
do {
|
||||
std::string name = convertFromWideString(findData.cFileName);
|
||||
std::string name = Utils::String::wideStringToString(findData.cFileName);
|
||||
// Ignore "." and ".."
|
||||
if ((name != ".") && (name != "..")) {
|
||||
std::string fullName(getGenericPath(path + "/" + name));
|
||||
|
@ -154,8 +134,15 @@ namespace Utils
|
|||
#if defined(_WIN64)
|
||||
// On Windows we need to check HOMEDRIVE and HOMEPATH.
|
||||
if (!homePath.length()) {
|
||||
#ifdef _WIN64
|
||||
std::string envHomeDrive =
|
||||
Utils::String::wideStringToString(_wgetenv(L"HOMEDRIVE"));
|
||||
std::string envHomePath =
|
||||
Utils::String::wideStringToString(_wgetenv(L"HOMEPATH"));
|
||||
#else
|
||||
std::string envHomeDrive = getenv("HOMEDRIVE");
|
||||
std::string envHomePath = getenv("HOMEPATH");
|
||||
#endif
|
||||
if (envHomeDrive.length() && envHomePath.length())
|
||||
homePath = getGenericPath(envHomeDrive + "/" + envHomePath);
|
||||
}
|
||||
|
@ -180,7 +167,13 @@ namespace Utils
|
|||
char temp[512];
|
||||
|
||||
// Return current working directory.
|
||||
#ifdef _WIN64
|
||||
wchar_t tempWide[512];
|
||||
return (_wgetcwd(tempWide, 512) ?
|
||||
getGenericPath(Utils::String::wideStringToString(tempWide)) : "");
|
||||
#else
|
||||
return (getcwd(temp, 512) ? getGenericPath(temp) : "");
|
||||
#endif
|
||||
}
|
||||
|
||||
void setExePath(const std::string& _path)
|
||||
|
@ -189,7 +182,7 @@ namespace Utils
|
|||
#if defined(_WIN64)
|
||||
std::wstring result(path_max, 0);
|
||||
if (GetModuleFileNameW(nullptr, &result[0], path_max) != 0)
|
||||
exePath = convertFromWideString(result);
|
||||
exePath = Utils::String::wideStringToString(result);
|
||||
#else
|
||||
std::string result(path_max, 0);
|
||||
if (readlink("/proc/self/exe", &result[0], path_max) != -1)
|
||||
|
@ -539,7 +532,12 @@ namespace Utils
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
std::ifstream sourceFile(Utils::String::stringToWideString(_source_path).c_str(),
|
||||
std::ios::binary);
|
||||
#else
|
||||
std::ifstream sourceFile(_source_path, std::ios::binary);
|
||||
#endif
|
||||
|
||||
if (sourceFile.fail()) {
|
||||
LOG(LogError) << "Error - Couldn't read from source file (" << _source_path <<
|
||||
|
@ -548,7 +546,12 @@ namespace Utils
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
std::ofstream targetFile(Utils::String::stringToWideString(_destination_path).c_str(),
|
||||
std::ios::binary);
|
||||
#else
|
||||
std::ofstream targetFile(_destination_path, std::ios::binary);
|
||||
#endif
|
||||
|
||||
if (targetFile.fail()) {
|
||||
LOG(LogError) << "Error - Couldn't write to target file (" << _destination_path <<
|
||||
|
@ -565,6 +568,38 @@ namespace Utils
|
|||
return false;
|
||||
}
|
||||
|
||||
bool renameFile(const std::string& _source_path,
|
||||
const std::string& _destination_path, bool _overwrite)
|
||||
{
|
||||
// Don't print any error message for a missing source file as Log will use this
|
||||
// function when initializing the logging. It would always generate an error in
|
||||
// case it's the first application start (as an old log file would then not exist).
|
||||
if (!exists(_source_path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(isDirectory(_destination_path)) {
|
||||
LOG(LogError) << "Error - Destination file is actually a directory:";
|
||||
LOG(LogError) << _destination_path;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!_overwrite && exists(_destination_path)) {
|
||||
LOG(LogError) << "Error - Destination file exists and the overwrite flag "
|
||||
"has not been set.";
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
_wrename(Utils::String::stringToWideString(_source_path).c_str(),
|
||||
Utils::String::stringToWideString(_destination_path).c_str());
|
||||
#else
|
||||
std::rename(_source_path.c_str(), _destination_path.c_str());
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool removeFile(const std::string& _path)
|
||||
{
|
||||
std::string path = getGenericPath(_path);
|
||||
|
@ -574,7 +609,26 @@ namespace Utils
|
|||
return true;
|
||||
|
||||
// Try to remove file.
|
||||
#ifdef _WIN64
|
||||
if (_wunlink(Utils::String::stringToWideString(path).c_str()) != 0) {
|
||||
LOG(LogError) << "Error - Couldn't delete file, permission problems?";
|
||||
LOG(LogError) << path;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (unlink(path.c_str()) != 0) {
|
||||
LOG(LogError) << "Error - Couldn't delete file, permission problems?";
|
||||
LOG(LogError) << path;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return (unlink(path.c_str()) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool createDirectory(const std::string& _path)
|
||||
|
@ -586,8 +640,13 @@ namespace Utils
|
|||
return true;
|
||||
|
||||
// Try to create directory.
|
||||
#ifdef _WIN64
|
||||
if (_wmkdir(Utils::String::stringToWideString(path).c_str()) == 0)
|
||||
return true;
|
||||
#else
|
||||
if (mkdir(path.c_str(), 0755) == 0)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
// Failed to create directory, try to create the parent.
|
||||
std::string parent = getParent(path);
|
||||
|
@ -597,15 +656,24 @@ namespace Utils
|
|||
createDirectory(parent);
|
||||
|
||||
// Try to create directory again now that the parent should exist.
|
||||
#ifdef _WIN64
|
||||
return (_wmkdir(Utils::String::stringToWideString(path).c_str()) == 0);
|
||||
#else
|
||||
return (mkdir(path.c_str(), 0755) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool exists(const std::string& _path)
|
||||
{
|
||||
std::string path = getGenericPath(_path);
|
||||
struct stat64 info;
|
||||
|
||||
#ifdef _WIN64
|
||||
struct _stat64 info;
|
||||
return (_wstat64(Utils::String::stringToWideString(path).c_str(), &info) == 0);
|
||||
#else
|
||||
struct stat64 info;
|
||||
return (stat64(path.c_str(), &info) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isAbsolute(const std::string& _path)
|
||||
|
@ -624,8 +692,13 @@ namespace Utils
|
|||
std::string path = getGenericPath(_path);
|
||||
struct stat64 info;
|
||||
|
||||
#ifdef _WIN64
|
||||
if (_wstat64(Utils::String::stringToWideString(path).c_str(), &info) != 0)
|
||||
return false;
|
||||
#else
|
||||
if (stat64(path.c_str(), &info) != 0)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// Check for S_IFREG attribute.
|
||||
return (S_ISREG(info.st_mode));
|
||||
|
@ -634,10 +707,15 @@ namespace Utils
|
|||
bool isDirectory(const std::string& _path)
|
||||
{
|
||||
std::string path = getGenericPath(_path);
|
||||
struct stat info;
|
||||
struct stat64 info;
|
||||
|
||||
if (stat(path.c_str(), &info) != 0)
|
||||
#ifdef _WIN64
|
||||
if (_wstat64(Utils::String::stringToWideString(path).c_str(), &info) != 0)
|
||||
return false;
|
||||
#else
|
||||
if (stat64(path.c_str(), &info) != 0)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// Check for S_IFDIR attribute.
|
||||
return (S_ISDIR(info.st_mode));
|
||||
|
|
|
@ -47,7 +47,10 @@ namespace Utils
|
|||
std::string resolveSymlink(const std::string& _path);
|
||||
bool copyFile(const std::string& _source_path,
|
||||
const std::string& _destination_path, bool _overwrite);
|
||||
bool renameFile(const std::string& _source_path,
|
||||
const std::string& _destination_path, bool _overwrite);
|
||||
bool removeFile(const std::string& _path);
|
||||
|
||||
bool createDirectory(const std::string& _path);
|
||||
bool exists(const std::string& _path);
|
||||
bool isAbsolute(const std::string& _path);
|
||||
|
|
|
@ -187,7 +187,7 @@ namespace Utils
|
|||
return string;
|
||||
}
|
||||
|
||||
std::wstring charToWideChar(const std::string& _string)
|
||||
std::wstring stringToWideString(const std::string& _string)
|
||||
{
|
||||
typedef std::codecvt_utf8<wchar_t> convert_type;
|
||||
std::wstring_convert<convert_type, wchar_t> stringConverter;
|
||||
|
@ -195,7 +195,7 @@ namespace Utils
|
|||
return stringConverter.from_bytes(_string);
|
||||
}
|
||||
|
||||
std::string wideCharToChar(const std::wstring& _string)
|
||||
std::string wideStringToString(const std::wstring& _string)
|
||||
{
|
||||
typedef std::codecvt_utf8<wchar_t> convert_type;
|
||||
std::wstring_convert<convert_type, wchar_t> stringConverter;
|
||||
|
|
|
@ -28,8 +28,8 @@ namespace Utils
|
|||
std::string trim(const std::string& _string);
|
||||
std::string replace(const std::string& _string, const std::string& _replace,
|
||||
const std::string& _with);
|
||||
std::wstring charToWideChar(const std::string& _string);
|
||||
std::string wideCharToChar(const std::wstring& _string);
|
||||
std::wstring stringToWideString(const std::string& _string);
|
||||
std::string wideStringToString(const std::wstring& _string);
|
||||
bool startsWith(const std::string& _string, const std::string& _start);
|
||||
bool endsWith(const std::string& _string, const std::string& _end);
|
||||
std::string removeParenthesis(const std::string& _string);
|
||||
|
|
Loading…
Reference in a new issue