#include #include #include #include namespace hex { EncodingFile::EncodingFile() : m_mapping(std::make_unique, std::string>>>()) { } EncodingFile::EncodingFile(const hex::EncodingFile &other) { m_mapping = std::make_unique, std::string>>>(*other.m_mapping); m_tableContent = other.m_tableContent; m_longestSequence = other.m_longestSequence; m_shortestSequence = other.m_shortestSequence; m_valid = other.m_valid; m_name = other.m_name; } EncodingFile::EncodingFile(EncodingFile &&other) noexcept { m_mapping = std::move(other.m_mapping); m_tableContent = std::move(other.m_tableContent); m_longestSequence = other.m_longestSequence; m_shortestSequence = other.m_shortestSequence; m_valid = other.m_valid; m_name = std::move(other.m_name); } EncodingFile::EncodingFile(Type type, const std::fs::path &path) : EncodingFile() { auto file = wolv::io::File(path, wolv::io::File::Mode::Read); switch (type) { case Type::Thingy: parse(file.readString()); break; default: return; } { m_name = path.stem().string(); m_name = wolv::util::replaceStrings(m_name, "_", " "); if (!m_name.empty()) m_name[0] = std::toupper(m_name[0]); } m_valid = true; } EncodingFile::EncodingFile(Type type, const std::string &content) : EncodingFile() { switch (type) { case Type::Thingy: parse(content); break; default: return; } m_name = "Unknown"; m_valid = true; } EncodingFile &EncodingFile::operator=(const hex::EncodingFile &other) { m_mapping = std::make_unique, std::string>>>(*other.m_mapping); m_tableContent = other.m_tableContent; m_longestSequence = other.m_longestSequence; m_shortestSequence = other.m_shortestSequence; m_valid = other.m_valid; m_name = other.m_name; return *this; } EncodingFile &EncodingFile::operator=(EncodingFile &&other) noexcept { m_mapping = std::move(other.m_mapping); m_tableContent = std::move(other.m_tableContent); m_longestSequence = other.m_longestSequence; m_shortestSequence = other.m_shortestSequence; m_valid = other.m_valid; m_name = std::move(other.m_name); return *this; } std::pair EncodingFile::getEncodingFor(std::span buffer) const { for (auto riter = m_mapping->crbegin(); riter != m_mapping->crend(); ++riter) { const auto &[size, mapping] = *riter; if (size > buffer.size()) continue; std::vector key(buffer.begin(), buffer.begin() + size); if (mapping.contains(key)) return { mapping.at(key), size }; } return { ".", 1 }; } u64 EncodingFile::getEncodingLengthFor(std::span buffer) const { for (auto riter = m_mapping->crbegin(); riter != m_mapping->crend(); ++riter) { const auto &[size, mapping] = *riter; if (size > buffer.size()) continue; std::vector key(buffer.begin(), buffer.begin() + size); if (mapping.contains(key)) return size; } return 1; } void EncodingFile::parse(const std::string &content) { m_tableContent = content; for (const auto &line : splitString(m_tableContent, "\n")) { std::string from, to; { auto delimiterPos = line.find('='); if (delimiterPos >= line.length()) continue; from = line.substr(0, delimiterPos); to = line.substr(delimiterPos + 1); if (from.empty()) continue; } auto fromBytes = hex::parseByteString(from); if (fromBytes.empty()) continue; if (to.length() > 1) to = wolv::util::trim(to); if (to.empty()) to = " "; if (!m_mapping->contains(fromBytes.size())) m_mapping->insert({ fromBytes.size(), {} }); u64 keySize = fromBytes.size(); (*m_mapping)[keySize].insert({ std::move(fromBytes), to }); m_longestSequence = std::max(m_longestSequence, keySize); m_shortestSequence = std::min(m_shortestSequence, keySize); } } }