diff --git a/lib/libimhex/include/hex/helpers/encoding_file.hpp b/lib/libimhex/include/hex/helpers/encoding_file.hpp index 4dc5fea78..e650712ab 100644 --- a/lib/libimhex/include/hex/helpers/encoding_file.hpp +++ b/lib/libimhex/include/hex/helpers/encoding_file.hpp @@ -20,10 +20,15 @@ namespace hex { Thingy }; - EncodingFile() = default; + EncodingFile(); + EncodingFile(const EncodingFile &other); + EncodingFile(EncodingFile &&other); EncodingFile(Type type, const std::fs::path &path); EncodingFile(Type type, const std::string &path); + EncodingFile& operator=(const EncodingFile &other); + EncodingFile& operator=(EncodingFile &&other); + [[nodiscard]] std::pair getEncodingFor(std::span buffer) const; [[nodiscard]] size_t getEncodingLengthFor(std::span buffer) const; [[nodiscard]] size_t getLongestSequence() const { return this->m_longestSequence; } @@ -38,7 +43,7 @@ namespace hex { bool m_valid = false; std::string m_tableContent; - std::map, std::string>> m_mapping; + std::unique_ptr, std::string>>> m_mapping; size_t m_longestSequence = 0; }; diff --git a/lib/libimhex/source/helpers/encoding_file.cpp b/lib/libimhex/source/helpers/encoding_file.cpp index 7e0339360..1a1fc49fc 100644 --- a/lib/libimhex/source/helpers/encoding_file.cpp +++ b/lib/libimhex/source/helpers/encoding_file.cpp @@ -7,7 +7,25 @@ namespace hex { - EncodingFile::EncodingFile(Type type, const std::fs::path &path) { + EncodingFile::EncodingFile() : m_mapping(std::make_unique, std::string>>>()) { + + } + + EncodingFile::EncodingFile(const hex::EncodingFile &other) { + this->m_mapping = std::make_unique, std::string>>>(*other.m_mapping); + this->m_tableContent = other.m_tableContent; + this->m_longestSequence = other.m_longestSequence; + this->m_valid = other.m_valid; + } + + EncodingFile::EncodingFile(EncodingFile &&other) { + this->m_mapping = std::move(other.m_mapping); + this->m_tableContent = std::move(other.m_tableContent); + this->m_longestSequence = other.m_longestSequence; + this->m_valid = other.m_valid; + } + + 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: @@ -20,7 +38,7 @@ namespace hex { this->m_valid = true; } - EncodingFile::EncodingFile(Type type, const std::string &content) { + EncodingFile::EncodingFile(Type type, const std::string &content) : EncodingFile() { switch (type) { case Type::Thingy: parse(content); @@ -32,8 +50,29 @@ namespace hex { this->m_valid = true; } + + EncodingFile &EncodingFile::operator=(const hex::EncodingFile &other) { + this->m_mapping = std::make_unique, std::string>>>(*other.m_mapping); + this->m_tableContent = other.m_tableContent; + this->m_longestSequence = other.m_longestSequence; + this->m_valid = other.m_valid; + + return *this; + } + + EncodingFile &EncodingFile::operator=(EncodingFile &&other) { + this->m_mapping = std::move(other.m_mapping); + this->m_tableContent = std::move(other.m_tableContent); + this->m_longestSequence = other.m_longestSequence; + this->m_valid = other.m_valid; + + return *this; + } + + + std::pair EncodingFile::getEncodingFor(std::span buffer) const { - for (auto riter = this->m_mapping.crbegin(); riter != this->m_mapping.crend(); ++riter) { + for (auto riter = this->m_mapping->crbegin(); riter != this->m_mapping->crend(); ++riter) { const auto &[size, mapping] = *riter; if (size > buffer.size()) continue; @@ -47,7 +86,7 @@ namespace hex { } size_t EncodingFile::getEncodingLengthFor(std::span buffer) const { - for (auto riter = this->m_mapping.crbegin(); riter != this->m_mapping.crend(); ++riter) { + for (auto riter = this->m_mapping->crbegin(); riter != this->m_mapping->crend(); ++riter) { const auto &[size, mapping] = *riter; if (size > buffer.size()) continue; @@ -85,11 +124,11 @@ namespace hex { if (to.empty()) to = " "; - if (!this->m_mapping.contains(fromBytes.size())) - this->m_mapping.insert({ fromBytes.size(), {} }); + if (!this->m_mapping->contains(fromBytes.size())) + this->m_mapping->insert({ fromBytes.size(), {} }); auto keySize = fromBytes.size(); - this->m_mapping[keySize].insert({ std::move(fromBytes), to }); + (*this->m_mapping)[keySize].insert({ std::move(fromBytes), to }); this->m_longestSequence = std::max(this->m_longestSequence, keySize); } diff --git a/plugins/builtin/source/ui/hex_editor.cpp b/plugins/builtin/source/ui/hex_editor.cpp index 953704469..23f7d924a 100644 --- a/plugins/builtin/source/ui/hex_editor.cpp +++ b/plugins/builtin/source/ui/hex_editor.cpp @@ -499,65 +499,67 @@ namespace hex::plugin::builtin::ui { this->m_encodingLineStartAddresses.push_back(0); } - if (this->m_encodingLineStartAddresses[y] >= this->m_bytesPerRow) { - encodingData.emplace_back(y * this->m_bytesPerRow + this->m_provider->getBaseAddress() + this->m_provider->getCurrentPageAddress(), CustomEncodingData(".", 1, ImGui::GetCustomColorU32(ImGuiCustomCol_ToolbarRed))); - this->m_encodingLineStartAddresses.push_back(0); - } else { - u32 offset = this->m_encodingLineStartAddresses[y]; - do { - const u64 address = y * this->m_bytesPerRow + offset + this->m_provider->getBaseAddress() + this->m_provider->getCurrentPageAddress(); + if (y < this->m_encodingLineStartAddresses.size()) { + if (this->m_encodingLineStartAddresses[y] >= this->m_bytesPerRow) { + encodingData.emplace_back(y * this->m_bytesPerRow + this->m_provider->getBaseAddress() + this->m_provider->getCurrentPageAddress(), CustomEncodingData(".", 1, ImGui::GetCustomColorU32(ImGuiCustomCol_ToolbarRed))); + this->m_encodingLineStartAddresses.push_back(0); + } else { + u32 offset = this->m_encodingLineStartAddresses[y]; + do { + const u64 address = y * this->m_bytesPerRow + offset + this->m_provider->getBaseAddress() + this->m_provider->getCurrentPageAddress(); - auto result = queryCustomEncodingData(this->m_provider, *this->m_currCustomEncoding, address); + auto result = queryCustomEncodingData(this->m_provider, *this->m_currCustomEncoding, address); - offset += result.advance; - encodingData.emplace_back(address, result); - } while (offset < this->m_bytesPerRow); + offset += result.advance; + encodingData.emplace_back(address, result); + } while (offset < this->m_bytesPerRow); - this->m_encodingLineStartAddresses.push_back(offset - this->m_bytesPerRow); - } - - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(0, 0)); - ImGui::PushID(y); - if (ImGui::BeginTable("##encoding_cell", encodingData.size(), ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoKeepColumnsVisible)) { - ImGui::TableNextRow(); - - for (const auto &[address, data] : encodingData) { - ImGui::TableNextColumn(); - - const auto cellStartPos = getCellPosition(); - const auto cellSize = ImGui::CalcTextSize(data.displayValue.c_str()) * ImVec2(1, 0) + ImVec2(this->m_characterCellPadding * 1_scaled, CharacterSize.y); - const bool cellHovered = ImGui::IsMouseHoveringRect(cellStartPos, cellStartPos + cellSize, true); - - const auto x = address % this->m_bytesPerRow; - if (x < validBytes && isCurrRegionValid(address)) { - auto [foregroundColor, backgroundColor] = cellColors[x / bytesPerCell]; - - backgroundColor = applySelectionColor(address, backgroundColor); - - // Draw highlights and selection - if (backgroundColor.has_value()) { - auto drawList = ImGui::GetWindowDrawList(); - - // Draw background color - drawList->AddRectFilled(cellStartPos, cellStartPos + cellSize, backgroundColor.value()); - - this->drawSelectionFrame(x, y, address, 1, cellStartPos, cellSize); - } - - auto startPos = ImGui::GetCursorPos(); - ImGui::TextFormattedColored(data.color, "{}", data.displayValue); - ImGui::SetCursorPosX(startPos.x + cellSize.x); - ImGui::SameLine(0, 0); - ImGui::Dummy({ 0, 0 }); - - this->handleSelection(address, data.advance, &bytes[address % this->m_bytesPerRow], cellHovered); - } + this->m_encodingLineStartAddresses.push_back(offset - this->m_bytesPerRow); } - ImGui::EndTable(); + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(0, 0)); + ImGui::PushID(y); + if (ImGui::BeginTable("##encoding_cell", encodingData.size(), ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoKeepColumnsVisible)) { + ImGui::TableNextRow(); + + for (const auto &[address, data] : encodingData) { + ImGui::TableNextColumn(); + + const auto cellStartPos = getCellPosition(); + const auto cellSize = ImGui::CalcTextSize(data.displayValue.c_str()) * ImVec2(1, 0) + ImVec2(this->m_characterCellPadding * 1_scaled, CharacterSize.y); + const bool cellHovered = ImGui::IsMouseHoveringRect(cellStartPos, cellStartPos + cellSize, true); + + const auto x = address % this->m_bytesPerRow; + if (x < validBytes && isCurrRegionValid(address)) { + auto [foregroundColor, backgroundColor] = cellColors[x / bytesPerCell]; + + backgroundColor = applySelectionColor(address, backgroundColor); + + // Draw highlights and selection + if (backgroundColor.has_value()) { + auto drawList = ImGui::GetWindowDrawList(); + + // Draw background color + drawList->AddRectFilled(cellStartPos, cellStartPos + cellSize, backgroundColor.value()); + + this->drawSelectionFrame(x, y, address, 1, cellStartPos, cellSize); + } + + auto startPos = ImGui::GetCursorPos(); + ImGui::TextFormattedColored(data.color, "{}", data.displayValue); + ImGui::SetCursorPosX(startPos.x + cellSize.x); + ImGui::SameLine(0, 0); + ImGui::Dummy({ 0, 0 }); + + this->handleSelection(address, data.advance, &bytes[address % this->m_bytesPerRow], cellHovered); + } + } + + ImGui::EndTable(); + } + ImGui::PopStyleVar(); + ImGui::PopID(); } - ImGui::PopStyleVar(); - ImGui::PopID(); } // Scroll to the cursor if it's either at the top or bottom edge of the screen