Introduce string utils

This commit is contained in:
momo5502
2024-12-21 11:31:32 +01:00
parent de8b85a3f9
commit 7633a4bbab
4 changed files with 63 additions and 20 deletions

View File

@@ -0,0 +1,40 @@
#pragma once
#include <string>
#include <ranges>
#include <cwctype>
#include <algorithm>
namespace utils::string
{
inline char char_to_lower(const char val)
{
return static_cast<char>(std::tolower(static_cast<unsigned char>(val)));
}
inline wchar_t char_to_lower(const wchar_t val)
{
return std::towlower(val);
}
template <class Elem, class Traits, class Alloc>
void to_lower_inplace(std::basic_string<Elem, Traits, Alloc>& str)
{
std::ranges::transform(str, str.begin(), [](const Elem e)
{
return char_to_lower(e);
});
}
template <class Elem, class Traits, class Alloc>
std::basic_string<Elem, Traits, Alloc> to_lower(std::basic_string<Elem, Traits, Alloc> str)
{
to_lower_inplace(str);
return str;
}
template <class Elem, class Traits, class Alloc>
std::basic_string<Elem, Traits, Alloc> to_lower_consume(std::basic_string<Elem, Traits, Alloc>& str)
{
return to_lower(std::move(str));
}
}

View File

@@ -3,6 +3,22 @@
#include "module_mapping.hpp"
#include "windows-emulator/logger.hpp"
namespace
{
std::filesystem::path canonicalize_module_path(const std::filesystem::path& file)
{
constexpr std::u16string_view nt_prefix = u"\\??\\";
const auto wide_file = file.u16string();
if (!wide_file.starts_with(nt_prefix))
{
return canonical(absolute(file));
}
return canonicalize_module_path(wide_file.substr(nt_prefix.size()));
}
}
static void serialize(utils::buffer_serializer& buffer, const exported_symbol& sym)
{
buffer.write(sym.name);
@@ -52,7 +68,7 @@ module_manager::module_manager(emulator& emu)
mapped_module* module_manager::map_module(const std::filesystem::path& file, logger& logger)
{
const auto canonical_file = canonical(absolute(file));
const auto canonical_file = canonicalize_module_path(file);
for (auto& mod : this->modules_)
{

View File

@@ -1,4 +1,5 @@
#include "hive_parser.hpp"
#include <utils/string.hpp>
// Based on this implementation: https://github.com/reahly/windows-hive-parser
@@ -130,11 +131,6 @@ namespace
throw std::runtime_error("Bad hive file '" + file_path.string() + "': " + e.what());
}
}
char char_to_lower(const char val)
{
return static_cast<char>(std::tolower(static_cast<unsigned char>(val)));
}
}
const hive_value* hive_key::get_value(std::ifstream& file, const std::string_view name)
@@ -188,7 +184,7 @@ void hive_key::parse(std::ifstream& file)
raw_value.data_offset = offset + static_cast<int>(offsetof(value_block_t, offset));
}
std::ranges::transform(value_name, value_name.begin(), char_to_lower);
utils::string::to_lower_inplace(value_name);
this->values_[std::move(value_name)] = std::move(raw_value);
}
@@ -211,7 +207,7 @@ void hive_key::parse(std::ifstream& file)
const auto subkey = read_file_object<key_block_t>(file, subkey_block_offset);
std::string subkey_name(subkey.name, std::min(subkey.len, static_cast<short>(sizeof(subkey.name))));
std::ranges::transform(subkey_name, subkey_name.begin(), char_to_lower);
utils::string::to_lower_inplace(subkey_name);
this->sub_keys_.emplace(std::move(subkey_name), hive_key{subkey.subkeys, subkey.value_count, subkey.offsets});
}

View File

@@ -1,25 +1,16 @@
#include "registry_manager.hpp"
#include <cwctype>
#include <serialization_helper.hpp>
#include "hive_parser.hpp"
#include <utils/string.hpp>
namespace
{
void string_to_lower(std::string& str)
{
std::ranges::transform(str, str.begin(), [](const char val)
{
return static_cast<char>(std::tolower(static_cast<unsigned char>(val)));
});
}
std::filesystem::path canonicalize_path(const std::filesystem::path& key)
{
auto path = key.lexically_normal().wstring();
std::ranges::transform(path, path.begin(), std::towlower);
return {std::move(path)};
return utils::string::to_lower_consume(path);
}
bool is_subpath(const std::filesystem::path& root, const std::filesystem::path& p)
@@ -144,7 +135,7 @@ std::optional<registry_key> registry_manager::get_key(const std::filesystem::pat
std::optional<registry_value> registry_manager::get_value(const registry_key& key, std::string name)
{
string_to_lower(name);
utils::string::to_lower_inplace(name);
const auto iterator = this->hives_.find(key.hive);
if (iterator == this->hives_.end())