fs::get_data_dir implemented

This commit is contained in:
Nekotekina 2016-07-11 22:00:12 +03:00
parent 2c981cf940
commit ba8fd825ec
3 changed files with 81 additions and 0 deletions

View File

@ -2,6 +2,8 @@
#include "StrFmt.h"
#include "Macro.h"
#include "SharedMutex.h"
#include "BEType.h"
#include "Crypto/sha1.h"
#include <unordered_map>
#include <algorithm>
@ -1207,6 +1209,78 @@ const std::string& fs::get_executable_dir()
return s_dir;
}
std::string fs::get_data_dir(const std::string& prefix, const std::string& location, const std::string& suffix)
{
static const std::string s_dir = []
{
const std::string& dir = get_config_dir() + "/data/";
if (!is_dir(dir) && !create_path(dir))
{
return get_config_dir();
}
return dir;
}();
std::vector<u8> buf;
buf.reserve(location.size() + 1);
// Normalize location
for (char c : location)
{
#ifdef _WIN32
if (c == '/' || c == '\\')
#else
if (c == '/')
#endif
{
if (buf.empty() || buf.back() != '/')
{
buf.push_back('/');
}
continue;
}
buf.push_back(c);
}
// Calculate hash
u8 hash[20];
sha1(buf.data(), buf.size(), hash);
// Concatenate
std::string&& result = fmt::format("%s%s/%016llx%08x-%s/", s_dir, prefix, reinterpret_cast<be_t<u64>&>(hash[0]), reinterpret_cast<be_t<u32>&>(hash[8]), suffix);
if (!is_dir(result))
{
// Create dir if necessary
if (create_path(result))
{
// Acknowledge original location
file(result + ".location", rewrite).write(buf);
}
}
return result;
}
std::string fs::get_data_dir(const std::string& prefix, const std::string& path)
{
#ifdef _WIN32
const auto& delim = "/\\";
#else
const auto& delim = "/";
#endif
// Extract file name and location
const std::string& location = fs::get_parent_dir(path);
const std::size_t name_pos = path.find_first_not_of(delim, location.size());
return fs::get_data_dir(prefix, location, name_pos == -1 ? std::string{} : path.substr(name_pos));
}
void fs::remove_all(const std::string& path, bool remove_root)
{
for (const auto& entry : dir(path))

View File

@ -439,6 +439,12 @@ namespace fs
// Get executable directory
const std::string& get_executable_dir();
// Get data/cache directory for specified prefix and suffix
std::string get_data_dir(const std::string& prefix, const std::string& location, const std::string& suffix);
// Get data/cache directory for specified prefix and path (suffix will be filename)
std::string get_data_dir(const std::string& prefix, const std::string& path);
// Delete directory and all its contents recursively
void remove_all(const std::string& path, bool remove_root = true);

View File

@ -204,6 +204,7 @@ void Emulator::Load()
const auto _psf = psf::load_object(fs::file(elf_dir + "/../PARAM.SFO"));
m_title = psf::get_string(_psf, "TITLE", m_path);
m_title_id = psf::get_string(_psf, "TITLE_ID");
fs::get_data_dir(m_title_id, m_path);
LOG_NOTICE(LOADER, "Title: %s", GetTitle());
LOG_NOTICE(LOADER, "Serial: %s", GetTitleID());