sys: Improve pattern visualizer API
This commit is contained in:
parent
4f0e5b99a8
commit
89a96c6d25
2
lib/external/pattern_language
vendored
2
lib/external/pattern_language
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 42fbcf258505d44628143f9dafd44f0c586f1d74
|
Subproject commit 565df62329f586842211b41788f9fec6dfa99150
|
@ -9,9 +9,10 @@
|
|||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <nlohmann/json_fwd.hpp>
|
#include <nlohmann/json_fwd.hpp>
|
||||||
@ -117,7 +118,7 @@ namespace hex {
|
|||||||
/* Pattern Language Function Registry. Allows adding of new functions that may be used inside the pattern language */
|
/* Pattern Language Function Registry. Allows adding of new functions that may be used inside the pattern language */
|
||||||
namespace PatternLanguage {
|
namespace PatternLanguage {
|
||||||
|
|
||||||
using VisualizerFunctionCallback = std::function<void(pl::ptrn::Pattern&, pl::ptrn::Iteratable&, bool, const std::vector<pl::core::Token::Literal> &)>;
|
using VisualizerFunctionCallback = std::function<void(pl::ptrn::Pattern&, pl::ptrn::Iteratable&, bool, std::span<const pl::core::Token::Literal>)>;
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
|
@ -26,38 +26,12 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::vector<T> patternToArray(pl::ptrn::Pattern *pattern){
|
std::vector<T> patternToArray(pl::ptrn::Pattern *pattern){
|
||||||
|
const auto bytes = pattern->getBytes();
|
||||||
|
|
||||||
std::vector<T> result;
|
std::vector<T> result;
|
||||||
result.resize(pattern->getChildren().size());
|
result.resize(bytes.size() / sizeof(T));
|
||||||
|
for (size_t i = 0; i < result.size(); i++)
|
||||||
if (dynamic_cast<pl::ptrn::PatternPadding*>(pattern) != nullptr && pattern->getSize() == 0)
|
std::memcpy(&result[i], &bytes[i * sizeof(T)], sizeof(T));
|
||||||
return result;
|
|
||||||
|
|
||||||
if (auto iteratable = dynamic_cast<pl::ptrn::Iteratable*>(pattern); iteratable != nullptr) {
|
|
||||||
iteratable->forEachEntry(0, iteratable->getEntryCount(), [&](u64, pl::ptrn::Pattern *entry) {
|
|
||||||
const auto children = entry->getChildren();
|
|
||||||
for (const auto &[offset, child] : children) {
|
|
||||||
auto startOffset = child->getOffset();
|
|
||||||
|
|
||||||
child->setOffset(offset);
|
|
||||||
ON_SCOPE_EXIT { child->setOffset(startOffset); };
|
|
||||||
|
|
||||||
T value;
|
|
||||||
if constexpr (std::floating_point<T>)
|
|
||||||
value = child->getValue().toFloatingPoint();
|
|
||||||
else if constexpr (std::signed_integral<T>)
|
|
||||||
value = child->getValue().toSigned();
|
|
||||||
else if constexpr (std::unsigned_integral<T>)
|
|
||||||
value = child->getValue().toUnsigned();
|
|
||||||
else
|
|
||||||
static_assert(hex::always_false<T>::value, "Invalid type");
|
|
||||||
|
|
||||||
result.push_back(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
result.resize(pattern->getSize() / sizeof(float));
|
|
||||||
pattern->getEvaluator()->readData(pattern->getOffset(), result.data(), result.size() * sizeof(float), pattern->getSection());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -80,7 +54,7 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void drawLinePlotVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, const std::vector<pl::core::Token::Literal> &arguments) {
|
void drawLinePlotVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, std::span<const pl::core::Token::Literal> arguments) {
|
||||||
static std::vector<float> values;
|
static std::vector<float> values;
|
||||||
auto dataPattern = arguments[0].toPattern();
|
auto dataPattern = arguments[0].toPattern();
|
||||||
|
|
||||||
@ -99,7 +73,7 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawScatterPlotVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, const std::vector<pl::core::Token::Literal> &arguments) {
|
void drawScatterPlotVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, std::span<const pl::core::Token::Literal> arguments) {
|
||||||
static std::vector<float> xValues, yValues;
|
static std::vector<float> xValues, yValues;
|
||||||
|
|
||||||
auto xPattern = arguments[0].toPattern();
|
auto xPattern = arguments[0].toPattern();
|
||||||
@ -121,14 +95,12 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawImageVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, const std::vector<pl::core::Token::Literal> &arguments) {
|
void drawImageVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, std::span<const pl::core::Token::Literal> arguments) {
|
||||||
static ImGui::Texture texture;
|
static ImGui::Texture texture;
|
||||||
if (shouldReset) {
|
if (shouldReset) {
|
||||||
auto pattern = arguments[1].toPattern();
|
auto pattern = arguments[0].toPattern();
|
||||||
|
|
||||||
std::vector<u8> data;
|
auto data = pattern->getBytes();
|
||||||
data.resize(pattern->getSize());
|
|
||||||
pattern->getEvaluator()->readData(pattern->getOffset(), data.data(), data.size(), pattern->getSection());
|
|
||||||
texture = ImGui::Texture(data.data(), data.size());
|
texture = ImGui::Texture(data.data(), data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,14 +108,14 @@ namespace hex::plugin::builtin {
|
|||||||
ImGui::Image(texture, texture.getSize());
|
ImGui::Image(texture, texture.getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawBitmapVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, const std::vector<pl::core::Token::Literal> &arguments) {
|
void drawBitmapVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, std::span<const pl::core::Token::Literal> arguments) {
|
||||||
static ImGui::Texture texture;
|
static ImGui::Texture texture;
|
||||||
if (shouldReset) {
|
if (shouldReset) {
|
||||||
auto pattern = arguments[1].toPattern();
|
auto pattern = arguments[0].toPattern();
|
||||||
auto width = arguments[2].toUnsigned();
|
auto width = arguments[1].toUnsigned();
|
||||||
auto height = arguments[3].toUnsigned();
|
auto height = arguments[2].toUnsigned();
|
||||||
|
|
||||||
auto data = patternToArray<u8>(pattern);
|
auto data = pattern->getBytes();
|
||||||
texture = ImGui::Texture(data.data(), data.size(), width, height);
|
texture = ImGui::Texture(data.data(), data.size(), width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +123,7 @@ namespace hex::plugin::builtin {
|
|||||||
ImGui::Image(texture, texture.getSize());
|
ImGui::Image(texture, texture.getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawDisassemblyVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, const std::vector<pl::core::Token::Literal> &arguments) {
|
void drawDisassemblyVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, std::span<const pl::core::Token::Literal> arguments) {
|
||||||
struct Disassembly {
|
struct Disassembly {
|
||||||
u64 address;
|
u64 address;
|
||||||
std::vector<u8> bytes;
|
std::vector<u8> bytes;
|
||||||
@ -160,10 +132,10 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
static std::vector<Disassembly> disassembly;
|
static std::vector<Disassembly> disassembly;
|
||||||
if (shouldReset) {
|
if (shouldReset) {
|
||||||
auto pattern = arguments[1].toPattern();
|
auto pattern = arguments[0].toPattern();
|
||||||
auto baseAddress = arguments[2].toUnsigned();
|
auto baseAddress = arguments[1].toUnsigned();
|
||||||
auto architecture = arguments[3].toUnsigned();
|
auto architecture = arguments[2].toUnsigned();
|
||||||
auto mode = arguments[4].toUnsigned();
|
auto mode = arguments[3].toUnsigned();
|
||||||
|
|
||||||
disassembly.clear();
|
disassembly.clear();
|
||||||
|
|
||||||
@ -171,7 +143,7 @@ namespace hex::plugin::builtin {
|
|||||||
if (cs_open(static_cast<cs_arch>(architecture), static_cast<cs_mode>(mode), &capstone) == CS_ERR_OK) {
|
if (cs_open(static_cast<cs_arch>(architecture), static_cast<cs_mode>(mode), &capstone) == CS_ERR_OK) {
|
||||||
cs_option(capstone, CS_OPT_SKIPDATA, CS_OPT_ON);
|
cs_option(capstone, CS_OPT_SKIPDATA, CS_OPT_ON);
|
||||||
|
|
||||||
auto data = patternToArray<u8>(pattern);
|
auto data = pattern->getBytes();
|
||||||
cs_insn *instructions = nullptr;
|
cs_insn *instructions = nullptr;
|
||||||
|
|
||||||
size_t instructionCount = cs_disasm(capstone, data.data(), data.size(), baseAddress, 0, &instructions);
|
size_t instructionCount = cs_disasm(capstone, data.data(), data.size(), baseAddress, 0, &instructions);
|
||||||
@ -207,9 +179,9 @@ namespace hex::plugin::builtin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw3DVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, const std::vector<pl::core::Token::Literal> &arguments) {
|
void draw3DVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, std::span<const pl::core::Token::Literal> arguments) {
|
||||||
auto verticesPattern = arguments[1].toPattern();
|
auto verticesPattern = arguments[0].toPattern();
|
||||||
auto indicesPattern = arguments[2].toPattern();
|
auto indicesPattern = arguments[1].toPattern();
|
||||||
|
|
||||||
static ImGui::Texture texture;
|
static ImGui::Texture texture;
|
||||||
static float scaling = 0.5F;
|
static float scaling = 0.5F;
|
||||||
@ -329,10 +301,10 @@ namespace hex::plugin::builtin {
|
|||||||
ImGui::Image(texture, texture.getSize(), ImVec2(0, 1), ImVec2(1, 0));
|
ImGui::Image(texture, texture.getSize(), ImVec2(0, 1), ImVec2(1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawSoundVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, const std::vector<pl::core::Token::Literal> &arguments) {
|
void drawSoundVisualizer(pl::ptrn::Pattern &, pl::ptrn::Iteratable &, bool shouldReset, std::span<const pl::core::Token::Literal> arguments) {
|
||||||
auto wavePattern = arguments[1].toPattern();
|
auto wavePattern = arguments[0].toPattern();
|
||||||
auto channels = arguments[2].toUnsigned();
|
auto channels = arguments[1].toUnsigned();
|
||||||
auto sampleRate = arguments[3].toUnsigned();
|
auto sampleRate = arguments[2].toUnsigned();
|
||||||
|
|
||||||
static std::vector<i16> waveData, sampledData;
|
static std::vector<i16> waveData, sampledData;
|
||||||
static ma_device audioDevice;
|
static ma_device audioDevice;
|
||||||
|
@ -134,7 +134,7 @@ namespace hex::plugin::builtin::ui {
|
|||||||
ImGui::TextUnformatted("hex.builtin.pattern_drawer.visualizer.invalid_parameter_count"_lang);
|
ImGui::TextUnformatted("hex.builtin.pattern_drawer.visualizer.invalid_parameter_count"_lang);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
visualizer.callback(pattern, iteratable, reset, arguments);
|
visualizer.callback(pattern, iteratable, reset, { arguments.begin() + 1, arguments.end() });
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
this->m_lastVisualizerError = e.what();
|
this->m_lastVisualizerError = e.what();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user