Revamped pattern data displaying to support per-type displaying

This commit is contained in:
WerWolv
2020-11-14 14:42:21 +01:00
parent 72f9da2a67
commit 658d4ec478
10 changed files with 358 additions and 133 deletions

View File

@@ -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;
}
}

View File

@@ -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;
};
}

View File

@@ -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;
};
}

View File

@@ -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;

View File

@@ -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);
};
}

View File

@@ -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;
};