mirror of https://github.com/WerWolv/ImHex.git
Revamped pattern data displaying to support per-type displaying
This commit is contained in:
parent
72f9da2a67
commit
658d4ec478
|
@ -5,7 +5,46 @@
|
|||
#include <array>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "parser/token.hpp"
|
||||
|
||||
namespace hex {
|
||||
|
||||
template<typename ... Args>
|
||||
inline std::string format(const std::string &format, Args ... args) {
|
||||
size_t size = snprintf( nullptr, 0, format.c_str(), args ... );
|
||||
|
||||
if( size <= 0 )
|
||||
return "";
|
||||
|
||||
std::vector<char> buffer(size + 1, 0x00);
|
||||
snprintf(buffer.data(), size + 1, format.c_str(), args ...);
|
||||
|
||||
return std::string(buffer.data(), buffer.data() + size);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr inline u64 signExtend(u64 value, u8 currWidth, u8 targetWidth) {
|
||||
u64 mask = 1LLU << (currWidth - 1);
|
||||
return (((value ^ mask) - mask) << (64 - targetWidth)) >> (64 - targetWidth);
|
||||
}
|
||||
|
||||
constexpr inline bool isUnsigned(const lang::Token::TypeToken::Type type) {
|
||||
return (static_cast<u32>(type) & 0x0F) == 0x00;
|
||||
}
|
||||
|
||||
constexpr inline bool isSigned(const lang::Token::TypeToken::Type type) {
|
||||
return (static_cast<u32>(type) & 0x0F) == 0x01;
|
||||
}
|
||||
|
||||
constexpr inline bool isFloatingPoint(const lang::Token::TypeToken::Type type) {
|
||||
return (static_cast<u32>(type) & 0x0F) == 0x02;
|
||||
}
|
||||
|
||||
constexpr inline u32 getTypeSize(const lang::Token::TypeToken::Type type) {
|
||||
return static_cast<u32>(type) >> 4;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace hex {
|
||||
|
||||
struct VariableType {
|
||||
size_t size;
|
||||
enum class Kind { Unsigned, Signed, FloatingPoint } kind;
|
||||
};
|
||||
|
||||
struct Highlight {
|
||||
Highlight(u64 offset, VariableType type, u32 color, std::string name)
|
||||
: offset(offset), type(type), color(color), name(name) {
|
||||
|
||||
}
|
||||
|
||||
u64 offset;
|
||||
VariableType type;
|
||||
u32 color;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <string>
|
||||
|
||||
#include "providers/provider.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string makeDisplayable(u8 *data, size_t size) {
|
||||
std::string result;
|
||||
for (u8* c = data; c < (data + size); c++) {
|
||||
if (iscntrl(*c) || *c > 0x7F)
|
||||
result += " ";
|
||||
else
|
||||
result += *c;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class PatternData {
|
||||
public:
|
||||
PatternData(u64 offset, size_t size, const std::string &name, u32 color = 0)
|
||||
: m_offset(offset), m_size(size), m_color(color), m_name(name) {
|
||||
if (color == 0)
|
||||
color = std::mt19937(std::random_device()())();
|
||||
|
||||
color &= ~0xFF00'0000;
|
||||
color |= 0x5000'0000;
|
||||
|
||||
this->m_color = color;
|
||||
}
|
||||
virtual ~PatternData() = default;
|
||||
|
||||
[[nodiscard]] u64 getOffset() const { return this->m_offset; }
|
||||
[[nodiscard]] size_t getSize() const { return this->m_size; }
|
||||
|
||||
[[nodiscard]] u32 getColor() const { return this->m_color; }
|
||||
[[nodiscard]] const std::string& getName() const { return this->m_name; }
|
||||
|
||||
virtual std::string format(prv::Provider* &provider) = 0;
|
||||
|
||||
private:
|
||||
u64 m_offset;
|
||||
size_t m_size;
|
||||
|
||||
u32 m_color;
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
|
||||
class PatternDataUnsigned : public PatternData {
|
||||
public:
|
||||
PatternDataUnsigned(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(offset, size, name, color) { }
|
||||
|
||||
std::string format(prv::Provider* &provider) override {
|
||||
u64 data = 0;
|
||||
provider->read(this->getOffset(), &data, this->getSize());
|
||||
|
||||
return hex::format("%lu (0x%08lx)", data, data);
|
||||
}
|
||||
};
|
||||
|
||||
class PatternDataSigned : public PatternData {
|
||||
public:
|
||||
PatternDataSigned(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(offset, size, name, color) { }
|
||||
|
||||
std::string format(prv::Provider* &provider) override {
|
||||
u64 data = 0;
|
||||
provider->read(this->getOffset(), &data, this->getSize());
|
||||
|
||||
s64 signedData = signedData = hex::signExtend(data, this->getSize(), 64);
|
||||
|
||||
return hex::format("%ld (0x%08lx)", signedData, data);
|
||||
}
|
||||
};
|
||||
|
||||
class PatternDataFloat : public PatternData {
|
||||
public:
|
||||
PatternDataFloat(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(offset, size, name, color) { }
|
||||
|
||||
std::string format(prv::Provider* &provider) override {
|
||||
double formatData = 0;
|
||||
if (this->getSize() == 4) {
|
||||
float data = 0;
|
||||
provider->read(this->getOffset(), &data, 4);
|
||||
formatData = data;
|
||||
} else if (this->getSize() == 8) {
|
||||
double data = 0;
|
||||
provider->read(this->getOffset(), &data, 8);
|
||||
formatData = data;
|
||||
}
|
||||
|
||||
return hex::format("%f (0x%08lx)", formatData, formatData);
|
||||
}
|
||||
};
|
||||
|
||||
class PatternDataCharacter : public PatternData {
|
||||
public:
|
||||
PatternDataCharacter(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(offset, size, name, color) { }
|
||||
|
||||
std::string format(prv::Provider* &provider) override {
|
||||
char character;
|
||||
provider->read(this->getOffset(), &character, 1);
|
||||
|
||||
return hex::format("'%c'", character);
|
||||
}
|
||||
};
|
||||
|
||||
class PatternDataString : public PatternData {
|
||||
public:
|
||||
PatternDataString(u64 offset, size_t size, const std::string &name, u32 color = 0) : PatternData(offset, size, name, color) { }
|
||||
|
||||
std::string format(prv::Provider* &provider) override {
|
||||
std::vector<u8> buffer(this->getSize() + 1, 0x00);
|
||||
provider->read(this->getOffset(), buffer.data(), this->getSize());
|
||||
buffer[this->getSize()] = '\0';
|
||||
|
||||
return hex::format("\"%s\"", makeDisplayable(buffer.data(), this->getSize()).c_str());
|
||||
}
|
||||
};
|
||||
|
||||
class PatternDataEnum : public PatternData {
|
||||
public:
|
||||
PatternDataEnum(u64 offset, size_t size, const std::string &name, const std::string &enumName, std::vector<std::pair<u64, std::string>> enumValues, u32 color = 0)
|
||||
: PatternData(offset, size, name, color), m_enumName(enumName), m_enumValues(enumValues) { }
|
||||
|
||||
std::string format(prv::Provider* &provider) override {
|
||||
u64 value = 0;
|
||||
provider->read(this->getOffset(), &value, this->getSize());
|
||||
|
||||
for (auto [enumValue, name] : this->m_enumValues) {
|
||||
if (value == enumValue)
|
||||
return hex::format("%lu (0x%08lx) : %s::%s", value, value, this->m_enumName.c_str(), name.c_str());
|
||||
}
|
||||
|
||||
return hex::format("%lu (0x%08lx) : %s::???", value, value, this->m_enumName.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_enumName;
|
||||
std::vector<std::pair<u64, std::string>> m_enumValues;
|
||||
};
|
||||
|
||||
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
#include "views/highlight.hpp"
|
||||
#include "views/pattern_data.hpp"
|
||||
|
||||
namespace hex {
|
||||
|
||||
|
@ -18,7 +18,7 @@ namespace hex {
|
|||
|
||||
class ViewHexEditor : public View {
|
||||
public:
|
||||
ViewHexEditor(prv::Provider* &dataProvider, std::vector<Highlight> &highlights);
|
||||
ViewHexEditor(prv::Provider* &dataProvider, std::vector<hex::PatternData*> &patternData);
|
||||
~ViewHexEditor() override;
|
||||
|
||||
void createView() override;
|
||||
|
@ -32,7 +32,7 @@ namespace hex {
|
|||
|
||||
|
||||
prv::Provider* &m_dataProvider;
|
||||
std::vector<Highlight> &m_highlights;
|
||||
std::vector<hex::PatternData*> &m_patternData;
|
||||
|
||||
char m_searchBuffer[0xFFFF] = { 0 };
|
||||
s64 m_lastSearchIndex = 0;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "parser/lexer.hpp"
|
||||
|
||||
#include "views/view.hpp"
|
||||
#include "views/highlight.hpp"
|
||||
#include "views/pattern_data.hpp"
|
||||
|
||||
#include "providers/provider.hpp"
|
||||
|
||||
|
@ -19,7 +19,7 @@ namespace hex {
|
|||
|
||||
class ViewPattern : public View {
|
||||
public:
|
||||
explicit ViewPattern(prv::Provider* &dataProvider, std::vector<Highlight> &highlights);
|
||||
explicit ViewPattern(prv::Provider* &dataProvider, std::vector<hex::PatternData*> &patternData);
|
||||
~ViewPattern() override;
|
||||
|
||||
void createMenu() override;
|
||||
|
@ -28,18 +28,20 @@ namespace hex {
|
|||
private:
|
||||
char *m_buffer = nullptr;
|
||||
|
||||
std::vector<Highlight> &m_highlights;
|
||||
std::vector<hex::PatternData*> &m_patternData;
|
||||
prv::Provider* &m_dataProvider;
|
||||
bool m_windowOpen = true;
|
||||
|
||||
ImGui::FileBrowser m_fileBrowser;
|
||||
|
||||
|
||||
void setHighlight(u64 offset, std::string name, lang::Token::TypeToken::Type type, size_t size = 0, u32 color = 0);
|
||||
void addPatternData(PatternData *patternData);
|
||||
void clearPatternData();
|
||||
void parsePattern(char *buffer);
|
||||
|
||||
s32 highlightUsingDecls(std::vector<lang::ASTNode*> &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDec, u64 offset, std::string name);
|
||||
s32 highlightStruct(std::vector<lang::ASTNode*> &ast, lang::ASTNodeStruct* currStructNode, u64 offset, std::string name);
|
||||
s32 highlightEnum(std::vector<lang::ASTNode*> &ast, lang::ASTNodeEnum* currEnumNode, u64 offset, std::string name);
|
||||
};
|
||||
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "imgui.h"
|
||||
#include "views/view.hpp"
|
||||
#include "views/highlight.hpp"
|
||||
#include "views/pattern_data.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
@ -16,7 +16,7 @@ namespace hex {
|
|||
|
||||
class ViewPatternData : public View {
|
||||
public:
|
||||
ViewPatternData(prv::Provider* &dataProvider, std::vector<Highlight> &highlights);
|
||||
ViewPatternData(prv::Provider* &dataProvider, std::vector<hex::PatternData*> &patternData);
|
||||
~ViewPatternData() override;
|
||||
|
||||
void createView() override;
|
||||
|
@ -24,7 +24,7 @@ namespace hex {
|
|||
|
||||
private:
|
||||
prv::Provider* &m_dataProvider;
|
||||
std::vector<Highlight> &m_highlights;
|
||||
std::vector<hex::PatternData*> &m_patternData;
|
||||
bool m_windowOpen = true;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "window.hpp"
|
||||
|
||||
#include "views/highlight.hpp"
|
||||
#include "views/pattern_data.hpp"
|
||||
#include "views/view_hexeditor.hpp"
|
||||
#include "views/view_pattern.hpp"
|
||||
#include "views/view_pattern_data.hpp"
|
||||
|
@ -15,13 +15,13 @@ int main() {
|
|||
hex::Window window;
|
||||
|
||||
// Shared Data
|
||||
std::vector<hex::Highlight> highlights;
|
||||
std::vector<hex::PatternData*> patternData;
|
||||
hex::prv::Provider *dataProvider = nullptr;
|
||||
|
||||
// Create views
|
||||
window.addView<hex::ViewHexEditor>(dataProvider, highlights);
|
||||
window.addView<hex::ViewPattern>(dataProvider, highlights);
|
||||
window.addView<hex::ViewPatternData>(dataProvider, highlights);
|
||||
window.addView<hex::ViewHexEditor>(dataProvider, patternData);
|
||||
window.addView<hex::ViewPattern>(dataProvider, patternData);
|
||||
window.addView<hex::ViewPatternData>(dataProvider, patternData);
|
||||
window.addView<hex::ViewHashes>(dataProvider);
|
||||
window.addView<hex::ViewInformation>(dataProvider);
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
namespace hex {
|
||||
|
||||
ViewHexEditor::ViewHexEditor(prv::Provider* &dataProvider, std::vector<Highlight> &highlights)
|
||||
: View(), m_dataProvider(dataProvider), m_highlights(highlights) {
|
||||
ViewHexEditor::ViewHexEditor(prv::Provider* &dataProvider, std::vector<hex::PatternData*> &patternData)
|
||||
: View(), m_dataProvider(dataProvider), m_patternData(patternData) {
|
||||
|
||||
this->m_memoryEditor.ReadFn = [](const ImU8 *data, size_t off) -> ImU8 {
|
||||
ViewHexEditor *_this = (ViewHexEditor *) data;
|
||||
|
@ -35,13 +35,13 @@ namespace hex {
|
|||
this->m_memoryEditor.HighlightFn = [](const ImU8 *data, size_t off, bool next) -> bool {
|
||||
ViewHexEditor *_this = (ViewHexEditor *) data;
|
||||
|
||||
for (auto&[offset, type, color, name] : _this->m_highlights) {
|
||||
if (next && off == (offset + type.size)) {
|
||||
for (auto& pattern : _this->m_patternData) {
|
||||
if (next && off == (pattern->getOffset() + pattern->getSize())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (off >= offset && off < (offset + type.size)) {
|
||||
_this->m_memoryEditor.HighlightColor = color;
|
||||
if (off >= pattern->getOffset() && off < (pattern->getOffset() + pattern->getSize())) {
|
||||
_this->m_memoryEditor.HighlightColor = pattern->getColor();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
namespace hex {
|
||||
|
||||
ViewPattern::ViewPattern(prv::Provider* &dataProvider, std::vector<Highlight> &highlights)
|
||||
: View(), m_dataProvider(dataProvider), m_highlights(highlights) {
|
||||
ViewPattern::ViewPattern(prv::Provider* &dataProvider, std::vector<hex::PatternData*> &patternData)
|
||||
: View(), m_dataProvider(dataProvider), m_patternData(patternData) {
|
||||
|
||||
this->m_buffer = new char[0xFF'FFFF];
|
||||
std::memset(this->m_buffer, 0x00, 0xFF'FFFF);
|
||||
|
@ -86,25 +86,15 @@ namespace hex {
|
|||
}
|
||||
|
||||
|
||||
void ViewPattern::setHighlight(u64 offset, std::string name, lang::Token::TypeToken::Type type, size_t size, u32 color) {
|
||||
if (color == 0)
|
||||
color = std::mt19937(std::random_device()())();
|
||||
void ViewPattern::addPatternData(PatternData *patternData) {
|
||||
this->m_patternData.push_back(patternData);
|
||||
}
|
||||
|
||||
color &= ~0xFF00'0000;
|
||||
color |= 0x5000'0000;
|
||||
void ViewPattern::clearPatternData() {
|
||||
for (auto &data : this->m_patternData)
|
||||
delete data;
|
||||
|
||||
VariableType varType = { 0 };
|
||||
|
||||
switch (static_cast<u32>(type) & 0x0F) {
|
||||
default:
|
||||
case 0: varType.kind = VariableType::Kind::Unsigned; break;
|
||||
case 1: varType.kind = VariableType::Kind::Signed; break;
|
||||
case 2: varType.kind = VariableType::Kind::FloatingPoint; break;
|
||||
}
|
||||
|
||||
varType.size = size;
|
||||
|
||||
this->m_highlights.emplace_back(offset, varType, color, name);
|
||||
this->m_patternData.clear();
|
||||
}
|
||||
|
||||
template<std::derived_from<lang::ASTNode> T>
|
||||
|
@ -122,7 +112,7 @@ namespace hex {
|
|||
static hex::lang::Lexer lexer;
|
||||
static hex::lang::Parser parser;
|
||||
|
||||
this->m_highlights.clear();
|
||||
this->clearPatternData();
|
||||
|
||||
auto [lexResult, tokens] = lexer.lex(buffer);
|
||||
|
||||
|
@ -142,10 +132,22 @@ namespace hex {
|
|||
|
||||
u64 offset = varNode->getOffset().value();
|
||||
if (varNode->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
|
||||
size_t size = static_cast<u32>(varNode->getVariableType()) >> 4 * varNode->getArraySize();
|
||||
this->setHighlight(offset, varNode->getVariableName(), varNode->getVariableType(), size);
|
||||
size_t size = getTypeSize(varNode->getVariableType()) * varNode->getArraySize();
|
||||
|
||||
if (isUnsigned(varNode->getVariableType()))
|
||||
this->addPatternData(new PatternDataUnsigned(offset, size, varNode->getVariableName()));
|
||||
else if (isSigned(varNode->getVariableType())) {
|
||||
if (getTypeSize(varNode->getVariableType()) == 1 && varNode->getArraySize() == 1)
|
||||
this->addPatternData(new PatternDataCharacter(offset, size, varNode->getVariableName()));
|
||||
else if (getTypeSize(varNode->getVariableType()) == 1 && varNode->getArraySize() > 1)
|
||||
this->addPatternData(new PatternDataString(offset, size, varNode->getVariableName()));
|
||||
else
|
||||
this->addPatternData(new PatternDataSigned(offset, size, varNode->getVariableName()));
|
||||
}
|
||||
else if (isFloatingPoint(varNode->getVariableType()))
|
||||
this->addPatternData(new PatternDataFloat(offset, size, varNode->getVariableName()));
|
||||
} else {
|
||||
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast))
|
||||
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast)) {
|
||||
if (varNode->getCustomVariableTypeName() == structNode->getName()) {
|
||||
for (u32 i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string name = varNode->getVariableName();
|
||||
|
@ -153,11 +155,27 @@ namespace hex {
|
|||
name += "[" + std::to_string(varNode->getArraySize()) + "]";
|
||||
|
||||
if (size_t size = this->highlightStruct(ast, structNode, offset, name); size == -1)
|
||||
this->m_highlights.clear();
|
||||
this->clearPatternData();
|
||||
else
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &enumNode : findNodes<lang::ASTNodeEnum>(lang::ASTNode::Type::Enum, ast)) {
|
||||
if (varNode->getCustomVariableTypeName() == enumNode->getName()) {
|
||||
for (u32 i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string name = varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
name += "[" + std::to_string(varNode->getArraySize()) + "]";
|
||||
|
||||
if (size_t size = this->highlightEnum(ast, enumNode, offset, name); size == -1)
|
||||
this->clearPatternData();
|
||||
else
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &usingNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast)) {
|
||||
if (varNode->getCustomVariableTypeName() == usingNode->getTypeName()) {
|
||||
|
@ -167,7 +185,7 @@ namespace hex {
|
|||
name += "[" + std::to_string(varNode->getArraySize()) + "]";
|
||||
|
||||
if (size_t size = this->highlightUsingDecls(ast, usingNode, varNode, offset, name); size == -1)
|
||||
this->m_highlights.clear();
|
||||
this->clearPatternData();
|
||||
else
|
||||
offset += size;
|
||||
}
|
||||
|
@ -186,11 +204,17 @@ namespace hex {
|
|||
if (currTypeDeclNode->getAssignedType() != lang::Token::TypeToken::Type::CustomType) {
|
||||
size_t size = (static_cast<u32>(currTypeDeclNode->getAssignedType()) >> 4);
|
||||
|
||||
this->setHighlight(offset, name, currTypeDeclNode->getAssignedType(), size);
|
||||
if (isUnsigned(currTypeDeclNode->getAssignedType()))
|
||||
this->addPatternData(new PatternDataUnsigned(offset, size, currTypeDeclNode->getTypeName()));
|
||||
else if (isSigned(currTypeDeclNode->getAssignedType()))
|
||||
this->addPatternData(new PatternDataSigned(offset, size, currTypeDeclNode->getTypeName()));
|
||||
else if (isFloatingPoint(currTypeDeclNode->getAssignedType()))
|
||||
this->addPatternData(new PatternDataFloat(offset, size, currTypeDeclNode->getTypeName()));
|
||||
|
||||
offset += size;
|
||||
} else {
|
||||
bool foundType = false;
|
||||
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast))
|
||||
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast)) {
|
||||
if (structNode->getName() == currTypeDeclNode->getAssignedCustomTypeName()) {
|
||||
for (size_t i = 0; i < currVarDecl->getArraySize(); i++) {
|
||||
size_t size = this->highlightStruct(ast, structNode, offset, name);
|
||||
|
@ -204,6 +228,24 @@ namespace hex {
|
|||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &enumNode : findNodes<lang::ASTNodeEnum>(lang::ASTNode::Type::Enum, ast)) {
|
||||
if (enumNode->getName() == currTypeDeclNode->getAssignedCustomTypeName()) {
|
||||
for (size_t i = 0; i < currVarDecl->getArraySize(); i++) {
|
||||
size_t size = this->highlightEnum(ast, enumNode, offset, name);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (auto &typeDeclNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast)) {
|
||||
if (typeDeclNode->getTypeName() == currTypeDeclNode->getAssignedCustomTypeName()) {
|
||||
|
@ -232,25 +274,40 @@ namespace hex {
|
|||
u64 startOffset = offset;
|
||||
|
||||
for (auto &node : currStructNode->getNodes()) {
|
||||
auto var = static_cast<lang::ASTNodeVariableDecl*>(node);
|
||||
auto varNode = static_cast<lang::ASTNodeVariableDecl*>(node);
|
||||
|
||||
if (var->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
|
||||
size_t size = (static_cast<u32>(var->getVariableType()) >> 4);
|
||||
for (size_t i = 0; i < var->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + var->getVariableName();
|
||||
if (var->getArraySize() > 1)
|
||||
if (varNode->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
|
||||
size_t size = (static_cast<u32>(varNode->getVariableType()) >> 4);
|
||||
for (size_t i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
memberName += "[" + std::to_string(i) + "]";
|
||||
|
||||
this->setHighlight(offset, memberName, var->getVariableType(), size);
|
||||
if (isUnsigned(varNode->getVariableType()))
|
||||
this->addPatternData(new PatternDataUnsigned(offset, size, memberName));
|
||||
else if (isSigned(varNode->getVariableType())) {
|
||||
if (getTypeSize(varNode->getVariableType()) == 1 && varNode->getArraySize() == 1)
|
||||
this->addPatternData(new PatternDataCharacter(offset, size, memberName));
|
||||
else if (getTypeSize(varNode->getVariableType()) == 1 && varNode->getArraySize() > 1) {
|
||||
this->addPatternData(new PatternDataString(offset, size * varNode->getArraySize(), name + "." + varNode->getVariableName()));
|
||||
offset += size * varNode->getArraySize();
|
||||
break;
|
||||
}
|
||||
else
|
||||
this->addPatternData(new PatternDataSigned(offset, size, memberName));
|
||||
}
|
||||
else if (isFloatingPoint(varNode->getVariableType()))
|
||||
this->addPatternData(new PatternDataFloat(offset, size, memberName));
|
||||
|
||||
offset += size;
|
||||
}
|
||||
} else {
|
||||
bool foundType = false;
|
||||
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast)) {
|
||||
if (structNode->getName() == var->getCustomVariableTypeName()) {
|
||||
for (size_t i = 0; i < var->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + var->getVariableName();
|
||||
if (var->getArraySize() > 1)
|
||||
if (structNode->getName() == varNode->getCustomVariableTypeName()) {
|
||||
for (size_t i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
memberName += "[" + std::to_string(i) + "]";
|
||||
|
||||
size_t size = this->highlightStruct(ast, structNode, offset, memberName);
|
||||
|
@ -266,14 +323,34 @@ namespace hex {
|
|||
}
|
||||
}
|
||||
|
||||
for (auto &typeDeclNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast)) {
|
||||
if (typeDeclNode->getTypeName() == var->getCustomVariableTypeName()) {
|
||||
for (size_t i = 0; i < var->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + var->getVariableName();
|
||||
if (var->getArraySize() > 1)
|
||||
for (auto &enumNode : findNodes<lang::ASTNodeEnum>(lang::ASTNode::Type::Enum, ast)) {
|
||||
if (enumNode->getName() == varNode->getCustomVariableTypeName()) {
|
||||
for (size_t i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
memberName += "[" + std::to_string(i) + "]";
|
||||
|
||||
size_t size = this->highlightUsingDecls(ast, typeDeclNode, var, offset, memberName);
|
||||
size_t size = this->highlightEnum(ast, enumNode, offset, memberName);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &typeDeclNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast)) {
|
||||
if (typeDeclNode->getTypeName() == varNode->getCustomVariableTypeName()) {
|
||||
for (size_t i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
memberName += "[" + std::to_string(i) + "]";
|
||||
|
||||
size_t size = this->highlightUsingDecls(ast, typeDeclNode, varNode, offset, memberName);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
@ -295,4 +372,18 @@ namespace hex {
|
|||
return offset - startOffset;
|
||||
}
|
||||
|
||||
s32 ViewPattern::highlightEnum(std::vector<lang::ASTNode*> &ast, lang::ASTNodeEnum* currEnumNode, u64 offset, std::string name) {
|
||||
if (!isUnsigned(currEnumNode->getUnderlyingType()))
|
||||
return -1;
|
||||
|
||||
s32 size = static_cast<u32>(currEnumNode->getUnderlyingType()) >> 4;
|
||||
|
||||
if (size > 8)
|
||||
return -1;
|
||||
|
||||
this->addPatternData(new PatternDataEnum(offset, size, name, currEnumNode->getName(), currEnumNode->getValues()));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
}
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
namespace hex {
|
||||
|
||||
ViewPatternData::ViewPatternData(prv::Provider* &dataProvider, std::vector<Highlight> &highlights)
|
||||
: View(), m_dataProvider(dataProvider), m_highlights(highlights) {
|
||||
ViewPatternData::ViewPatternData(prv::Provider* &dataProvider, std::vector<hex::PatternData*> &patternData)
|
||||
: View(), m_dataProvider(dataProvider), m_patternData(patternData) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -15,18 +15,6 @@ namespace hex {
|
|||
|
||||
}
|
||||
|
||||
std::string makeDisplayable(u8 *data, size_t size) {
|
||||
std::string result;
|
||||
for (u8* c = data; c < (data + size - 1); c++) {
|
||||
if (iscntrl(*c) || *c > 0x7F)
|
||||
result += " ";
|
||||
else
|
||||
result += *c;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ViewPatternData::createView() {
|
||||
if (!this->m_windowOpen)
|
||||
return;
|
||||
|
@ -36,35 +24,11 @@ namespace hex {
|
|||
|
||||
if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) {
|
||||
|
||||
for (auto&[offset, type, color, name] : this->m_highlights) {
|
||||
std::vector<u8> buffer(type.size + 1, 0x00);
|
||||
|
||||
this->m_dataProvider->read(offset, buffer.data(), type.size);
|
||||
|
||||
if (type.size <= 8) {
|
||||
u64 data = 0;
|
||||
std::memcpy(&data, buffer.data(), type.size);
|
||||
|
||||
switch (type.kind) {
|
||||
case VariableType::Kind::Unsigned:
|
||||
ImGui::LabelText(name.c_str(), "[0x%08lx:0x%08lx] %lu (0x%08lx) \"%s\"", offset,
|
||||
offset + type.size, data, data,
|
||||
makeDisplayable(buffer.data(), buffer.size()).c_str());
|
||||
break;
|
||||
case VariableType::Kind::Signed:
|
||||
ImGui::LabelText(name.c_str(), "[0x%08lx:0x%08lx] %ld (0x%08lx) \"%s\"", offset,
|
||||
offset + type.size, data, data,
|
||||
makeDisplayable(buffer.data(), buffer.size()).c_str());
|
||||
break;
|
||||
case VariableType::Kind::FloatingPoint:
|
||||
ImGui::LabelText(name.c_str(), "[0x%08lx:0x%08lx] %f (0x%08lx) \"%s\"", offset,
|
||||
offset + type.size, data, data,
|
||||
makeDisplayable(buffer.data(), buffer.size()).c_str());
|
||||
break;
|
||||
}
|
||||
} else
|
||||
ImGui::LabelText(name.c_str(), "[0x%08lx:0x%08lx] [ ARRAY ] \"%s\"", offset, offset + type.size,
|
||||
makeDisplayable(buffer.data(), buffer.size()).c_str());
|
||||
for (auto& patternData : this->m_patternData) {
|
||||
ImGui::LabelText(patternData->getName().c_str(), "[0x%08lx:0x%08lx] %s",
|
||||
patternData->getOffset(),
|
||||
patternData->getOffset() + patternData->getSize(),
|
||||
patternData->format(this->m_dataProvider).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue