impr: Replace horrible pattern extra data class with a more modular system

This commit is contained in:
WerWolv
2023-04-17 16:18:48 +02:00
parent 535aeb5e39
commit 99a736df27
26 changed files with 705 additions and 720 deletions

View File

@@ -1,145 +0,0 @@
#pragma once
#include <hex/api/content_registry.hpp>
#include <hex/providers/provider.hpp>
#include <pl/pattern_language.hpp>
#include <hex/data_processor/attribute.hpp>
#include <hex/data_processor/node.hpp>
#include <hex/data_processor/link.hpp>
#include <hex/helpers/logger.hpp>
#include <map>
#include <imnodes.h>
#include <imnodes_internal.h>
namespace hex::plugin::builtin {
class ProviderExtraData {
public:
struct Data {
Data() : patternLanguage(), bookmarks(), dataProcessor(), editor(), hashes(), yara() {
log::debug("Creating new extra data instance");
}
bool dataDirty = false;
struct PatternLanguage {
struct PatternVariable {
bool inVariable;
bool outVariable;
pl::core::Token::ValueType type;
pl::core::Token::Literal value;
};
enum class EnvVarType
{
Integer,
Float,
String,
Bool
};
struct EnvVar {
u64 id;
std::string name;
pl::core::Token::Literal value;
EnvVarType type;
bool operator==(const EnvVar &other) const {
return this->id == other.id;
}
};
std::string sourceCode;
std::mutex runtimeMutex;
std::unique_ptr<pl::PatternLanguage> runtime = std::make_unique<pl::PatternLanguage>();
std::vector<std::pair<pl::core::LogConsole::Level, std::string>> console;
bool executionDone = true;
std::optional<pl::core::err::PatternLanguageError> lastEvaluationError;
std::vector<std::pair<pl::core::LogConsole::Level, std::string>> lastEvaluationLog;
std::map<std::string, pl::core::Token::Literal> lastEvaluationOutVars;
std::map<std::string, PatternVariable> patternVariables;
std::map<u64, pl::api::Section> sections;
std::list<EnvVar> envVarEntries;
} patternLanguage;
std::list<ImHexApi::Bookmarks::Entry> bookmarks;
struct DataProcessor {
struct Workspace {
std::unique_ptr<ImNodesContext, void(*)(ImNodesContext*)> context = { []{
ImNodesContext *ctx = ImNodes::CreateContext();
ctx->Style = ImNodes::GetStyle();
ctx->Io = ImNodes::GetIO();
ctx->AttributeFlagStack = GImNodes->AttributeFlagStack;
return ctx;
}(), ImNodes::DestroyContext };
std::list<std::unique_ptr<dp::Node>> nodes;
std::list<dp::Node*> endNodes;
std::list<dp::Link> links;
std::vector<hex::prv::Overlay *> dataOverlays;
std::optional<dp::Node::NodeError> currNodeError;
};
Workspace mainWorkspace;
std::vector<Workspace*> workspaceStack;
} dataProcessor;
struct HexEditor {
std::optional<u64> selectionStart = std::nullopt, selectionEnd = std::nullopt;
float scrollPosition = 0.0F;
} editor;
struct Hashes {
std::vector<ContentRegistry::Hashes::Hash::Function> hashFunctions;
} hashes;
struct Yara {
struct YaraMatch {
std::string identifier;
std::string variable;
u64 address;
size_t size;
bool wholeDataMatch;
mutable u32 highlightId;
mutable u32 tooltipId;
};
std::vector<std::pair<std::fs::path, std::fs::path>> rules;
std::vector<YaraMatch> matches;
std::vector<YaraMatch*> sortedMatches;
} yara;
};
static Data& getCurrent() {
return get(ImHexApi::Provider::get());
}
static Data& get(const hex::prv::Provider *provider) {
return s_data[provider];
}
static void erase(hex::prv::Provider *provider) {
s_data.erase(provider);
}
static bool markDirty() {
return getCurrent().dataDirty = true;
}
private:
ProviderExtraData() = default;
static inline std::map<const hex::prv::Provider*, Data> s_data = {};
};
}

View File

@@ -10,7 +10,7 @@ namespace hex::plugin::builtin {
class PopupFileChooser : public Popup<PopupFileChooser> {
public:
PopupFileChooser(const std::vector<std::fs::path> &files, const std::vector<nfdfilteritem_t> &validExtensions, bool multiple, const std::function<void(std::fs::path)> &callback)
: hex::Popup<PopupFileChooser>("hex.builtin.common.choose_file", false),
: hex::Popup<PopupFileChooser>("hex.builtin.common.choose_file"),
m_indices({ }), m_files(files),
m_openCallback(callback),
m_validExtensions(validExtensions), m_multiple(multiple) { }

View File

@@ -15,14 +15,15 @@ namespace hex::plugin::builtin {
void drawContent() override;
private:
static bool importBookmarks(hex::prv::Provider *provider, const nlohmann::json &json);
static bool exportBookmarks(hex::prv::Provider *provider, nlohmann::json &json);
bool importBookmarks(hex::prv::Provider *provider, const nlohmann::json &json);
bool exportBookmarks(hex::prv::Provider *provider, nlohmann::json &json);
void registerMenuItems();
private:
std::string m_currFilter;
std::list<ImHexApi::Bookmarks::Entry>::iterator m_dragStartIterator;
PerProvider<std::list<ImHexApi::Bookmarks::Entry>> m_bookmarks;
};
}

View File

@@ -7,7 +7,7 @@
#include <hex/data_processor/node.hpp>
#include <hex/data_processor/link.hpp>
#include "content/helpers/provider_extra_data.hpp"
#include <imnodes_internal.h>
#include <array>
#include <string>
@@ -16,8 +16,26 @@ namespace hex::plugin::builtin {
class ViewDataProcessor : public View {
public:
using Workspace = ProviderExtraData::Data::DataProcessor::Workspace;
struct Workspace {
Workspace() = default;
std::unique_ptr<ImNodesContext, void(*)(ImNodesContext*)> context = { []{
ImNodesContext *ctx = ImNodes::CreateContext();
ctx->Style = ImNodes::GetStyle();
ctx->Io = ImNodes::GetIO();
ctx->AttributeFlagStack = GImNodes->AttributeFlagStack;
return ctx;
}(), ImNodes::DestroyContext };
std::list<std::unique_ptr<dp::Node>> nodes;
std::list<dp::Node*> endNodes;
std::list<dp::Link> links;
std::vector<hex::prv::Overlay *> dataOverlays;
std::optional<dp::Node::NodeError> currNodeError;
};
public:
ViewDataProcessor();
~ViewDataProcessor() override;
@@ -29,12 +47,14 @@ namespace hex::plugin::builtin {
static std::unique_ptr<dp::Node> loadNode(const nlohmann::json &data);
static void loadNodes(Workspace &workspace, const nlohmann::json &data);
private:
static void eraseLink(Workspace &workspace, int id);
static void eraseNodes(Workspace &workspace, const std::vector<int> &ids);
static void processNodes(Workspace &workspace);
void reloadCustomNodes();
std::vector<Workspace*> &getWorkspaceStack() { return *this->m_workspaceStack; }
private:
bool m_updateNodePositions = false;
int m_rightClickedId = -1;
@@ -48,6 +68,9 @@ namespace hex::plugin::builtin {
};
std::vector<CustomNode> m_customNodes;
PerProvider<Workspace> m_mainWorkspace;
PerProvider<std::vector<Workspace*>> m_workspaceStack;
};
}

View File

@@ -18,12 +18,15 @@ namespace hex::plugin::builtin {
void drawContent() override;
private:
static bool importHashes(prv::Provider *provider, const nlohmann::json &json);
static bool exportHashes(prv::Provider *provider, nlohmann::json &json);
bool importHashes(prv::Provider *provider, const nlohmann::json &json);
bool exportHashes(prv::Provider *provider, nlohmann::json &json);
private:
ContentRegistry::Hashes::Hash *m_selectedHash = nullptr;
std::string m_newHashName;
PerProvider<std::vector<ContentRegistry::Hashes::Hash::Function>> m_hashFunctions;
};
}

View File

@@ -6,7 +6,6 @@
#include <hex/helpers/concepts.hpp>
#include <hex/helpers/encoding_file.hpp>
#include <content/helpers/provider_extra_data.hpp>
#include <ui/hex_editor.hpp>
namespace hex::plugin::builtin {
@@ -74,6 +73,9 @@ namespace hex::plugin::builtin {
bool m_shouldOpenPopup = false;
std::unique_ptr<Popup> m_currPopup;
PerProvider<std::optional<u64>> m_selectionStart, m_selectionEnd;
PerProvider<float> m_scrollPosition;
};
}

View File

@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include <hex/ui/view.hpp>
#include <hex/providers/provider.hpp>
@@ -7,7 +7,6 @@
#include <pl/pattern_language.hpp>
#include <pl/core/errors/error.hpp>
#include <content/helpers/provider_extra_data.hpp>
#include <content/providers/memory_file_provider.hpp>
#include <ui/hex_editor.hpp>
@@ -102,7 +101,32 @@ namespace hex::plugin::builtin {
};
private:
using PlData = ProviderExtraData::Data::PatternLanguage;
struct PatternVariable {
bool inVariable;
bool outVariable;
pl::core::Token::ValueType type;
pl::core::Token::Literal value;
};
enum class EnvVarType
{
Integer,
Float,
String,
Bool
};
struct EnvVar {
u64 id;
std::string name;
pl::core::Token::Literal value;
EnvVarType type;
bool operator==(const EnvVar &other) const {
return this->id == other.id;
}
};
std::unique_ptr<pl::PatternLanguage> m_parserRuntime;
@@ -130,10 +154,22 @@ namespace hex::plugin::builtin {
ui::HexEditor m_sectionHexEditor;
PerProvider<std::string> m_sourceCode;
PerProvider<std::vector<std::pair<pl::core::LogConsole::Level, std::string>>> m_console;
PerProvider<bool> m_executionDone = true;
PerProvider<std::optional<pl::core::err::PatternLanguageError>> m_lastEvaluationError;
PerProvider<std::vector<std::pair<pl::core::LogConsole::Level, std::string>>> m_lastEvaluationLog;
PerProvider<std::map<std::string, pl::core::Token::Literal>> m_lastEvaluationOutVars;
PerProvider<std::map<std::string, PatternVariable>> m_patternVariables;
PerProvider<std::map<u64, pl::api::Section>> m_sections;
PerProvider<std::list<EnvVar>> m_envVarEntries;
private:
void drawConsole(ImVec2 size, const std::vector<std::pair<pl::core::LogConsole::Level, std::string>> &console);
void drawEnvVars(ImVec2 size, std::list<PlData::EnvVar> &envVars);
void drawVariableSettings(ImVec2 size, std::map<std::string, PlData::PatternVariable> &patternVariables);
void drawEnvVars(ImVec2 size, std::list<EnvVar> &envVars);
void drawVariableSettings(ImVec2 size, std::map<std::string, PatternVariable> &patternVariables);
void drawSectionSelector(ImVec2 size, std::map<u64, pl::api::Section> &sections);
void drawPatternTooltip(pl::ptrn::Pattern *pattern);

View File

@@ -17,6 +17,22 @@ namespace hex::plugin::builtin {
void drawContent() override;
private:
struct YaraMatch {
std::string identifier;
std::string variable;
u64 address;
size_t size;
bool wholeDataMatch;
mutable u32 highlightId;
mutable u32 tooltipId;
};
private:
PerProvider<std::vector<std::pair<std::fs::path, std::fs::path>>> m_rules;
PerProvider<std::vector<YaraMatch>> m_matches;
PerProvider<std::vector<YaraMatch*>> m_sortedMatches;
u32 m_selectedRule = 0;
TaskHolder m_matcherTask;