diff --git a/plugins/builtin/include/content/views/view_hexeditor.hpp b/plugins/builtin/include/content/views/view_hexeditor.hpp index 9ce66f2cc..7f7e379e9 100644 --- a/plugins/builtin/include/content/views/view_hexeditor.hpp +++ b/plugins/builtin/include/content/views/view_hexeditor.hpp @@ -30,8 +30,6 @@ namespace hex::plugin::builtin { private: MemoryEditor m_memoryEditor; - std::map m_highlightedBytes; - std::vector m_searchStringBuffer; std::vector m_searchHexBuffer; SearchFunction m_searchFunction = nullptr; @@ -47,6 +45,7 @@ namespace hex::plugin::builtin { u64 m_resizeSize = 0; std::vector m_dataToSave; + std::set m_highlightedPatterns; std::string m_loaderScriptScriptPath; std::string m_loaderScriptFilePath; diff --git a/plugins/builtin/source/content/views/view_hexeditor.cpp b/plugins/builtin/source/content/views/view_hexeditor.cpp index e6cd79c89..3d92aa380 100644 --- a/plugins/builtin/source/content/views/view_hexeditor.cpp +++ b/plugins/builtin/source/content/views/view_hexeditor.cpp @@ -75,13 +75,24 @@ namespace hex::plugin::builtin { prevColor = (color & 0x00FFFFFF) | alpha; } - if (_this->m_highlightedBytes.contains(off)) { - auto color = (_this->m_highlightedBytes[off] & 0x00FFFFFF) | alpha; - currColor = currColor.has_value() ? ImAlphaBlendColors(color, currColor.value()) : color; - } - if (_this->m_highlightedBytes.contains(off - 1)) { - auto color = (_this->m_highlightedBytes[off - 1] & 0x00FFFFFF) | alpha; - prevColor = prevColor.has_value() ? ImAlphaBlendColors(color, prevColor.value()) : color; + { + for (const auto &pattern : SharedData::patternData) { + auto child = pattern->getPattern(off); + if (child != nullptr) { + auto color = (child->getColor() & 0x00FFFFFF) | alpha; + currColor = currColor.has_value() ? ImAlphaBlendColors(color, currColor.value()) : color; + break; + } + } + + for (const auto &pattern : SharedData::patternData) { + auto child = pattern->getPattern(off - 1); + if (child != nullptr) { + auto color = (child->getColor() & 0x00FFFFFF) | alpha; + prevColor = prevColor.has_value() ? ImAlphaBlendColors(color, currColor.value()) : color; + break; + } + } } if (next && prevColor != currColor) { @@ -151,7 +162,6 @@ namespace hex::plugin::builtin { EventManager::unsubscribe(this); EventManager::unsubscribe(this); EventManager::unsubscribe(this); - EventManager::unsubscribe(this); EventManager::unsubscribe(this); EventManager::unsubscribe(this); } @@ -642,7 +652,11 @@ namespace hex::plugin::builtin { EventManager::post(path); EventManager::post(); - EventManager::post(); + + { + std::vector patterns; + EventManager::post(patterns); + } } bool ViewHexEditor::saveToFile(const std::string &path, const std::vector& data) { @@ -1282,14 +1296,6 @@ R"( } }); - EventManager::subscribe(this, [this]() { - this->m_highlightedBytes.clear(); - - for (const auto &pattern : SharedData::patternData) { - this->m_highlightedBytes.merge(pattern->getHighlightedAddresses()); - } - }); - EventManager::subscribe(this, [this](std::string name) { if (name == "Create File") { hex::openFileBrowser("hex.builtin.view.hexeditor.create_file"_lang, DialogMode::Save, { }, [this](auto path) { diff --git a/plugins/builtin/source/content/views/view_pattern_data.cpp b/plugins/builtin/source/content/views/view_pattern_data.cpp index 8dcbf97a8..cfc95e4f5 100644 --- a/plugins/builtin/source/content/views/view_pattern_data.cpp +++ b/plugins/builtin/source/content/views/view_pattern_data.cpp @@ -7,7 +7,7 @@ namespace hex::plugin::builtin { ViewPatternData::ViewPatternData() : View("hex.builtin.view.pattern_data.name") { - EventManager::subscribe(this, [this]() { + EventManager::subscribe(this, [this](auto&) { this->m_sortedPatternData.clear(); }); } diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 3fa7bb36c..c1dc5505b 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -661,7 +661,11 @@ namespace hex::plugin::builtin { this->m_textEditor.SetErrorMarkers({ }); this->m_console.clear(); this->clearPatternData(); - EventManager::post(); + + { + std::vector patterns; + EventManager::post(patterns); + } std::thread([this, code] { std::map envVars; @@ -691,7 +695,7 @@ namespace hex::plugin::builtin { if (result.has_value()) { SharedData::patternData = std::move(result.value()); - EventManager::post(); + EventManager::post(SharedData::patternData); } this->m_evaluatorRunning = false; diff --git a/plugins/libimhex/include/hex/api/event.hpp b/plugins/libimhex/include/hex/api/event.hpp index 316151145..218f3a819 100644 --- a/plugins/libimhex/include/hex/api/event.hpp +++ b/plugins/libimhex/include/hex/api/event.hpp @@ -95,11 +95,13 @@ namespace hex { static EventList s_events; }; + namespace pl { class PatternData; } + /* Default Events */ EVENT_DEF(EventFileLoaded, std::string); EVENT_DEF(EventFileUnloaded); EVENT_DEF(EventDataChanged); - EVENT_DEF(EventPatternChanged); + EVENT_DEF(EventPatternChanged, std::vector&); EVENT_DEF(EventWindowClosing, GLFWwindow*); EVENT_DEF(EventRegionSelected, Region); EVENT_DEF(EventProjectFileStore); diff --git a/plugins/libimhex/include/hex/pattern_language/ast_node.hpp b/plugins/libimhex/include/hex/pattern_language/ast_node.hpp index 504250a76..6caa3b697 100644 --- a/plugins/libimhex/include/hex/pattern_language/ast_node.hpp +++ b/plugins/libimhex/include/hex/pattern_language/ast_node.hpp @@ -15,31 +15,10 @@ namespace hex::pl { - class ASTNode; - class ASTNodeAttribute; - class PatternData; class Evaluator; - class Attributable { - protected: - Attributable() = default; - - Attributable(const Attributable &) = default; - - public: - - void addAttribute(ASTNodeAttribute *attribute) { - this->m_attributes.push_back(attribute); - } - - [[nodiscard]] const auto &getAttributes() const { - return this->m_attributes; - } - - private: - std::vector m_attributes; - }; + class ASTNode; class Clonable { public: @@ -99,6 +78,33 @@ namespace hex::pl { std::optional m_value; }; + class Attributable { + protected: + Attributable() = default; + ~Attributable() { + for (auto &attribute : this->m_attributes) + delete attribute; + } + + Attributable(const Attributable &other) { + for (auto &attribute : other.m_attributes) + this->m_attributes.push_back(static_cast(attribute->clone())); + } + + public: + + void addAttribute(ASTNodeAttribute *attribute) { + this->m_attributes.push_back(attribute); + } + + [[nodiscard]] const auto &getAttributes() const { + return this->m_attributes; + } + + private: + std::vector m_attributes; + }; + class ASTNodeLiteral : public ASTNode { public: explicit ASTNodeLiteral(Token::Literal literal) : ASTNode(), m_literal(literal) { } @@ -429,7 +435,14 @@ namespace hex::pl { [[nodiscard]] std::optional getEndian() const { return this->m_endian; } [[nodiscard]] ASTNode *evaluate(Evaluator *evaluator) const override { - return this->m_type->evaluate(evaluator); + auto type = this->m_type->evaluate(evaluator); + + if (auto attributable = dynamic_cast(type)) { + for (auto &attribute : this->getAttributes()) + attributable->addAttribute(static_cast(attribute->clone())); + } + + return type; } [[nodiscard]] std::vector createPatterns(Evaluator *evaluator) const override { @@ -978,7 +991,6 @@ namespace hex::pl { delete entries.back(); entries.pop_back(); entryIndex--; - }; if (this->m_size != nullptr) { diff --git a/plugins/libimhex/include/hex/pattern_language/pattern_data.hpp b/plugins/libimhex/include/hex/pattern_language/pattern_data.hpp index 1bb2e308f..af7a2a678 100644 --- a/plugins/libimhex/include/hex/pattern_language/pattern_data.hpp +++ b/plugins/libimhex/include/hex/pattern_language/pattern_data.hpp @@ -101,7 +101,7 @@ namespace hex::pl { virtual PatternData* clone() = 0; [[nodiscard]] u64 getOffset() const { return this->m_offset; } - void setOffset(u64 offset) { this->m_offset = offset; } + virtual void setOffset(u64 offset) { this->m_offset = offset; } [[nodiscard]] size_t getSize() const { return this->m_size; } void setSize(size_t size) { this->m_size = size; } @@ -135,14 +135,21 @@ namespace hex::pl { virtual void createEntry(prv::Provider* &provider) = 0; [[nodiscard]] virtual std::string getFormattedName() const = 0; - virtual std::map getHighlightedAddresses() { - if (this->isHidden()) return { }; + [[nodiscard]] + virtual const PatternData* getPattern(u64 offset) const { + if (offset >= this->getOffset() && offset < (this->getOffset() + this->getSize())) + return this; + else + return nullptr; + } + + virtual void getHighlightedAddresses(std::map &highlight) const { + if (this->isHidden()) return; - std::map result; for (u64 i = 0; i < this->getSize(); i++) - result.insert({ this->getOffset() + i, this->getColor() }); + highlight.insert({ this->getOffset() + i, this->getColor() }); - return result; + this->m_evaluator->handleAbort(); } virtual void sort(ImGuiTableSortSpecs *sortSpecs, prv::Provider *provider) { } @@ -382,14 +389,11 @@ namespace hex::pl { } } - std::map getHighlightedAddresses() override { - auto ownAddresses = PatternData::getHighlightedAddresses(); - auto pointedToAddresses = this->m_pointedAt->getHighlightedAddresses(); - - ownAddresses.merge(pointedToAddresses); - - return ownAddresses; + void getHighlightedAddresses(std::map &highlight) const override { + PatternData::getHighlightedAddresses(highlight); + this->m_pointedAt->getHighlightedAddresses(highlight); } + [[nodiscard]] std::string getFormattedName() const override { std::string result = this->m_pointedAt->getFormattedName() + "* : "; switch (this->getSize()) { @@ -440,6 +444,14 @@ namespace hex::pl { this->m_pointerBase = base; } + [[nodiscard]] + const PatternData* getPattern(u64 offset) const override { + if (offset >= this->getOffset() && offset < (this->getOffset() + this->getSize())) + return this; + else + return this->m_pointedAt->getPattern(offset); + } + private: PatternData *m_pointedAt = nullptr; u64 m_pointedAtAddress = 0; @@ -807,20 +819,23 @@ namespace hex::pl { } } - std::map getHighlightedAddresses() override { - std::map result; - + void getHighlightedAddresses(std::map &highlight) const override { for (auto &entry : this->m_entries) { - result.merge(entry->getHighlightedAddresses()); + entry->getHighlightedAddresses(highlight); } - - return result; } [[nodiscard]] std::string getFormattedName() const override { return this->m_entries[0]->getTypeName() + "[" + std::to_string(this->m_entries.size()) + "]"; } + void setOffset(u64 offset) override { + for (auto &entry : this->m_entries) + entry->setOffset(entry->getOffset() - this->getOffset() + offset); + + PatternData::setOffset(offset); + } + [[nodiscard]] const std::vector& getEntries() { return this->m_entries; } @@ -851,6 +866,18 @@ namespace hex::pl { return true; } + [[nodiscard]] + const PatternData* getPattern(u64 offset) const override { + auto iter = std::find_if(this->m_entries.begin(), this->m_entries.end(), [this, offset](PatternData *pattern){ + return offset >= this->getOffset() && offset < (this->getOffset() + this->getSize()); + }); + + if (iter == this->m_entries.end()) + return nullptr; + else + return *iter; + } + private: std::vector m_entries; u64 m_displayEnd = 50; @@ -868,6 +895,7 @@ namespace hex::pl { ~PatternDataStaticArray() override { delete this->m_template; + delete this->m_highlightTemplate; } PatternData* clone() override { @@ -932,18 +960,21 @@ namespace hex::pl { } } - std::map getHighlightedAddresses() override { - auto startOffset = this->m_template->getOffset(); + void getHighlightedAddresses(std::map &highlight) const override { + auto entry = this->m_template->clone(); - std::map result; - for (u64 address = this->getOffset(); address < this->getOffset() + this->getSize(); address += this->m_template->getSize()) { - this->m_template->setOffset(address); - result.merge(this->m_template->getHighlightedAddresses()); + for (u64 address = this->getOffset(); address < this->getOffset() + this->getSize(); address += entry->getSize()) { + entry->setOffset(address); + entry->getHighlightedAddresses(highlight); } - this->m_template->setOffset(startOffset); + delete entry; + } - return result; + void setOffset(u64 offset) override { + this->m_template->setOffset(this->m_template->getOffset() - this->getOffset() + offset); + + PatternData::setOffset(offset); } void setColor(u32 color) override { @@ -969,6 +1000,7 @@ namespace hex::pl { void setEntries(PatternData* templ, size_t count) { this->m_template = templ; + this->m_highlightTemplate = this->m_template->clone(); this->m_entryCount = count; if (this->hasOverriddenColor()) this->setColor(this->m_template->getColor()); @@ -983,8 +1015,19 @@ namespace hex::pl { return *this->m_template == *otherArray.m_template && this->m_entryCount == otherArray.m_entryCount; } + [[nodiscard]] + const PatternData* getPattern(u64 offset) const override { + if (offset >= this->getOffset() && offset < (this->getOffset() + this->getSize())) { + this->m_highlightTemplate->setOffset((offset / this->m_highlightTemplate->getSize()) * this->m_highlightTemplate->getSize()); + return this->m_highlightTemplate; + } else { + return nullptr; + } + } + private: PatternData *m_template; + mutable PatternData *m_highlightTemplate; size_t m_entryCount; u64 m_displayEnd = 50; }; @@ -1039,13 +1082,17 @@ namespace hex::pl { } - std::map getHighlightedAddresses() override { - std::map result; + void getHighlightedAddresses(std::map &highlight) const override { for (auto &member : this->m_members) { - result.merge(member->getHighlightedAddresses()); + member->getHighlightedAddresses(highlight); } + } - return result; + void setOffset(u64 offset) override { + for (auto &member : this->m_members) + member->setOffset(member->getOffset() - this->getOffset() + offset); + + PatternData::setOffset(offset); } void setColor(u32 color) override { @@ -1101,6 +1148,19 @@ namespace hex::pl { return true; } + [[nodiscard]] + const PatternData* getPattern(u64 offset) const override { + + auto iter = std::find_if(this->m_members.begin(), this->m_members.end(), [offset](PatternData *pattern){ + return offset >= pattern->getOffset() && offset < (pattern->getOffset() + pattern->getSize()); + }); + + if (iter == this->m_members.end()) + return nullptr; + else + return *iter; + } + private: std::vector m_members; std::vector m_sortedMembers; @@ -1158,14 +1218,17 @@ namespace hex::pl { } - std::map getHighlightedAddresses() override { - std::map result; - + void getHighlightedAddresses(std::map &highlight) const override { for (auto &member : this->m_members) { - result.merge(member->getHighlightedAddresses()); + member->getHighlightedAddresses(highlight); } + } - return result; + void setOffset(u64 offset) override { + for (auto &member : this->m_members) + member->setOffset(member->getOffset() - this->getOffset() + offset); + + PatternData::setOffset(offset); } void setColor(u32 color) override { @@ -1220,6 +1283,19 @@ namespace hex::pl { return true; } + [[nodiscard]] + const PatternData* getPattern(u64 offset) const override { + + auto largestMember = std::find_if(this->m_members.begin(), this->m_members.end(), [this](PatternData *pattern) { + return pattern->getSize() == this->getSize(); + }); + + if (largestMember == this->m_members.end()) + return nullptr; + else + return *largestMember; + } + private: std::vector m_members; std::vector m_sortedMembers; @@ -1451,6 +1527,13 @@ namespace hex::pl { } + void setOffset(u64 offset) override { + for (auto &field : this->m_fields) + field->setOffset(field->getOffset() - this->getOffset() + offset); + + PatternData::setOffset(offset); + } + [[nodiscard]] std::string getFormattedName() const override { return "bitfield " + PatternData::getTypeName(); }