Skip to content

Commit

Permalink
Encode to/from utf8 when storing/loading path from json
Browse files Browse the repository at this point in the history
  • Loading branch information
black-sliver committed Jan 1, 2024
1 parent 37d39cb commit 1a20303
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 15 deletions.
59 changes: 59 additions & 0 deletions src/core/fileutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,4 +420,63 @@ static bool getFileMTime(const std::string& path, std::chrono::system_clock::tim
return getFileMTime(path.c_str(), tp);
}

#ifdef WIN32
// for now we use ANSI paths on windows, so we have to convert ANSI -> UTF8
static std::string pathToUTF8(const std::string& s)
{
std::wstring wbuf;
std::string res;
// ansi -> wstring
int wlen = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, NULL, 0);
if (wlen < 1) // error
return res;
wbuf.resize(wlen); // resize to incl NUL, since the implicit NUL can not be written
wlen = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, wbuf.data(), wbuf.size());
if (wlen < 1) // error
return res;
wbuf.resize(wlen - 1); // cut terminating NUL
// wstring -> utf8
int len = WideCharToMultiByte(CP_UTF8, 0, wbuf.c_str(), -1, NULL, 0, NULL, NULL);
if (len < 1) // error
return res;
res.resize(len);
len = WideCharToMultiByte(CP_UTF8, 0, wbuf.c_str(), -1, res.data(), res.size(), NULL, NULL);
if (len < 1) // error
res.resize(0);
else
res.resize(len - 1); // cut terminating NUL
return res;
}

static std::string pathFromUTF8(const std::string& s)
{
std::wstring wbuf;
std::string res;
// utf8 -> wstring
int wlen = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, NULL, 0);
if (wlen < 1) // error
return res;
wbuf.resize(wlen); // resize to incl NUL, since the implicit NUL can not be written
wlen = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, wbuf.data(), wbuf.size());
if (wlen < 1) // error
return res;
wbuf.resize(wlen - 1); // cut terminating NUL
// wstring -> ansi
int len = WideCharToMultiByte(CP_ACP, 0, wbuf.c_str(), -1, NULL, 0, NULL, NULL);
if (len < 1) // error
return res;
res.resize(len);
len = WideCharToMultiByte(CP_ACP, 0, wbuf.c_str(), -1, res.data(), res.size(), NULL, NULL);
if (len < 1) // error
res.resize(0);
else
res.resize(len - 1); // cut terminating NUL
return res;
}
#else // non-WIN32
// on non-windows paths are expected to be UTF8
#define pathToUTF8(s) (s)
#define pathFromUTF8(s) (s)
#endif

#endif // _CORE_FILEUTIL_H
14 changes: 9 additions & 5 deletions src/core/statemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ bool StateManager::saveState(Tracker* tracker, ScriptHost*,
}
state["ui_hints"] = jUiHints;
state["pack"] = {
{ "path", pack->getPath() },
{ "path", pathToUTF8(pack->getPath()) },
{ "uid", pack->getUID() },
{ "variant", pack->getVariant() },
{ "version", pack->getVersion() },
Expand All @@ -77,10 +77,14 @@ bool StateManager::saveState(Tracker* tracker, ScriptHost*,
}
printf("Saving state \"%s\" to file %s...\n",
external ? "export" : name.c_str(), filename.c_str());
std::string new_state = state.dump();
std::string old_state;
if (!readFile(filename, old_state) || old_state != new_state)
return writeFile(filename, new_state);
try {
std::string new_state = state.dump();
std::string old_state;
if (!readFile(filename, old_state) || old_state != new_state)
return writeFile(filename, new_state);
} catch (std::exception& ex) {
fprintf(stderr, "error saving: %s\n", ex.what());
}
return true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ int main(int argc, char** argv)
// argc/argv should be empty here. we pass everything through json args
json args = json::object();
if (packPath) {
args["pack"] = { {"path", packPath} };
args["pack"] = { {"path", pathToUTF8(packPath)} };
} else if (loadPack) {
args["pack"] = { {"uid", loadPack} };
}
Expand Down
18 changes: 9 additions & 9 deletions src/poptracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,12 @@ PopTracker::PopTracker(int argc, char** argv, bool cli, const json& args)
_config["software_fps_limit"] = DEFAULT_SOFTWARE_FPS_LIMIT;

if (_config["export_file"].is_string() && _config["export_uid"].is_string()) {
_exportFile = _config["export_file"];
_exportFile = pathFromUTF8(_config["export_file"]);
_exportUID = _config["export_uid"];
}

if (_config["export_dir"].is_string())
_exportDir = _config["export_dir"];
_exportDir = pathFromUTF8(_config["export_dir"]);

if (_config["at_uri"].is_string())
_atUri = _config["at_uri"];
Expand Down Expand Up @@ -349,9 +349,9 @@ bool PopTracker::start()
if (pos.top <= -1 * size.height)
pos.top = 0;
}
auto jPack = _args.contains("pack") ? _args["pack"] : _config["pack"];
auto& jPack = _args.contains("pack") ? _args["pack"] : _config["pack"];
if (jPack.type() == json::value_t::object) {
std::string path = to_string(jPack["path"],"");
std::string path = pathFromUTF8(to_string(jPack["path"],""));
std::string variant = to_string(jPack["variant"],"");
if (!scheduleLoadTracker(path,variant))
{
Expand Down Expand Up @@ -502,7 +502,7 @@ bool PopTracker::start()
json extra = { { "at_uri", _atUri }, {"at_slot", _atSlot } };
if (StateManager::saveState(_tracker, _scriptHost, _win->getHints(), extra, true, filename, true))
{
_exportFile = filename;
_exportFile = filename; // this is local encoding for fopen
_exportUID = _pack->getUID();
_exportDir = os_dirname(_exportFile);
}
Expand All @@ -518,7 +518,7 @@ bool PopTracker::start()
std::string filename;
if (!Dlg::OpenFile("Load State", lastName.c_str(), {{"JSON Files",{"*.json"}}}, filename)) return;
if (filename != _exportFile) {
_exportFile = filename;
_exportFile = filename; // this is local encoding for fopen
_exportDir = os_dirname(_exportFile);
_exportUID.clear();
}
Expand Down Expand Up @@ -731,7 +731,7 @@ bool PopTracker::frame()
_config["format_version"] = 1;
if (_pack)
_config["pack"] = {
{"path",_pack->getPath()},
{"path",pathToUTF8(_pack->getPath())},
{"variant",_pack->getVariant()},
{"uid",_pack->getUID()},
{"version",_pack->getVersion()}
Expand All @@ -744,9 +744,9 @@ bool PopTracker::frame()
{"display_name", _win->getDisplayName()},
{"display_pos", {disppos.left,disppos.top}}
};
_config["export_file"] = _exportFile;
_config["export_file"] = pathToUTF8(_exportFile);
_config["export_uid"] = _exportUID;
_config["export_dir"] = _exportDir;
_config["export_dir"] = pathToUTF8(_exportDir);
saveConfig();
}

Expand Down

0 comments on commit 1a20303

Please sign in to comment.