impr: Properly display custom encoding characters that are split between lines
This commit is contained in:
parent
bd190d2b65
commit
3a840c4ced
@ -24,6 +24,7 @@ namespace hex {
|
||||
EncodingFile(Type type, const std::fs::path &path);
|
||||
|
||||
[[nodiscard]] std::pair<std::string_view, size_t> getEncodingFor(std::span<u8> buffer) const;
|
||||
[[nodiscard]] size_t getEncodingLengthFor(std::span<u8> buffer) const;
|
||||
[[nodiscard]] size_t getLongestSequence() const { return this->m_longestSequence; }
|
||||
|
||||
[[nodiscard]] bool valid() const { return this->m_valid; }
|
||||
|
@ -26,7 +26,7 @@ namespace hex {
|
||||
|
||||
if (size > buffer.size()) continue;
|
||||
|
||||
auto key = std::vector<u8>(buffer.begin(), buffer.begin() + size);
|
||||
std::vector<u8> key(buffer.begin(), buffer.begin() + size);
|
||||
if (mapping.contains(key))
|
||||
return { mapping.at(key), size };
|
||||
}
|
||||
@ -34,6 +34,20 @@ namespace hex {
|
||||
return { ".", 1 };
|
||||
}
|
||||
|
||||
size_t EncodingFile::getEncodingLengthFor(std::span<u8> buffer) const {
|
||||
for (auto riter = this->m_mapping.crbegin(); riter != this->m_mapping.crend(); ++riter) {
|
||||
const auto &[size, mapping] = *riter;
|
||||
|
||||
if (size > buffer.size()) continue;
|
||||
|
||||
std::vector<u8> key(buffer.begin(), buffer.begin() + size);
|
||||
if (mapping.contains(key))
|
||||
return size;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void EncodingFile::parseThingyFile(wolv::io::File &file) {
|
||||
for (const auto &line : splitString(file.readString(), "\n")) {
|
||||
|
||||
@ -60,9 +74,11 @@ namespace hex {
|
||||
|
||||
if (!this->m_mapping.contains(fromBytes.size()))
|
||||
this->m_mapping.insert({ fromBytes.size(), {} });
|
||||
this->m_mapping[fromBytes.size()].insert({ fromBytes, to });
|
||||
|
||||
this->m_longestSequence = std::max(this->m_longestSequence, fromBytes.size());
|
||||
auto keySize = fromBytes.size();
|
||||
this->m_mapping[keySize].insert({ std::move(fromBytes), to });
|
||||
|
||||
this->m_longestSequence = std::max(this->m_longestSequence, keySize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,7 @@ namespace hex::plugin::builtin::ui {
|
||||
|
||||
void setCustomEncoding(EncodingFile encoding) {
|
||||
this->m_currCustomEncoding = std::move(encoding);
|
||||
this->m_encodingLineStartAddresses.clear();
|
||||
}
|
||||
|
||||
void forceUpdateScrollPosition() {
|
||||
@ -202,6 +203,7 @@ namespace hex::plugin::builtin::ui {
|
||||
u32 m_byteCellPadding = 0, m_characterCellPadding = 0;
|
||||
|
||||
std::optional<EncodingFile> m_currCustomEncoding;
|
||||
std::vector<u64> m_encodingLineStartAddresses;
|
||||
|
||||
std::pair<Region, bool> m_currValidRegion = { Region::Invalid(), false };
|
||||
|
||||
|
@ -93,8 +93,10 @@ namespace hex::plugin::builtin::ui {
|
||||
{
|
||||
auto bytesPerRow = ContentRegistry::Settings::getSetting("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.bytes_per_row");
|
||||
|
||||
if (bytesPerRow.is_number())
|
||||
if (bytesPerRow.is_number()) {
|
||||
this->m_bytesPerRow = static_cast<int>(bytesPerRow);
|
||||
this->m_encodingLineStartAddresses.clear();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
@ -195,12 +197,34 @@ namespace hex::plugin::builtin::ui {
|
||||
ImColor color;
|
||||
};
|
||||
|
||||
static CustomEncodingData queryCustomEncodingData(prv::Provider *provider, const EncodingFile &encodingFile, u64 address) {
|
||||
static CustomEncodingData queryCustomEncodingData(prv::Provider *provider, const EncodingFile &encodingFile, std::vector<u64> &lineStartAddresses, u32 bytesPerRow, u64 address) {
|
||||
const auto longestSequence = encodingFile.getLongestSequence();
|
||||
|
||||
if (longestSequence == 0)
|
||||
return { ".", 1, 0xFFFF8000 };
|
||||
|
||||
if (lineStartAddresses.empty() || lineStartAddresses.size() <= address / bytesPerRow) {
|
||||
auto prevSize = lineStartAddresses.size();
|
||||
auto newSize = address / bytesPerRow + 1;
|
||||
lineStartAddresses.reserve(newSize);
|
||||
|
||||
std::vector<u8> buffer;
|
||||
for (auto i = prevSize; i < newSize; i++) {
|
||||
u32 offset = 0;
|
||||
while (offset < bytesPerRow) {
|
||||
size_t readSize = std::min<size_t>(longestSequence, provider->getActualSize() - address);
|
||||
buffer.resize(readSize);
|
||||
provider->read(address, buffer.data(), readSize);
|
||||
|
||||
offset += encodingFile.getEncodingLengthFor(buffer);
|
||||
}
|
||||
|
||||
lineStartAddresses.push_back(offset % bytesPerRow);
|
||||
}
|
||||
}
|
||||
|
||||
address += lineStartAddresses[address / bytesPerRow];
|
||||
|
||||
size_t size = std::min<size_t>(longestSequence, provider->getActualSize() - address);
|
||||
|
||||
std::vector<u8> buffer(size);
|
||||
@ -560,7 +584,7 @@ namespace hex::plugin::builtin::ui {
|
||||
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, this->m_encodingLineStartAddresses, this->m_bytesPerRow, address);
|
||||
offset += std::max<size_t>(1, result.advance);
|
||||
|
||||
encodingData.emplace_back(address, result);
|
||||
|
Loading…
x
Reference in New Issue
Block a user