refactor: Get rid of this->m_

This commit is contained in:
WerWolv
2023-12-19 13:10:25 +01:00
parent dd4be3b772
commit c7ab4a4569
119 changed files with 2973 additions and 2973 deletions

View File

@@ -113,13 +113,13 @@ namespace hex {
float xStep = (size.x * 0.95F) / 0xFF;
float yStep = (size.y * 0.95F) / 0xFF;
if (!this->m_processing)
for (size_t i = 0; i < (this->m_buffer.empty() ? 0 : this->m_buffer.size() - 1); i++) {
auto x = this->m_buffer[i] * xStep;
auto y = this->m_buffer[i + 1] * yStep;
if (!m_processing)
for (size_t i = 0; i < (m_buffer.empty() ? 0 : m_buffer.size() - 1); i++) {
auto x = m_buffer[i] * xStep;
auto y = m_buffer[i + 1] * yStep;
auto color = ImLerp(ImColor(0xFF, 0x6D, 0x01).Value, ImColor(0x01, 0x93, 0xFF).Value, float(i) / this->m_buffer.size()) + ImVec4(this->m_glowBuffer[i], this->m_glowBuffer[i], this->m_glowBuffer[i], 0.0F);
color.w = this->m_opacity;
auto color = ImLerp(ImColor(0xFF, 0x6D, 0x01).Value, ImColor(0x01, 0x93, 0xFF).Value, float(i) / m_buffer.size()) + ImVec4(m_glowBuffer[i], m_glowBuffer[i], m_glowBuffer[i], 0.0F);
color.w = m_opacity;
auto pos = ImGui::GetWindowPos() + ImVec2(size.x * 0.025F, size.y * 0.025F) + ImVec2(x, y);
drawList->AddRectFilled(pos, pos + ImVec2(xStep, yStep), ImColor(color));
@@ -130,36 +130,36 @@ namespace hex {
}
void process(prv::Provider *provider, u64 address, size_t size) {
this->m_processing = true;
this->m_buffer = impl::getSampleSelection(provider, address, size, this->m_sampleSize);
m_processing = true;
m_buffer = impl::getSampleSelection(provider, address, size, m_sampleSize);
processImpl();
this->m_processing = false;
m_processing = false;
}
void process(const std::vector<u8> &buffer) {
this->m_processing = true;
this->m_buffer = impl::getSampleSelection(buffer, this->m_sampleSize);
m_processing = true;
m_buffer = impl::getSampleSelection(buffer, m_sampleSize);
processImpl();
this->m_processing = false;
m_processing = false;
}
void reset(u64 size) {
this->m_processing = true;
this->m_buffer.clear();
this->m_buffer.reserve(this->m_sampleSize);
this->m_byteCount = 0;
this->m_fileSize = size;
m_processing = true;
m_buffer.clear();
m_buffer.reserve(m_sampleSize);
m_byteCount = 0;
m_fileSize = size;
}
void update(u8 byte) {
// Check if there is some space left
if (this->m_byteCount < this->m_fileSize) {
if ((this->m_byteCount % u64(std::ceil(double(this->m_fileSize) / double(this->m_sampleSize)))) == 0)
this->m_buffer.push_back(byte);
++this->m_byteCount;
if (this->m_byteCount == this->m_fileSize) {
if (m_byteCount < m_fileSize) {
if ((m_byteCount % u64(std::ceil(double(m_fileSize) / double(m_sampleSize)))) == 0)
m_buffer.push_back(byte);
++m_byteCount;
if (m_byteCount == m_fileSize) {
processImpl();
this->m_processing = false;
m_processing = false;
}
}
}
@@ -167,20 +167,20 @@ namespace hex {
private:
void processImpl() {
this->m_glowBuffer.resize(this->m_buffer.size());
m_glowBuffer.resize(m_buffer.size());
std::map<u64, size_t> heatMap;
for (size_t i = 0; i < (this->m_buffer.empty() ? 0 : this->m_buffer.size() - 1); i++) {
auto count = ++heatMap[this->m_buffer[i] << 8 | heatMap[i + 1]];
for (size_t i = 0; i < (m_buffer.empty() ? 0 : m_buffer.size() - 1); i++) {
auto count = ++heatMap[m_buffer[i] << 8 | heatMap[i + 1]];
this->m_highestCount = std::max(this->m_highestCount, count);
m_highestCount = std::max(m_highestCount, count);
}
for (size_t i = 0; i < (this->m_buffer.empty() ? 0 : this->m_buffer.size() - 1); i++) {
this->m_glowBuffer[i] = std::min<float>(0.2F + (float(heatMap[this->m_buffer[i] << 8 | this->m_buffer[i + 1]]) / float(this->m_highestCount / 1000)), 1.0F);
for (size_t i = 0; i < (m_buffer.empty() ? 0 : m_buffer.size() - 1); i++) {
m_glowBuffer[i] = std::min<float>(0.2F + (float(heatMap[m_buffer[i] << 8 | m_buffer[i + 1]]) / float(m_highestCount / 1000)), 1.0F);
}
this->m_opacity = (log10(float(this->m_sampleSize)) / log10(float(m_highestCount))) / 10.0F;
m_opacity = (log10(float(m_sampleSize)) / log10(float(m_highestCount))) / 10.0F;
}
private:
@@ -209,13 +209,13 @@ namespace hex {
float xStep = (size.x * 0.95F) / 0xFF;
float yStep = (size.y * 0.95F) / 0xFF;
if (!this->m_processing)
for (size_t i = 0; i < (this->m_buffer.empty() ? 0 : this->m_buffer.size()); i++) {
auto x = this->m_buffer[i] * xStep;
auto y = yStep * ((float(i) / this->m_buffer.size()) * 0xFF);
if (!m_processing)
for (size_t i = 0; i < (m_buffer.empty() ? 0 : m_buffer.size()); i++) {
auto x = m_buffer[i] * xStep;
auto y = yStep * ((float(i) / m_buffer.size()) * 0xFF);
auto color = ImLerp(ImColor(0xFF, 0x6D, 0x01).Value, ImColor(0x01, 0x93, 0xFF).Value, float(i) / this->m_buffer.size()) + ImVec4(this->m_glowBuffer[i], this->m_glowBuffer[i], this->m_glowBuffer[i], 0.0F);
color.w = this->m_opacity;
auto color = ImLerp(ImColor(0xFF, 0x6D, 0x01).Value, ImColor(0x01, 0x93, 0xFF).Value, float(i) / m_buffer.size()) + ImVec4(m_glowBuffer[i], m_glowBuffer[i], m_glowBuffer[i], 0.0F);
color.w = m_opacity;
auto pos = ImGui::GetWindowPos() + ImVec2(size.x * 0.025F, size.y * 0.025F) + ImVec2(x, y);
drawList->AddRectFilled(pos, pos + ImVec2(xStep, yStep), ImColor(color));
@@ -226,56 +226,56 @@ namespace hex {
}
void process(prv::Provider *provider, u64 address, size_t size) {
this->m_processing = true;
this->m_buffer = impl::getSampleSelection(provider, address, size, this->m_sampleSize);
m_processing = true;
m_buffer = impl::getSampleSelection(provider, address, size, m_sampleSize);
processImpl();
this->m_processing = false;
m_processing = false;
}
void process(const std::vector<u8> &buffer) {
this->m_processing = true;
this->m_buffer = impl::getSampleSelection(buffer, this->m_sampleSize);
m_processing = true;
m_buffer = impl::getSampleSelection(buffer, m_sampleSize);
processImpl();
this->m_processing = false;
m_processing = false;
}
void reset(u64 size) {
this->m_processing = true;
this->m_buffer.clear();
this->m_buffer.reserve(this->m_sampleSize);
this->m_byteCount = 0;
this->m_fileSize = size;
m_processing = true;
m_buffer.clear();
m_buffer.reserve(m_sampleSize);
m_byteCount = 0;
m_fileSize = size;
}
void update(u8 byte) {
// Check if there is some space left
if (this->m_byteCount < this->m_fileSize) {
if ((this->m_byteCount % u64(std::ceil(double(this->m_fileSize) / double(this->m_sampleSize)))) == 0)
this->m_buffer.push_back(byte);
++this->m_byteCount;
if (this->m_byteCount == this->m_fileSize) {
if (m_byteCount < m_fileSize) {
if ((m_byteCount % u64(std::ceil(double(m_fileSize) / double(m_sampleSize)))) == 0)
m_buffer.push_back(byte);
++m_byteCount;
if (m_byteCount == m_fileSize) {
processImpl();
this->m_processing = false;
m_processing = false;
}
}
}
private:
void processImpl() {
this->m_glowBuffer.resize(this->m_buffer.size());
m_glowBuffer.resize(m_buffer.size());
std::map<u64, size_t> heatMap;
for (size_t i = 0; i < (this->m_buffer.empty() ? 0 : this->m_buffer.size() - 1); i++) {
auto count = ++heatMap[this->m_buffer[i] << 8 | heatMap[i + 1]];
for (size_t i = 0; i < (m_buffer.empty() ? 0 : m_buffer.size() - 1); i++) {
auto count = ++heatMap[m_buffer[i] << 8 | heatMap[i + 1]];
this->m_highestCount = std::max(this->m_highestCount, count);
m_highestCount = std::max(m_highestCount, count);
}
for (size_t i = 0; i < (this->m_buffer.empty() ? 0 : this->m_buffer.size() - 1); i++) {
this->m_glowBuffer[i] = std::min<float>(0.2F + (float(heatMap[this->m_buffer[i] << 8 | this->m_buffer[i + 1]]) / float(this->m_highestCount / 1000)), 1.0F);
for (size_t i = 0; i < (m_buffer.empty() ? 0 : m_buffer.size() - 1); i++) {
m_glowBuffer[i] = std::min<float>(0.2F + (float(heatMap[m_buffer[i] << 8 | m_buffer[i + 1]]) / float(m_highestCount / 1000)), 1.0F);
}
this->m_opacity = (log10(float(this->m_sampleSize)) / log10(float(m_highestCount))) / 10.0F;
m_opacity = (log10(float(m_sampleSize)) / log10(float(m_highestCount))) / 10.0F;
}
private:
size_t m_sampleSize = 0;
@@ -298,7 +298,7 @@ namespace hex {
void draw(ImVec2 size, ImPlotFlags flags, bool updateHandle = false) {
if (!this->m_processing && ImPlot::BeginPlot("##ChunkBasedAnalysis", size, flags)) {
if (!m_processing && ImPlot::BeginPlot("##ChunkBasedAnalysis", size, flags)) {
ImPlot::SetupAxes("hex.builtin.common.address"_lang, "hex.builtin.view.information.entropy"_lang,
ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch,
ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch);
@@ -307,31 +307,31 @@ namespace hex {
// Set the axis limit to [first block : last block]
ImPlot::SetupAxesLimits(
this->m_xBlockEntropy.empty() ? 0 : this->m_xBlockEntropy.front(),
this->m_xBlockEntropy.empty() ? 0 : this->m_xBlockEntropy.back(),
m_xBlockEntropy.empty() ? 0 : m_xBlockEntropy.front(),
m_xBlockEntropy.empty() ? 0 : m_xBlockEntropy.back(),
-0.1F,
1.1F,
ImGuiCond_Always);
// Draw the plot
ImPlot::PlotLine("##ChunkBasedAnalysisLine", this->m_xBlockEntropy.data(), this->m_yBlockEntropySampled.data(), this->m_xBlockEntropy.size());
ImPlot::PlotLine("##ChunkBasedAnalysisLine", m_xBlockEntropy.data(), m_yBlockEntropySampled.data(), m_xBlockEntropy.size());
// The parameter updateHandle is used when using the pattern language since we don't have a provider
// but just a set of bytes, we won't be able to use the drag bar correctly.
if (updateHandle) {
// Set a draggable line on the plot
if (ImPlot::DragLineX(1, &this->m_handlePosition, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
if (ImPlot::DragLineX(1, &m_handlePosition, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
// The line was dragged, update the position in the hex editor
// Clamp the value between the start/end of the region to analyze
this->m_handlePosition = std::clamp<double>(
this->m_handlePosition,
this->m_startAddress,
this->m_endAddress);
m_handlePosition = std::clamp<double>(
m_handlePosition,
m_startAddress,
m_endAddress);
// Compute the position inside hex editor
u64 address = u64(std::max<double>(this->m_handlePosition, 0)) + this->m_baseAddress;
address = std::min<u64>(address, this->m_baseAddress + this->m_fileSize - 1);
u64 address = u64(std::max<double>(m_handlePosition, 0)) + m_baseAddress;
address = std::min<u64>(address, m_baseAddress + m_fileSize - 1);
ImHexApi::HexEditor::setSelection(address, 1);
}
}
@@ -340,92 +340,92 @@ namespace hex {
}
void process(prv::Provider *provider, u64 chunkSize, u64 startAddress, u64 endAddress) {
this->m_processing = true;
m_processing = true;
// Update attributes
this->m_chunkSize = chunkSize;
this->m_startAddress = startAddress;
this->m_endAddress = endAddress;
m_chunkSize = chunkSize;
m_startAddress = startAddress;
m_endAddress = endAddress;
this->m_baseAddress = provider->getBaseAddress();
this->m_fileSize = provider->getSize();
m_baseAddress = provider->getBaseAddress();
m_fileSize = provider->getSize();
// Get a file reader
auto reader = prv::ProviderReader(provider);
std::vector<u8> bytes = reader.read(this->m_startAddress, this->m_endAddress - this->m_startAddress);
std::vector<u8> bytes = reader.read(m_startAddress, m_endAddress - m_startAddress);
this->processImpl(bytes);
// Set the diagram handle position to the start of the plot
this->m_handlePosition = this->m_startAddress;
m_handlePosition = m_startAddress;
this->m_processing = false;
m_processing = false;
}
void process(const std::vector<u8> &buffer, u64 chunkSize) {
this->m_processing = true;
m_processing = true;
// Update attributes (use buffer size as end address)
this->m_chunkSize = chunkSize;
this->m_startAddress = 0;
this->m_endAddress = buffer.size();
m_chunkSize = chunkSize;
m_startAddress = 0;
m_endAddress = buffer.size();
this->m_baseAddress = 0;
this->m_fileSize = buffer.size();
m_baseAddress = 0;
m_fileSize = buffer.size();
this->processImpl(buffer);
// Set the diagram handle position to the start of the plot
this->m_handlePosition = this->m_startAddress;
m_handlePosition = m_startAddress;
this->m_processing = false;
m_processing = false;
}
// Reset the entropy analysis
void reset(u64 chunkSize, u64 startAddress, u64 endAddress, u64 baseAddress, u64 size) {
this->m_processing = true;
m_processing = true;
// Update attributes
this->m_chunkSize = chunkSize;
this->m_startAddress = startAddress;
this->m_endAddress = endAddress;
this->m_baseAddress = baseAddress;
this->m_fileSize = size;
m_chunkSize = chunkSize;
m_startAddress = startAddress;
m_endAddress = endAddress;
m_baseAddress = baseAddress;
m_fileSize = size;
this->m_blockValueCounts = { 0 };
m_blockValueCounts = { 0 };
// Reset and resize the array
this->m_yBlockEntropy.clear();
m_yBlockEntropy.clear();
this->m_byteCount = 0;
this->m_blockCount = 0;
m_byteCount = 0;
m_blockCount = 0;
// Set the diagram handle position to the start of the plot
this->m_handlePosition = this->m_startAddress;
m_handlePosition = m_startAddress;
}
// Process one byte at the time
void update(u8 byte) {
u64 totalBlock = std::ceil((this->m_endAddress - this->m_startAddress) / this->m_chunkSize);
u64 totalBlock = std::ceil((m_endAddress - m_startAddress) / m_chunkSize);
// Check if there is still some
if (this->m_blockCount < totalBlock) {
if (m_blockCount < totalBlock) {
// Increment the occurrence of the current byte
this->m_blockValueCounts[byte]++;
m_blockValueCounts[byte]++;
this->m_byteCount++;
m_byteCount++;
// Check if we processed one complete chunk, if so compute the entropy and start analysing the next chunk
if (((this->m_byteCount % this->m_chunkSize) == 0) || this->m_byteCount == (this->m_endAddress - this->m_startAddress)) [[unlikely]] {
this->m_yBlockEntropy.push_back(calculateEntropy(this->m_blockValueCounts, this->m_chunkSize));
if (((m_byteCount % m_chunkSize) == 0) || m_byteCount == (m_endAddress - m_startAddress)) [[unlikely]] {
m_yBlockEntropy.push_back(calculateEntropy(m_blockValueCounts, m_chunkSize));
this->m_blockCount += 1;
this->m_blockValueCounts = { 0 };
m_blockCount += 1;
m_blockValueCounts = { 0 };
}
// Check if we processed the last block, if so setup the X axis part of the data
if (this->m_blockCount == totalBlock) {
if (m_blockCount == totalBlock) {
processFinalize();
this->m_processing = false;
m_processing = false;
}
}
}
@@ -456,72 +456,72 @@ namespace hex {
// Return the highest entropy value among all of the blocks
double getHighestEntropyBlockValue() {
double result = 0.0f;
if (!this->m_yBlockEntropy.empty())
result = *std::max_element(this->m_yBlockEntropy.begin(), this->m_yBlockEntropy.end());
if (!m_yBlockEntropy.empty())
result = *std::max_element(m_yBlockEntropy.begin(), m_yBlockEntropy.end());
return result;
}
// Return the highest entropy value among all of the blocks
u64 getHighestEntropyBlockAddress() {
u64 address = 0x00;
if (!this->m_yBlockEntropy.empty())
address = (std::max_element(this->m_yBlockEntropy.begin(), this->m_yBlockEntropy.end()) - this->m_yBlockEntropy.begin()) * this->m_blockSize;
return this->m_startAddress + address;
if (!m_yBlockEntropy.empty())
address = (std::max_element(m_yBlockEntropy.begin(), m_yBlockEntropy.end()) - m_yBlockEntropy.begin()) * m_blockSize;
return m_startAddress + address;
}
// Return the highest entropy value among all of the blocks
double getLowestEntropyBlockValue() {
double result = 0.0f;
if (this->m_yBlockEntropy.size() > 1)
result = *std::min_element(this->m_yBlockEntropy.begin(), this->m_yBlockEntropy.end() - 1);
if (m_yBlockEntropy.size() > 1)
result = *std::min_element(m_yBlockEntropy.begin(), m_yBlockEntropy.end() - 1);
return result;
}
// Return the highest entropy value among all of the blocks
u64 getLowestEntropyBlockAddress() {
u64 address = 0x00;
if (this->m_yBlockEntropy.size() > 1)
address = (std::min_element(this->m_yBlockEntropy.begin(), this->m_yBlockEntropy.end() - 1) - this->m_yBlockEntropy.begin()) * this->m_blockSize;
return this->m_startAddress + address;
if (m_yBlockEntropy.size() > 1)
address = (std::min_element(m_yBlockEntropy.begin(), m_yBlockEntropy.end() - 1) - m_yBlockEntropy.begin()) * m_blockSize;
return m_startAddress + address;
}
// Return the number of blocks that have been processed
u64 getSize() const {
return this->m_yBlockEntropySampled.size();
return m_yBlockEntropySampled.size();
}
// Return the size of the chunk used for this analysis
u64 getChunkSize() const {
return this->m_chunkSize;
return m_chunkSize;
}
void setHandlePosition(u64 filePosition) {
this->m_handlePosition = filePosition;
m_handlePosition = filePosition;
}
private:
// Private method used to factorize the process public method
void processImpl(const std::vector<u8> &bytes) {
this->m_blockValueCounts = { 0 };
m_blockValueCounts = { 0 };
// Reset and resize the array
this->m_yBlockEntropy.clear();
m_yBlockEntropy.clear();
this->m_byteCount = 0;
this->m_blockCount = 0;
m_byteCount = 0;
m_blockCount = 0;
// Loop over each byte of the file (or a part of it)
for (u8 byte: bytes) {
// Increment the occurrence of the current byte
this->m_blockValueCounts[byte]++;
m_blockValueCounts[byte]++;
this->m_byteCount++;
m_byteCount++;
// Check if we processed one complete chunk, if so compute the entropy and start analysing the next chunk
if (((this->m_byteCount % this->m_chunkSize) == 0) || this->m_byteCount == bytes.size() * 8) [[unlikely]] {
this->m_yBlockEntropy.push_back(calculateEntropy(this->m_blockValueCounts, this->m_chunkSize));
if (((m_byteCount % m_chunkSize) == 0) || m_byteCount == bytes.size() * 8) [[unlikely]] {
m_yBlockEntropy.push_back(calculateEntropy(m_blockValueCounts, m_chunkSize));
this->m_blockCount += 1;
this->m_blockValueCounts = { 0 };
m_blockCount += 1;
m_blockValueCounts = { 0 };
}
}
processFinalize();
@@ -529,23 +529,23 @@ namespace hex {
void processFinalize() {
// Only save at most m_sampleSize elements of the result
this->m_yBlockEntropySampled = sampleData(this->m_yBlockEntropy, std::min<size_t>(this->m_blockCount + 1, this->m_sampleSize));
m_yBlockEntropySampled = sampleData(m_yBlockEntropy, std::min<size_t>(m_blockCount + 1, m_sampleSize));
if (!this->m_yBlockEntropySampled.empty())
this->m_yBlockEntropySampled.push_back(this->m_yBlockEntropySampled.back());
if (!m_yBlockEntropySampled.empty())
m_yBlockEntropySampled.push_back(m_yBlockEntropySampled.back());
double stride = std::max(1.0, double(
double(std::ceil((this->m_endAddress - this->m_startAddress)) / this->m_blockSize) / this->m_yBlockEntropySampled.size()));
double(std::ceil((m_endAddress - m_startAddress)) / m_blockSize) / m_yBlockEntropySampled.size()));
this->m_blockCount = this->m_yBlockEntropySampled.size() - 1;
m_blockCount = m_yBlockEntropySampled.size() - 1;
// The m_xBlockEntropy attribute is used to specify the position of entropy values
// in the plot when the Y axis doesn't start at 0
this->m_xBlockEntropy.clear();
this->m_xBlockEntropy.resize(this->m_blockCount);
for (u64 i = 0; i < this->m_blockCount; ++i)
this->m_xBlockEntropy[i] = ((this->m_startAddress / this->m_blockSize) + stride * i) * this->m_blockSize;
this->m_xBlockEntropy.push_back(this->m_endAddress);
m_xBlockEntropy.clear();
m_xBlockEntropy.resize(m_blockCount);
for (u64 i = 0; i < m_blockCount; ++i)
m_xBlockEntropy[i] = ((m_startAddress / m_blockSize) + stride * i) * m_blockSize;
m_xBlockEntropy.push_back(m_endAddress);
}
private:
@@ -594,12 +594,12 @@ namespace hex {
void draw(ImVec2 size, ImPlotFlags flags) {
if (!this->m_processing && ImPlot::BeginPlot("##distribution", size, flags)) {
if (!m_processing && ImPlot::BeginPlot("##distribution", size, flags)) {
ImPlot::SetupAxes("hex.builtin.common.value"_lang, "hex.builtin.common.count"_lang,
ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch,
ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch);
ImPlot::SetupAxisScale(ImAxis_Y1, ImPlotScale_Log10);
ImPlot::SetupAxesLimits(-1, 256, 1, double(*std::max_element(this->m_valueCounts.begin(), this->m_valueCounts.end())) * 1.1F, ImGuiCond_Always);
ImPlot::SetupAxesLimits(-1, 256, 1, double(*std::max_element(m_valueCounts.begin(), m_valueCounts.end())) * 1.1F, ImGuiCond_Always);
ImPlot::SetupAxisFormat(ImAxis_X1, impl::IntegerAxisFormatter, (void*)("0x%02llX"));
ImPlot::SetupAxisTicks(ImAxis_X1, 0, 255, 17);
ImPlot::SetupMouseText(ImPlotLocation_NorthEast);
@@ -610,67 +610,67 @@ namespace hex {
return result;
}();
ImPlot::PlotBars<ImU64>("##bytes", x.data(), this->m_valueCounts.data(), x.size(), 1);
ImPlot::PlotBars<ImU64>("##bytes", x.data(), m_valueCounts.data(), x.size(), 1);
ImPlot::EndPlot();
}
}
void process(prv::Provider *provider, u64 startAddress, u64 endAddress) {
this->m_processing = true;
m_processing = true;
// Update attributes
this->m_startAddress = startAddress;
this->m_endAddress = endAddress;
m_startAddress = startAddress;
m_endAddress = endAddress;
// Get a file reader
auto reader = prv::ProviderReader(provider);
std::vector<u8> bytes = reader.read(this->m_startAddress, this->m_endAddress - this->m_startAddress);
std::vector<u8> bytes = reader.read(m_startAddress, m_endAddress - m_startAddress);
this->processImpl(bytes);
this->m_processing = false;
m_processing = false;
}
void process(const std::vector<u8> &buffer) {
this->m_processing = true;
m_processing = true;
// Update attributes
this->m_startAddress = 0;
this->m_endAddress = buffer.size();
m_startAddress = 0;
m_endAddress = buffer.size();
this->processImpl(buffer);
this->m_processing = false;
m_processing = false;
}
// Reset the byte distribution array
void reset() {
this->m_processing = true;
this->m_valueCounts.fill(0);
this->m_processing = false;
m_processing = true;
m_valueCounts.fill(0);
m_processing = false;
}
// Process one byte at the time
void update(u8 byte) {
this->m_processing = true;
this->m_valueCounts[byte]++;
this->m_processing = false;
m_processing = true;
m_valueCounts[byte]++;
m_processing = false;
}
// Return byte distribution array in it's current state
std::array<ImU64, 256> & get() {
return this->m_valueCounts;
return m_valueCounts;
}
private:
// Private method used to factorize the process public method
void processImpl(const std::vector<u8> &bytes) {
// Reset the array
this->m_valueCounts.fill(0);
m_valueCounts.fill(0);
// Loop over each byte of the file (or a part of it)
// Increment the occurrence of the current byte
for (u8 byte : bytes)
this->m_valueCounts[byte]++;
m_valueCounts[byte]++;
}
private:
@@ -689,13 +689,13 @@ namespace hex {
void draw(ImVec2 size, ImPlotFlags flags, bool updateHandle = false) {
// Draw the result of the analysis
if (!this->m_processing && ImPlot::BeginPlot("##byte_types", size, flags)) {
if (!m_processing && ImPlot::BeginPlot("##byte_types", size, flags)) {
ImPlot::SetupAxes("hex.builtin.common.address"_lang, "hex.builtin.common.percentage"_lang,
ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch,
ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoHighlight | ImPlotAxisFlags_NoSideSwitch);
ImPlot::SetupAxesLimits(
this->m_xBlockTypeDistributions.empty() ? 0 : this->m_xBlockTypeDistributions.front(),
this->m_xBlockTypeDistributions.empty() ? 0 : this->m_xBlockTypeDistributions.back(),
m_xBlockTypeDistributions.empty() ? 0 : m_xBlockTypeDistributions.front(),
m_xBlockTypeDistributions.empty() ? 0 : m_xBlockTypeDistributions.back(),
-0.1F,
100.1F,
ImGuiCond_Always);
@@ -709,25 +709,25 @@ namespace hex {
};
for (u32 i = 0; i < Names.size(); i++) {
ImPlot::PlotLine(Names[i], this->m_xBlockTypeDistributions.data(), this->m_yBlockTypeDistributionsSampled[i].data(), this->m_xBlockTypeDistributions.size());
ImPlot::PlotLine(Names[i], m_xBlockTypeDistributions.data(), m_yBlockTypeDistributionsSampled[i].data(), m_xBlockTypeDistributions.size());
}
// The parameter updateHandle is used when using the pattern language since we don't have a provider
// but just a set of bytes, we won't be able to use the drag bar correctly.
if (updateHandle) {
// Set a draggable line on the plot
if (ImPlot::DragLineX(1, &this->m_handlePosition, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
if (ImPlot::DragLineX(1, &m_handlePosition, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
// The line was dragged, update the position in the hex editor
// Clamp the value between the start/end of the region to analyze
this->m_handlePosition = std::clamp<double>(
this->m_handlePosition,
this->m_startAddress,
this->m_endAddress);
m_handlePosition = std::clamp<double>(
m_handlePosition,
m_startAddress,
m_endAddress);
// Compute the position inside hex editor
u64 address = u64(std::max<double>(this->m_handlePosition, 0)) + this->m_baseAddress;
address = std::min<u64>(address, this->m_baseAddress + this->m_fileSize - 1);
u64 address = u64(std::max<double>(m_handlePosition, 0)) + m_baseAddress;
address = std::min<u64>(address, m_baseAddress + m_fileSize - 1);
ImHexApi::HexEditor::setSelection(address, 1);
}
}
@@ -736,103 +736,103 @@ namespace hex {
}
void process(prv::Provider *provider, u64 startAddress, u64 endAddress) {
this->m_processing = true;
m_processing = true;
// Update attributes
this->m_startAddress = startAddress;
this->m_endAddress = endAddress;
this->m_baseAddress = provider->getBaseAddress();
this->m_fileSize = provider->getSize();
m_startAddress = startAddress;
m_endAddress = endAddress;
m_baseAddress = provider->getBaseAddress();
m_fileSize = provider->getSize();
// Get a file reader
auto reader = prv::ProviderReader(provider);
std::vector<u8> bytes = reader.read(this->m_startAddress, this->m_endAddress - this->m_startAddress);
std::vector<u8> bytes = reader.read(m_startAddress, m_endAddress - m_startAddress);
this->processImpl(bytes);
// Set the diagram handle position to the start of the plot
this->m_handlePosition = this->m_startAddress;
m_handlePosition = m_startAddress;
this->m_processing = false;
m_processing = false;
}
void process(const std::vector<u8> &buffer, u64 baseAddress, u64 fileSize) {
this->m_processing = true;
m_processing = true;
// Update attributes
this->m_startAddress = 0;
this->m_endAddress = buffer.size();
this->m_baseAddress = baseAddress;
this->m_fileSize = fileSize;
m_startAddress = 0;
m_endAddress = buffer.size();
m_baseAddress = baseAddress;
m_fileSize = fileSize;
this->processImpl(buffer);
// Set the diagram handle position to the start of the plot
this->m_handlePosition = this->m_startAddress;
m_handlePosition = m_startAddress;
this->m_processing = false;
m_processing = false;
}
// Reset the byte type distribution analysis
void reset(u64 startAddress, u64 endAddress, u64 baseAddress, u64 size) {
this->m_processing = true;
m_processing = true;
// Update attributes
this->m_startAddress = startAddress;
this->m_endAddress = endAddress;
this->m_baseAddress = baseAddress;
this->m_fileSize = size;
m_startAddress = startAddress;
m_endAddress = endAddress;
m_baseAddress = baseAddress;
m_fileSize = size;
this->m_byteCount = 0;
this->m_blockCount = 0;
this->m_blockValueCounts = { 0 };
m_byteCount = 0;
m_blockCount = 0;
m_blockValueCounts = { 0 };
// Reset and resize the array
this->m_yBlockTypeDistributions.fill({});
m_yBlockTypeDistributions.fill({});
// Set the diagram handle position to the start of the plot
this->m_handlePosition = this->m_startAddress;
m_handlePosition = m_startAddress;
}
// Process one byte at the time
void update(u8 byte) {
u64 totalBlock = std::ceil((this->m_endAddress - this->m_startAddress) / this->m_blockSize);
u64 totalBlock = std::ceil((m_endAddress - m_startAddress) / m_blockSize);
// Check if there is still some block to process
if (this->m_blockCount < totalBlock) {
if (m_blockCount < totalBlock) {
this->m_blockValueCounts[byte]++;
m_blockValueCounts[byte]++;
this->m_byteCount++;
if (((this->m_byteCount % this->m_blockSize) == 0) || this->m_byteCount == (this->m_endAddress - this->m_startAddress)) [[unlikely]] {
auto typeDist = calculateTypeDistribution(this->m_blockValueCounts, this->m_blockSize);
m_byteCount++;
if (((m_byteCount % m_blockSize) == 0) || m_byteCount == (m_endAddress - m_startAddress)) [[unlikely]] {
auto typeDist = calculateTypeDistribution(m_blockValueCounts, m_blockSize);
for (size_t i = 0; i < typeDist.size(); i++)
this->m_yBlockTypeDistributions[i].push_back(typeDist[i] * 100);
m_yBlockTypeDistributions[i].push_back(typeDist[i] * 100);
this->m_blockCount += 1;
this->m_blockValueCounts = { 0 };
m_blockCount += 1;
m_blockValueCounts = { 0 };
}
// Check if we processed the last block, if so setup the X axis part of the data
if (this->m_blockCount == totalBlock) {
if (m_blockCount == totalBlock) {
processFinalize();
this->m_processing = false;
m_processing = false;
}
}
}
// Return the percentage of plain text character inside the analyzed region
double getPlainTextCharacterPercentage() {
if (this->m_yBlockTypeDistributions[2].empty() || this->m_yBlockTypeDistributions[4].empty())
if (m_yBlockTypeDistributions[2].empty() || m_yBlockTypeDistributions[4].empty())
return -1.0;
double plainTextPercentage = std::reduce(this->m_yBlockTypeDistributions[2].begin(), this->m_yBlockTypeDistributions[2].end()) / this->m_yBlockTypeDistributions[2].size();
return plainTextPercentage + std::reduce(this->m_yBlockTypeDistributions[4].begin(), this->m_yBlockTypeDistributions[4].end()) / this->m_yBlockTypeDistributions[4].size();
double plainTextPercentage = std::reduce(m_yBlockTypeDistributions[2].begin(), m_yBlockTypeDistributions[2].end()) / m_yBlockTypeDistributions[2].size();
return plainTextPercentage + std::reduce(m_yBlockTypeDistributions[4].begin(), m_yBlockTypeDistributions[4].end()) / m_yBlockTypeDistributions[4].size();
}
void setHandlePosition(u64 filePosition) {
this->m_handlePosition = filePosition;
m_handlePosition = filePosition;
}
private:
@@ -880,24 +880,24 @@ namespace hex {
// Private method used to factorize the process public method
void processImpl(const std::vector<u8> &bytes) {
this->m_blockValueCounts = { 0 };
m_blockValueCounts = { 0 };
this->m_yBlockTypeDistributions.fill({});
this->m_byteCount = 0;
this->m_blockCount = 0;
m_yBlockTypeDistributions.fill({});
m_byteCount = 0;
m_blockCount = 0;
// Loop over each byte of the file (or a part of it)
for (u8 byte : bytes) {
this->m_blockValueCounts[byte]++;
m_blockValueCounts[byte]++;
this->m_byteCount++;
if (((this->m_byteCount % this->m_blockSize) == 0) || this->m_byteCount == (this->m_endAddress - this->m_startAddress)) [[unlikely]] {
auto typeDist = calculateTypeDistribution(this->m_blockValueCounts, this->m_blockSize);
m_byteCount++;
if (((m_byteCount % m_blockSize) == 0) || m_byteCount == (m_endAddress - m_startAddress)) [[unlikely]] {
auto typeDist = calculateTypeDistribution(m_blockValueCounts, m_blockSize);
for (size_t i = 0; i < typeDist.size(); i++)
this->m_yBlockTypeDistributions[i].push_back(typeDist[i] * 100);
m_yBlockTypeDistributions[i].push_back(typeDist[i] * 100);
this->m_blockCount += 1;
this->m_blockValueCounts = { 0 };
m_blockCount += 1;
m_blockValueCounts = { 0 };
}
}
@@ -906,23 +906,23 @@ namespace hex {
void processFinalize() {
// Only save at most m_sampleSize elements of the result
for (size_t i = 0; i < this->m_yBlockTypeDistributions.size(); ++i) {
this->m_yBlockTypeDistributionsSampled[i] = sampleData(this->m_yBlockTypeDistributions[i], std::min<size_t>(this->m_blockCount + 1, this->m_sampleSize));
for (size_t i = 0; i < m_yBlockTypeDistributions.size(); ++i) {
m_yBlockTypeDistributionsSampled[i] = sampleData(m_yBlockTypeDistributions[i], std::min<size_t>(m_blockCount + 1, m_sampleSize));
if (!this->m_yBlockTypeDistributionsSampled[i].empty())
this->m_yBlockTypeDistributionsSampled[i].push_back(this->m_yBlockTypeDistributionsSampled[i].back());
if (!m_yBlockTypeDistributionsSampled[i].empty())
m_yBlockTypeDistributionsSampled[i].push_back(m_yBlockTypeDistributionsSampled[i].back());
}
double stride = std::max(1.0, double(this->m_blockCount) / this->m_yBlockTypeDistributionsSampled[0].size());
this->m_blockCount = this->m_yBlockTypeDistributionsSampled[0].size() - 1;
double stride = std::max(1.0, double(m_blockCount) / m_yBlockTypeDistributionsSampled[0].size());
m_blockCount = m_yBlockTypeDistributionsSampled[0].size() - 1;
// The m_xBlockTypeDistributions attribute is used to specify the position of entropy
// values in the plot when the Y axis doesn't start at 0
this->m_xBlockTypeDistributions.clear();
this->m_xBlockTypeDistributions.resize(this->m_blockCount);
for (u64 i = 0; i < this->m_blockCount; ++i)
this->m_xBlockTypeDistributions[i] = this->m_startAddress + (stride * i * this->m_blockSize);
this->m_xBlockTypeDistributions.push_back(this->m_endAddress);
m_xBlockTypeDistributions.clear();
m_xBlockTypeDistributions.resize(m_blockCount);
for (u64 i = 0; i < m_blockCount; ++i)
m_xBlockTypeDistributions[i] = m_startAddress + (stride * i * m_blockSize);
m_xBlockTypeDistributions.push_back(m_endAddress);
}
private:

View File

@@ -16,16 +16,16 @@ namespace hex::plugin::builtin {
ImGui::TextUnformatted("hex.builtin.popup.blocking_task.desc"_lang);
ImGui::Separator();
if (this->m_task.getProgress() == 0)
if (m_task.getProgress() == 0)
ImGuiExt::TextSpinner("");
else
ImGui::ProgressBar(this->m_task.getProgress() / 100.0F);
ImGui::ProgressBar(m_task.getProgress() / 100.0F);
ImGui::NewLine();
if (ImGui::ButtonEx("hex.builtin.common.cancel"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0)) || ImGui::IsKeyDown(ImGuiKey_Escape))
this->m_task.interrupt();
m_task.interrupt();
if (!this->m_task.isRunning()) {
if (!m_task.isRunning()) {
ImGui::CloseCurrentPopup();
}
}

View File

@@ -24,23 +24,23 @@ namespace hex::plugin::builtin {
void drawContent() override {
ImGui::PushItemWidth(600_scaled);
ImGui::BeginDisabled(this->m_requestTask.isRunning());
if (ImGui::InputText("##input", this->m_inputBuffer, ImGuiInputTextFlags_EnterReturnsTrue)) {
ImGui::BeginDisabled(m_requestTask.isRunning());
if (ImGui::InputText("##input", m_inputBuffer, ImGuiInputTextFlags_EnterReturnsTrue)) {
this->executeQuery();
}
ImGui::EndDisabled();
ImGui::PopItemWidth();
if (ImGui::BeginChild("##answer", scaled(ImVec2(600, 350)), true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
if (!this->m_requestTask.isRunning()) {
if (this->m_answer.empty()) {
if (this->m_noAnswer)
if (!m_requestTask.isRunning()) {
if (m_answer.empty()) {
if (m_noAnswer)
ImGuiExt::TextFormattedCentered("{}", "hex.builtin.popup.docs_question.no_answer"_lang);
else
ImGuiExt::TextFormattedCentered("{}", "hex.builtin.popup.docs_question.prompt"_lang);
} else {
int id = 1;
for (auto &[type, text] : this->m_answer) {
for (auto &[type, text] : m_answer) {
ImGui::PushID(id);
switch (type) {
case TextBlockType::Text:
@@ -79,10 +79,10 @@ namespace hex::plugin::builtin {
private:
void executeQuery() {
this->m_requestTask = TaskManager::createBackgroundTask("Query Docs", [this, input = this->m_inputBuffer](Task &) {
this->m_noAnswer = false;
m_requestTask = TaskManager::createBackgroundTask("Query Docs", [this, input = m_inputBuffer](Task &) {
m_noAnswer = false;
for (auto space : { "xj7sbzGbHH260vbpZOu1", "WZzDdGjxmgMSIE3xly6o" }) {
this->m_answer.clear();
m_answer.clear();
auto request = HttpRequest("POST", hex::format("https://api.gitbook.com/v1/spaces/{}/search/ask", space));
@@ -115,19 +115,19 @@ namespace hex::plugin::builtin {
if (block.starts_with("rust\n")) {
block = block.substr(5);
this->m_answer.emplace_back(TextBlockType::Code, block);
m_answer.emplace_back(TextBlockType::Code, block);
} else if (block.starts_with("cpp\n")) {
block = block.substr(4);
this->m_answer.emplace_back(TextBlockType::Code, block);
m_answer.emplace_back(TextBlockType::Code, block);
} else {
this->m_answer.emplace_back(TextBlockType::Text, block);
m_answer.emplace_back(TextBlockType::Text, block);
}
}
} catch(...) {
continue;
}
this->m_noAnswer = this->m_answer.empty();
m_noAnswer = m_answer.empty();
}
});
}

View File

@@ -31,10 +31,10 @@ namespace hex::plugin::builtin {
if (adjustedPath.empty())
adjustedPath = path.filename();
this->m_files.push_back({ path, adjustedPath });
m_files.push_back({ path, adjustedPath });
}
std::sort(this->m_files.begin(), this->m_files.end(), [](const auto &a, const auto &b) {
std::sort(m_files.begin(), m_files.end(), [](const auto &a, const auto &b) {
return a.first < b.first;
});
}
@@ -44,19 +44,19 @@ namespace hex::plugin::builtin {
if (ImGui::BeginListBox("##files", scaled(ImVec2(500, 400)))) {
u32 index = 0;
for (auto &[path, pathName] : this->m_files) {
for (auto &[path, pathName] : m_files) {
ImGui::PushID(index);
bool selected = this->m_indices.contains(index);
bool selected = m_indices.contains(index);
if (ImGui::Selectable(wolv::util::toUTF8String(pathName).c_str(), selected, ImGuiSelectableFlags_DontClosePopups)) {
if (!this->m_multiple) {
this->m_indices.clear();
this->m_indices.insert(index);
if (!m_multiple) {
m_indices.clear();
m_indices.insert(index);
} else {
if (selected) {
this->m_indices.erase(index);
m_indices.erase(index);
} else {
this->m_indices.insert(index);
m_indices.insert(index);
}
}
}
@@ -74,18 +74,18 @@ namespace hex::plugin::builtin {
}
if (ImGui::Button("hex.builtin.common.open"_lang) || doubleClicked) {
for (const auto &index : this->m_indices)
this->m_openCallback(this->m_files[index].first);
for (const auto &index : m_indices)
m_openCallback(m_files[index].first);
Popup::close();
}
ImGui::SameLine();
if (ImGui::Button("hex.builtin.common.browse"_lang)) {
fs::openFileBrowser(fs::DialogMode::Open, this->m_validExtensions, [this](const auto &path) {
this->m_openCallback(path);
fs::openFileBrowser(fs::DialogMode::Open, m_validExtensions, [this](const auto &path) {
m_openCallback(path);
Popup::close();
}, {}, this->m_multiple);
}, {}, m_multiple);
}
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Escape)))

View File

@@ -20,11 +20,11 @@ namespace hex::plugin::builtin {
m_message(std::move(message)), m_function(std::move(function)) { }
void drawContent() override {
ImGuiExt::TextFormattedWrapped("{}", this->m_message.c_str());
ImGuiExt::TextFormattedWrapped("{}", m_message.c_str());
ImGui::NewLine();
ImGui::Separator();
if (ImGui::Button("hex.builtin.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape))
this->m_function();
m_function();
ImGui::SetWindowPos((ImHexApi::System::getMainWindowSize() - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);

View File

@@ -17,20 +17,20 @@ namespace hex::plugin::builtin {
m_yesFunction(std::move(yesFunction)), m_noFunction(std::move(noFunction)) { }
void drawContent() override {
ImGuiExt::TextFormattedWrapped("{}", this->m_message.c_str());
ImGuiExt::TextFormattedWrapped("{}", m_message.c_str());
ImGui::NewLine();
ImGui::Separator();
auto width = ImGui::GetWindowWidth();
ImGui::SetCursorPosX(width / 9);
if (ImGui::Button("hex.builtin.common.yes"_lang, ImVec2(width / 3, 0))) {
this->m_yesFunction();
m_yesFunction();
this->close();
}
ImGui::SameLine();
ImGui::SetCursorPosX(width / 9 * 5);
if (ImGui::Button("hex.builtin.common.no"_lang, ImVec2(width / 3, 0))) {
this->m_noFunction();
m_noFunction();
this->close();
}

View File

@@ -15,12 +15,12 @@ namespace hex::plugin::builtin {
PopupTelemetryRequest()
: hex::Popup<PopupTelemetryRequest>("hex.builtin.common.question", false) {
// Check if there is a telemetry uuid
this->m_uuid = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.uuid", "").get<std::string>();
if(this->m_uuid.empty()) {
m_uuid = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.uuid", "").get<std::string>();
if(m_uuid.empty()) {
// Generate a new uuid
this->m_uuid = wolv::hash::generateUUID();
m_uuid = wolv::hash::generateUUID();
// Save
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.uuid", this->m_uuid);
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.uuid", m_uuid);
}
}
@@ -43,7 +43,7 @@ namespace hex::plugin::builtin {
ImGui::TableNextColumn();
ImGui::TextUnformatted("hex.builtin.welcome.server_contact.data_collected.uuid"_lang);
ImGui::TableNextColumn();
ImGui::TextWrapped("%s", this->m_uuid.c_str());
ImGui::TextWrapped("%s", m_uuid.c_str());
ImGui::TableNextRow();
ImGui::TableNextColumn();

View File

@@ -19,17 +19,17 @@ namespace hex::plugin::builtin {
m_message(std::move(message)), m_function(std::move(function)) { }
void drawContent() override {
ImGuiExt::TextFormattedWrapped("{}", Lang(this->m_message));
ImGuiExt::TextFormattedWrapped("{}", Lang(m_message));
ImGui::NewLine();
ImGui::PushItemWidth(-1);
if (this->m_justOpened) {
if (m_justOpened) {
ImGui::SetKeyboardFocusHere();
this->m_justOpened = false;
m_justOpened = false;
}
ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_KEY, this->m_input);
ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_KEY, m_input);
ImGui::PopItemWidth();
ImGui::NewLine();
@@ -38,7 +38,7 @@ namespace hex::plugin::builtin {
auto width = ImGui::GetWindowWidth();
ImGui::SetCursorPosX(width / 9);
if (ImGui::Button("hex.builtin.common.okay"_lang, ImVec2(width / 3, 0)) || ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Enter))) {
this->m_function(this->m_input);
m_function(m_input);
this->close();
}
ImGui::SameLine();

View File

@@ -17,7 +17,7 @@ namespace hex::plugin::builtin {
m_yesFunction(std::move(yesFunction)), m_noFunction(std::move(noFunction)) { }
void drawContent() override {
ImGuiExt::TextFormattedWrapped("{}", this->m_message.c_str());
ImGuiExt::TextFormattedWrapped("{}", m_message.c_str());
ImGui::NewLine();
if (ImGui::BeginTable("##unsaved_providers", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 4))) {
@@ -35,13 +35,13 @@ namespace hex::plugin::builtin {
auto width = ImGui::GetWindowWidth();
ImGui::SetCursorPosX(width / 9);
if (ImGui::Button("hex.builtin.common.yes"_lang, ImVec2(width / 3, 0))) {
this->m_yesFunction();
m_yesFunction();
this->close();
}
ImGui::SameLine();
ImGui::SetCursorPosX(width / 9 * 5);
if (ImGui::Button("hex.builtin.common.no"_lang, ImVec2(width / 3, 0)) || ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Escape))) {
this->m_noFunction();
m_noFunction();
this->close();
}

View File

@@ -11,7 +11,7 @@ namespace hex::plugin::builtin {
IntelHexProvider() = default;
~IntelHexProvider() override = default;
[[nodiscard]] bool isAvailable() const override { return this->m_dataValid; }
[[nodiscard]] bool isAvailable() const override { return m_dataValid; }
[[nodiscard]] bool isReadable() const override { return true; }
[[nodiscard]] bool isWritable() const override { return false; }
[[nodiscard]] bool isResizable() const override { return false; }

View File

@@ -11,9 +11,9 @@ namespace hex::plugin::builtin {
[[nodiscard]] bool isAvailable() const override { return true; }
[[nodiscard]] bool isReadable() const override { return true; }
[[nodiscard]] bool isWritable() const override { return !this->m_readOnly; }
[[nodiscard]] bool isResizable() const override { return !this->m_readOnly; }
[[nodiscard]] bool isSavable() const override { return this->m_name.empty(); }
[[nodiscard]] bool isWritable() const override { return !m_readOnly; }
[[nodiscard]] bool isResizable() const override { return !m_readOnly; }
[[nodiscard]] bool isSavable() const override { return m_name.empty(); }
[[nodiscard]] bool isSavableAsRecent() const override { return false; }
[[nodiscard]] bool open() override;
@@ -21,7 +21,7 @@ namespace hex::plugin::builtin {
void readRaw(u64 offset, void *buffer, size_t size) override;
void writeRaw(u64 offset, const void *buffer, size_t size) override;
[[nodiscard]] u64 getActualSize() const override { return this->m_data.size(); }
[[nodiscard]] u64 getActualSize() const override { return m_data.size(); }
void resizeRaw(u64 newSize) override;
void insertRaw(u64 offset, u64 size) override;
@@ -43,7 +43,7 @@ namespace hex::plugin::builtin {
void loadSettings(const nlohmann::json &settings) override;
[[nodiscard]] nlohmann::json storeSettings(nlohmann::json settings) const override;
void setReadOnly(bool readOnly) { this->m_readOnly = readOnly; }
void setReadOnly(bool readOnly) { m_readOnly = readOnly; }
private:
void renameFile();

View File

@@ -29,9 +29,9 @@ namespace hex::plugin::builtin {
[[nodiscard]] bool isAvailable() const override {
#ifdef _WIN32
return this->m_processHandle != nullptr;
return m_processHandle != nullptr;
#elif __linux__
return this->m_processId != -1;
return m_processId != -1;
#endif
}
[[nodiscard]] bool isReadable() const override { return true; }
@@ -46,11 +46,11 @@ namespace hex::plugin::builtin {
void save() override {}
[[nodiscard]] std::string getName() const override { return hex::format("hex.builtin.provider.process_memory.name"_lang, this->m_selectedProcess != nullptr ? this->m_selectedProcess->name : ""); }
[[nodiscard]] std::string getName() const override { return hex::format("hex.builtin.provider.process_memory.name"_lang, m_selectedProcess != nullptr ? m_selectedProcess->name : ""); }
[[nodiscard]] std::vector<Description> getDataDescription() const override {
return {
{ "hex.builtin.provider.process_memory.process_name"_lang, this->m_selectedProcess->name },
{ "hex.builtin.provider.process_memory.process_id"_lang, std::to_string(this->m_selectedProcess->id) }
{ "hex.builtin.provider.process_memory.process_name"_lang, m_selectedProcess->name },
{ "hex.builtin.provider.process_memory.process_id"_lang, std::to_string(m_selectedProcess->id) }
};
}

View File

@@ -14,19 +14,19 @@ namespace hex::plugin::builtin::undo {
void undo(prv::Provider *provider) override {
hex::unused(provider);
ImHexApi::Bookmarks::remove(this->m_entry.id);
ImHexApi::Bookmarks::remove(m_entry.id);
}
void redo(prv::Provider *provider) override {
hex::unused(provider);
auto &[region, name, comment, color, locked, id] = this->m_entry;
auto &[region, name, comment, color, locked, id] = m_entry;
id = ImHexApi::Bookmarks::add(region, name, comment, color);
}
[[nodiscard]] std::string format() const override {
return hex::format("Bookmark {} created", this->m_entry.name);
return hex::format("Bookmark {} created", m_entry.name);
}
std::unique_ptr<Operation> clone() const override {
@@ -34,7 +34,7 @@ namespace hex::plugin::builtin::undo {
}
[[nodiscard]] Region getRegion() const override {
return this->m_entry.region;
return m_entry.region;
}
bool shouldHighlight() const override { return false; }

View File

@@ -13,15 +13,15 @@ namespace hex::plugin::builtin::undo {
m_offset(offset), m_size(size) { }
void undo(prv::Provider *provider) override {
provider->removeRaw(this->m_offset, this->m_size);
provider->removeRaw(m_offset, m_size);
}
void redo(prv::Provider *provider) override {
provider->insertRaw(this->m_offset, this->m_size);
provider->insertRaw(m_offset, m_size);
}
[[nodiscard]] std::string format() const override {
return hex::format("hex.builtin.undo_operation.insert"_lang, hex::toByteString(this->m_size), this->m_offset);
return hex::format("hex.builtin.undo_operation.insert"_lang, hex::toByteString(m_size), m_offset);
}
std::unique_ptr<Operation> clone() const override {
@@ -29,7 +29,7 @@ namespace hex::plugin::builtin::undo {
}
[[nodiscard]] Region getRegion() const override {
return { this->m_offset, this->m_size };
return { m_offset, m_size };
}
private:

View File

@@ -13,20 +13,20 @@ namespace hex::plugin::builtin::undo {
m_offset(offset), m_size(size) { }
void undo(prv::Provider *provider) override {
provider->insertRaw(this->m_offset, this->m_size);
provider->insertRaw(m_offset, m_size);
provider->writeRaw(this->m_offset, this->m_removedData.data(), this->m_removedData.size());
provider->writeRaw(m_offset, m_removedData.data(), m_removedData.size());
}
void redo(prv::Provider *provider) override {
this->m_removedData.resize(this->m_size);
provider->readRaw(this->m_offset, this->m_removedData.data(), this->m_removedData.size());
m_removedData.resize(m_size);
provider->readRaw(m_offset, m_removedData.data(), m_removedData.size());
provider->removeRaw(this->m_offset, this->m_size);
provider->removeRaw(m_offset, m_size);
}
[[nodiscard]] std::string format() const override {
return hex::format("hex.builtin.undo_operation.remove"_lang, hex::toByteString(this->m_size), this->m_offset);
return hex::format("hex.builtin.undo_operation.remove"_lang, hex::toByteString(m_size), m_offset);
}
std::unique_ptr<Operation> clone() const override {
@@ -34,7 +34,7 @@ namespace hex::plugin::builtin::undo {
}
[[nodiscard]] Region getRegion() const override {
return { this->m_offset, this->m_size };
return { m_offset, m_size };
}
bool shouldHighlight() const override { return false; }

View File

@@ -16,20 +16,20 @@ namespace hex::plugin::builtin::undo {
m_newData(newData, newData + size) { }
void undo(prv::Provider *provider) override {
provider->writeRaw(this->m_offset, this->m_oldData.data(), this->m_oldData.size());
provider->writeRaw(m_offset, m_oldData.data(), m_oldData.size());
}
void redo(prv::Provider *provider) override {
provider->writeRaw(this->m_offset, this->m_newData.data(), this->m_newData.size());
provider->writeRaw(m_offset, m_newData.data(), m_newData.size());
}
[[nodiscard]] std::string format() const override {
return hex::format("hex.builtin.undo_operation.write"_lang, hex::toByteString(this->m_newData.size()), this->m_offset);
return hex::format("hex.builtin.undo_operation.write"_lang, hex::toByteString(m_newData.size()), m_offset);
}
std::vector<std::string> formatContent() const override {
return {
hex::format("{} {} {}", hex::crypt::encode16(this->m_oldData), ICON_VS_ARROW_RIGHT, hex::crypt::encode16(this->m_newData)),
hex::format("{} {} {}", hex::crypt::encode16(m_oldData), ICON_VS_ARROW_RIGHT, hex::crypt::encode16(m_newData)),
};
}
@@ -38,7 +38,7 @@ namespace hex::plugin::builtin::undo {
}
[[nodiscard]] Region getRegion() const override {
return { this->m_offset, this->m_oldData.size() };
return { m_offset, m_oldData.size() };
}
private:

View File

@@ -11,7 +11,7 @@ namespace hex::plugin::builtin {
public:
explicit ViewProvider() {
EventProviderClosing::subscribe(this, [this](const prv::Provider *provider, bool*) {
if (this->m_provider == provider)
if (m_provider == provider)
ImHexApi::Provider::remove(this, false);
});
}
@@ -20,85 +20,85 @@ namespace hex::plugin::builtin {
}
[[nodiscard]] bool isAvailable() const override {
if (this->m_provider == nullptr)
if (m_provider == nullptr)
return false;
else
return this->m_provider->isAvailable();
return m_provider->isAvailable();
}
[[nodiscard]] bool isReadable() const override {
if (this->m_provider == nullptr)
if (m_provider == nullptr)
return false;
else
return this->m_provider->isReadable();
return m_provider->isReadable();
}
[[nodiscard]] bool isWritable() const override {
if (this->m_provider == nullptr)
if (m_provider == nullptr)
return false;
else
return this->m_provider->isWritable();
return m_provider->isWritable();
}
[[nodiscard]] bool isResizable() const override { return true; }
[[nodiscard]] bool isSavable() const override {
if (this->m_provider == nullptr)
if (m_provider == nullptr)
return false;
else
return this->m_provider->isSavable();
return m_provider->isSavable();
}
void save() override {
this->m_provider->save();
m_provider->save();
}
[[nodiscard]] bool open() override { return true; }
void close() override { }
void resizeRaw(u64 newSize) override {
this->m_size = newSize;
m_size = newSize;
}
void insertRaw(u64 offset, u64 size) override {
if (this->m_provider == nullptr)
if (m_provider == nullptr)
return;
this->m_size += size;
this->m_provider->insert(offset + this->m_startAddress, size);
m_size += size;
m_provider->insert(offset + m_startAddress, size);
}
void removeRaw(u64 offset, u64 size) override {
if (this->m_provider == nullptr)
if (m_provider == nullptr)
return;
this->m_size -= size;
this->m_provider->remove(offset + this->m_startAddress, size);
m_size -= size;
m_provider->remove(offset + m_startAddress, size);
}
void readRaw(u64 offset, void *buffer, size_t size) override {
if (this->m_provider == nullptr)
if (m_provider == nullptr)
return;
this->m_provider->read(offset + this->m_startAddress, buffer, size);
m_provider->read(offset + m_startAddress, buffer, size);
}
void writeRaw(u64 offset, const void *buffer, size_t size) override {
if (this->m_provider == nullptr)
if (m_provider == nullptr)
return;
this->m_provider->write(offset + this->m_startAddress, buffer, size);
m_provider->write(offset + m_startAddress, buffer, size);
}
[[nodiscard]] u64 getActualSize() const override { return this->m_size; }
[[nodiscard]] u64 getActualSize() const override { return m_size; }
[[nodiscard]] std::string getName() const override {
if (this->m_provider == nullptr)
if (m_provider == nullptr)
return "View";
else
return hex::format("{} View", this->m_provider->getName());
return hex::format("{} View", m_provider->getName());
}
[[nodiscard]] std::vector<Description> getDataDescription() const override {
if (this->m_provider == nullptr)
if (m_provider == nullptr)
return { };
return this->m_provider->getDataDescription();
return m_provider->getDataDescription();
}
void loadSettings(const nlohmann::json &settings) override { hex::unused(settings); }
@@ -109,9 +109,9 @@ namespace hex::plugin::builtin {
}
void setProvider(u64 startAddress, size_t size, hex::prv::Provider *provider) {
this->m_startAddress = startAddress;
this->m_size = size;
this->m_provider = provider;
m_startAddress = startAddress;
m_size = size;
m_provider = provider;
}
[[nodiscard]] std::pair<Region, bool> getRegionValidity(u64 address) const override {

View File

@@ -48,7 +48,7 @@ namespace hex::plugin::builtin {
std::string m_exactResult;
void focusInputTextBox() {
this->m_focusInputTextBox = true;
m_focusInputTextBox = true;
}
std::vector<CommandResult> getCommandResults(const std::string &input);

View File

@@ -51,7 +51,7 @@ namespace hex::plugin::builtin {
void reloadCustomNodes();
std::vector<Workspace*> &getWorkspaceStack() { return *this->m_workspaceStack; }
std::vector<Workspace*> &getWorkspaceStack() { return *m_workspaceStack; }
private:
void drawContextMenus(ViewDataProcessor::Workspace &workspace);

View File

@@ -23,42 +23,42 @@ namespace hex::plugin::builtin {
};
[[nodiscard]] bool isAnyPopupOpen() const {
return this->m_currPopup != nullptr;
return m_currPopup != nullptr;
}
template<std::derived_from<Popup> T>
[[nodiscard]] bool isPopupOpen() const {
return dynamic_cast<T*>(this->m_currPopup.get()) != nullptr;
return dynamic_cast<T*>(m_currPopup.get()) != nullptr;
}
template<std::derived_from<Popup> T, typename ... Args>
void openPopup(Args && ...args) {
this->m_currPopup = std::make_unique<T>(std::forward<Args>(args)...);
this->m_shouldOpenPopup = true;
m_currPopup = std::make_unique<T>(std::forward<Args>(args)...);
m_shouldOpenPopup = true;
}
void closePopup() {
this->m_currPopup.reset();
m_currPopup.reset();
}
bool isSelectionValid() const {
return this->m_hexEditor.isSelectionValid();
return m_hexEditor.isSelectionValid();
}
Region getSelection() const {
return this->m_hexEditor.getSelection();
return m_hexEditor.getSelection();
}
void setSelection(const Region &region) {
this->m_hexEditor.setSelection(region);
m_hexEditor.setSelection(region);
}
void setSelection(u128 start, u128 end) {
this->m_hexEditor.setSelection(start, end);
m_hexEditor.setSelection(start, end);
}
void jumpToSelection() {
this->m_hexEditor.jumpToSelection();
m_hexEditor.jumpToSelection();
}
private:

View File

@@ -52,20 +52,20 @@ namespace hex::plugin::builtin {
ImGuiExt::TextFormattedWrapped("{}", static_cast<const char *>("hex.builtin.view.pattern_editor.accept_pattern.desc"_lang));
std::vector<std::string> entries;
entries.resize(this->m_view->m_possiblePatternFiles.get(provider).size());
entries.resize(m_view->m_possiblePatternFiles.get(provider).size());
for (u32 i = 0; i < entries.size(); i++) {
entries[i] = wolv::util::toUTF8String(this->m_view->m_possiblePatternFiles.get(provider)[i].filename());
entries[i] = wolv::util::toUTF8String(m_view->m_possiblePatternFiles.get(provider)[i].filename());
}
if (ImGui::BeginListBox("##patterns_accept", ImVec2(-FLT_MIN, 0))) {
u32 index = 0;
for (auto &path : this->m_view->m_possiblePatternFiles.get(provider)) {
if (ImGui::Selectable(wolv::util::toUTF8String(path.filename()).c_str(), index == this->m_selectedPatternFile, ImGuiSelectableFlags_DontClosePopups))
this->m_selectedPatternFile = index;
for (auto &path : m_view->m_possiblePatternFiles.get(provider)) {
if (ImGui::Selectable(wolv::util::toUTF8String(path.filename()).c_str(), index == m_selectedPatternFile, ImGuiSelectableFlags_DontClosePopups))
m_selectedPatternFile = index;
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0))
this->m_view->loadPatternFile(this->m_view->m_possiblePatternFiles.get(provider)[this->m_selectedPatternFile], provider);
m_view->loadPatternFile(m_view->m_possiblePatternFiles.get(provider)[m_selectedPatternFile], provider);
ImGuiExt::InfoTooltip(wolv::util::toUTF8String(path).c_str());
@@ -84,7 +84,7 @@ namespace hex::plugin::builtin {
ImGuiExt::ConfirmButtons("hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang,
[this, provider] {
this->m_view->loadPatternFile(this->m_view->m_possiblePatternFiles.get(provider)[this->m_selectedPatternFile], provider);
m_view->loadPatternFile(m_view->m_possiblePatternFiles.get(provider)[m_selectedPatternFile], provider);
this->close();
},
[this] {

View File

@@ -18,10 +18,10 @@ namespace hex::plugin::builtin::ui {
void draw(float height = ImGui::GetContentRegionAvail().y);
void setProvider(prv::Provider *provider) {
this->m_provider = provider;
this->m_currValidRegion = { Region::Invalid(), false };
m_provider = provider;
m_currValidRegion = { Region::Invalid(), false };
}
void setUnknownDataCharacter(char character) { this->m_unknownDataCharacter = character; }
void setUnknownDataCharacter(char character) { m_unknownDataCharacter = character; }
private:
enum class CellType { None, Hex, ASCII };
@@ -36,36 +36,36 @@ namespace hex::plugin::builtin::ui {
public:
void setSelectionUnchecked(std::optional<u64> start, std::optional<u64> end) {
this->m_selectionStart = start;
this->m_selectionEnd = end;
this->m_cursorPosition = end;
m_selectionStart = start;
m_selectionEnd = end;
m_cursorPosition = end;
}
void setSelection(const Region &region) { this->setSelection(region.getStartAddress(), region.getEndAddress()); }
void setSelection(u128 start, u128 end) {
if (!ImHexApi::Provider::isValid())
return;
if (start > this->m_provider->getBaseAddress() + this->m_provider->getActualSize())
if (start > m_provider->getBaseAddress() + m_provider->getActualSize())
return;
if (start < this->m_provider->getBaseAddress())
if (start < m_provider->getBaseAddress())
return;
if (this->m_provider->getActualSize() == 0)
if (m_provider->getActualSize() == 0)
return;
const size_t maxAddress = this->m_provider->getActualSize() + this->m_provider->getBaseAddress() - 1;
const size_t maxAddress = m_provider->getActualSize() + m_provider->getBaseAddress() - 1;
constexpr static auto alignDown = [](u128 value, u128 alignment) {
return value & ~(alignment - 1);
};
this->m_selectionChanged = this->m_selectionStart != start || this->m_selectionEnd != end;
m_selectionChanged = m_selectionStart != start || m_selectionEnd != end;
if (!this->m_selectionStart.has_value()) this->m_selectionStart = start;
if (!this->m_selectionEnd.has_value()) this->m_selectionEnd = end;
if (!m_selectionStart.has_value()) m_selectionStart = start;
if (!m_selectionEnd.has_value()) m_selectionEnd = end;
if (auto bytesPerCell = this->m_currDataVisualizer->getBytesPerCell(); bytesPerCell > 1) {
if (auto bytesPerCell = m_currDataVisualizer->getBytesPerCell(); bytesPerCell > 1) {
if (end > start) {
start = alignDown(start, bytesPerCell);
end = alignDown(end, bytesPerCell) + (bytesPerCell - 1);
@@ -75,14 +75,14 @@ namespace hex::plugin::builtin::ui {
}
}
this->m_selectionStart = std::clamp<u128>(start, 0, maxAddress);
this->m_selectionEnd = std::clamp<u128>(end, 0, maxAddress);
this->m_cursorPosition = this->m_selectionEnd;
m_selectionStart = std::clamp<u128>(start, 0, maxAddress);
m_selectionEnd = std::clamp<u128>(end, 0, maxAddress);
m_cursorPosition = m_selectionEnd;
if (this->m_selectionChanged) {
if (m_selectionChanged) {
auto selection = this->getSelection();
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion{ { selection.address, selection.size }, this->m_provider });
this->m_shouldModifyValue = true;
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion{ { selection.address, selection.size }, m_provider });
m_shouldModifyValue = true;
}
}
@@ -90,138 +90,138 @@ namespace hex::plugin::builtin::ui {
if (!isSelectionValid())
return Region::Invalid();
const auto start = std::min(this->m_selectionStart.value(), this->m_selectionEnd.value());
const auto end = std::max(this->m_selectionStart.value(), this->m_selectionEnd.value());
const auto start = std::min(m_selectionStart.value(), m_selectionEnd.value());
const auto end = std::max(m_selectionStart.value(), m_selectionEnd.value());
const size_t size = end - start + 1;
return { start, size };
}
[[nodiscard]] std::optional<u64> getCursorPosition() const {
return this->m_cursorPosition;
return m_cursorPosition;
}
void setCursorPosition(u64 cursorPosition) {
this->m_cursorPosition = cursorPosition;
m_cursorPosition = cursorPosition;
}
[[nodiscard]] bool isSelectionValid() const {
return this->m_selectionStart.has_value() && this->m_selectionEnd.has_value();
return m_selectionStart.has_value() && m_selectionEnd.has_value();
}
void jumpToSelection(bool center = true) {
this->m_shouldJumpToSelection = true;
m_shouldJumpToSelection = true;
if (center)
this->m_centerOnJump = true;
m_centerOnJump = true;
}
void scrollToSelection() {
this->m_shouldScrollToSelection = true;
m_shouldScrollToSelection = true;
}
void jumpIfOffScreen() {
this->m_shouldJumpWhenOffScreen = true;
m_shouldJumpWhenOffScreen = true;
}
[[nodiscard]] u16 getBytesPerRow() const {
return this->m_bytesPerRow;
return m_bytesPerRow;
}
[[nodiscard]] u16 getBytesPerCell() const {
return this->m_currDataVisualizer->getBytesPerCell();
return m_currDataVisualizer->getBytesPerCell();
}
void setBytesPerRow(u16 bytesPerRow) {
this->m_bytesPerRow = bytesPerRow;
m_bytesPerRow = bytesPerRow;
}
[[nodiscard]] u16 getVisibleRowCount() const {
return this->m_visibleRowCount;
return m_visibleRowCount;
}
void setSelectionColor(color_t color) {
this->m_selectionColor = color;
m_selectionColor = color;
}
void enableUpperCaseHex(bool upperCaseHex) {
this->m_upperCaseHex = upperCaseHex;
m_upperCaseHex = upperCaseHex;
}
void enableGrayOutZeros(bool grayOutZeros) {
this->m_grayOutZero = grayOutZeros;
m_grayOutZero = grayOutZeros;
}
void enableShowAscii(bool showAscii) {
this->m_showAscii = showAscii;
m_showAscii = showAscii;
}
void enableShowHumanReadableUnits(bool showHumanReadableUnits) {
this->m_showHumanReadableUnits = showHumanReadableUnits;
m_showHumanReadableUnits = showHumanReadableUnits;
}
void enableSyncScrolling(bool syncScrolling) {
this->m_syncScrolling = syncScrolling;
m_syncScrolling = syncScrolling;
}
void setByteCellPadding(u32 byteCellPadding) {
this->m_byteCellPadding = byteCellPadding;
m_byteCellPadding = byteCellPadding;
}
void setCharacterCellPadding(u32 characterCellPadding) {
this->m_characterCellPadding = characterCellPadding;
m_characterCellPadding = characterCellPadding;
}
[[nodiscard]] const std::optional<EncodingFile>& getCustomEncoding() const {
return this->m_currCustomEncoding;
return m_currCustomEncoding;
}
void setCustomEncoding(const EncodingFile &encoding) {
this->m_currCustomEncoding = encoding;
this->m_encodingLineStartAddresses.clear();
m_currCustomEncoding = encoding;
m_encodingLineStartAddresses.clear();
}
void setCustomEncoding(EncodingFile &&encoding) {
this->m_currCustomEncoding = std::move(encoding);
this->m_encodingLineStartAddresses.clear();
m_currCustomEncoding = std::move(encoding);
m_encodingLineStartAddresses.clear();
}
void forceUpdateScrollPosition() {
this->m_shouldUpdateScrollPosition = true;
m_shouldUpdateScrollPosition = true;
}
void setForegroundHighlightCallback(const std::function<std::optional<color_t>(u64, const u8 *, size_t)> &callback) {
this->m_foregroundColorCallback = callback;
m_foregroundColorCallback = callback;
}
void setBackgroundHighlightCallback(const std::function<std::optional<color_t>(u64, const u8 *, size_t)> &callback) {
this->m_backgroundColorCallback = callback;
m_backgroundColorCallback = callback;
}
void setTooltipCallback(const std::function<void(u64, const u8 *, size_t)> &callback) {
this->m_tooltipCallback = callback;
m_tooltipCallback = callback;
}
[[nodiscard]] float getScrollPosition() const {
return this->m_scrollPosition;
return m_scrollPosition;
}
void setScrollPosition(float scrollPosition) {
this->m_scrollPosition = scrollPosition;
m_scrollPosition = scrollPosition;
}
void setEditingAddress(u64 address) {
this->m_editingAddress = address;
this->m_shouldModifyValue = false;
this->m_enteredEditingMode = true;
m_editingAddress = address;
m_shouldModifyValue = false;
m_enteredEditingMode = true;
this->m_editingBytes.resize(this->m_currDataVisualizer->getBytesPerCell());
this->m_provider->read(address + this->m_provider->getBaseAddress(), this->m_editingBytes.data(), this->m_editingBytes.size());
this->m_editingCellType = CellType::Hex;
m_editingBytes.resize(m_currDataVisualizer->getBytesPerCell());
m_provider->read(address + m_provider->getBaseAddress(), m_editingBytes.data(), m_editingBytes.size());
m_editingCellType = CellType::Hex;
}
void clearEditingAddress() {
this->m_editingAddress = std::nullopt;
m_editingAddress = std::nullopt;
}
private:

View File

@@ -17,7 +17,7 @@ namespace hex::plugin::builtin::ui {
class PatternDrawer : public pl::PatternVisitor {
public:
PatternDrawer() {
this->m_formatters = pl::gen::fmt::createFormatters();
m_formatters = pl::gen::fmt::createFormatters();
}
virtual ~PatternDrawer() = default;
@@ -30,9 +30,9 @@ namespace hex::plugin::builtin::ui {
Flattened = 2
};
void setTreeStyle(TreeStyle style) { this->m_treeStyle = style; }
void setSelectionCallback(std::function<void(Region)> callback) { this->m_selectionCallback = std::move(callback); }
void enableRowColoring(bool enabled) { this->m_rowColoring = enabled; }
void setTreeStyle(TreeStyle style) { m_treeStyle = style; }
void setSelectionCallback(std::function<void(Region)> callback) { m_selectionCallback = std::move(callback); }
void enableRowColoring(bool enabled) { m_rowColoring = enabled; }
void reset();
private:

View File

@@ -180,12 +180,12 @@ namespace hex::plugin::builtin {
}
unitString = wolv::util::trim(unitString);
this->m_unitString = unitString;
m_unitString = unitString;
if (unitString.empty()) {
if (multiplier == 1)
return { Unit::Unitless, 1 };
else {
this->m_unitString = unitStringCopy;
m_unitString = unitStringCopy;
return { Unit::Unitless, 1 };
}

View File

@@ -29,27 +29,27 @@ namespace hex::plugin::builtin {
constexpr static int StepSize = 1, FastStepSize = 10;
ImGui::PushItemWidth(100_scaled);
ImGui::InputScalar("hex.builtin.nodes.constants.buffer.size"_lang, ImGuiDataType_U32, &this->m_size, &StepSize, &FastStepSize);
ImGui::InputScalar("hex.builtin.nodes.constants.buffer.size"_lang, ImGuiDataType_U32, &m_size, &StepSize, &FastStepSize);
ImGui::PopItemWidth();
}
void process() override {
if (this->m_buffer.size() != this->m_size)
this->m_buffer.resize(this->m_size, 0x00);
if (m_buffer.size() != m_size)
m_buffer.resize(m_size, 0x00);
this->setBufferOnOutput(0, this->m_buffer);
this->setBufferOnOutput(0, m_buffer);
}
void store(nlohmann::json &j) const override {
j = nlohmann::json::object();
j["size"] = this->m_size;
j["data"] = this->m_buffer;
j["size"] = m_size;
j["data"] = m_buffer;
}
void load(const nlohmann::json &j) override {
this->m_size = j.at("size");
this->m_buffer = j.at("data").get<std::vector<u8>>();
m_size = j.at("size");
m_buffer = j.at("data").get<std::vector<u8>>();
}
private:
@@ -64,21 +64,21 @@ namespace hex::plugin::builtin {
}
void drawNode() override {
ImGui::InputTextMultiline("##string", this->m_value, ImVec2(150_scaled, 0), ImGuiInputTextFlags_AllowTabInput);
ImGui::InputTextMultiline("##string", m_value, ImVec2(150_scaled, 0), ImGuiInputTextFlags_AllowTabInput);
}
void process() override {
this->setBufferOnOutput(0, hex::decodeByteString(this->m_value));
this->setBufferOnOutput(0, hex::decodeByteString(m_value));
}
void store(nlohmann::json &j) const override {
j = nlohmann::json::object();
j["data"] = this->m_value;
j["data"] = m_value;
}
void load(const nlohmann::json &j) override {
this->m_value = j.at("data").get<std::string>();
m_value = j.at("data").get<std::string>();
}
private:
@@ -91,22 +91,22 @@ namespace hex::plugin::builtin {
void drawNode() override {
ImGui::PushItemWidth(100_scaled);
ImGuiExt::InputHexadecimal("##integer_value", &this->m_value);
ImGuiExt::InputHexadecimal("##integer_value", &m_value);
ImGui::PopItemWidth();
}
void process() override {
this->setIntegerOnOutput(0, this->m_value);
this->setIntegerOnOutput(0, m_value);
}
void store(nlohmann::json &j) const override {
j = nlohmann::json::object();
j["data"] = this->m_value;
j["data"] = m_value;
}
void load(const nlohmann::json &j) override {
this->m_value = j.at("data");
m_value = j.at("data");
}
private:
@@ -119,22 +119,22 @@ namespace hex::plugin::builtin {
void drawNode() override {
ImGui::PushItemWidth(100_scaled);
ImGui::InputScalar("##floatValue", ImGuiDataType_Float, &this->m_value, nullptr, nullptr, "%f", ImGuiInputTextFlags_CharsDecimal);
ImGui::InputScalar("##floatValue", ImGuiDataType_Float, &m_value, nullptr, nullptr, "%f", ImGuiInputTextFlags_CharsDecimal);
ImGui::PopItemWidth();
}
void process() override {
this->setFloatOnOutput(0, this->m_value);
this->setFloatOnOutput(0, m_value);
}
void store(nlohmann::json &j) const override {
j = nlohmann::json::object();
j["data"] = this->m_value;
j["data"] = m_value;
}
void load(const nlohmann::json &j) override {
this->m_value = j.at("data");
m_value = j.at("data");
}
private:
@@ -151,30 +151,30 @@ namespace hex::plugin::builtin {
void drawNode() override {
ImGui::PushItemWidth(200_scaled);
ImGui::ColorPicker4("##colorPicker", &this->m_color.Value.x, ImGuiColorEditFlags_AlphaBar);
ImGui::ColorPicker4("##colorPicker", &m_color.Value.x, ImGuiColorEditFlags_AlphaBar);
ImGui::PopItemWidth();
}
void process() override {
this->setBufferOnOutput(0, wolv::util::toBytes<u8>(u8(this->m_color.Value.x * 0xFF)));
this->setBufferOnOutput(1, wolv::util::toBytes<u8>(u8(this->m_color.Value.y * 0xFF)));
this->setBufferOnOutput(2, wolv::util::toBytes<u8>(u8(this->m_color.Value.z * 0xFF)));
this->setBufferOnOutput(3, wolv::util::toBytes<u8>(u8(this->m_color.Value.w * 0xFF)));
this->setBufferOnOutput(0, wolv::util::toBytes<u8>(u8(m_color.Value.x * 0xFF)));
this->setBufferOnOutput(1, wolv::util::toBytes<u8>(u8(m_color.Value.y * 0xFF)));
this->setBufferOnOutput(2, wolv::util::toBytes<u8>(u8(m_color.Value.z * 0xFF)));
this->setBufferOnOutput(3, wolv::util::toBytes<u8>(u8(m_color.Value.w * 0xFF)));
}
void store(nlohmann::json &j) const override {
j = nlohmann::json::object();
j["data"] = nlohmann::json::object();
j["data"]["r"] = this->m_color.Value.x;
j["data"]["g"] = this->m_color.Value.y;
j["data"]["b"] = this->m_color.Value.z;
j["data"]["a"] = this->m_color.Value.w;
j["data"]["r"] = m_color.Value.x;
j["data"]["g"] = m_color.Value.y;
j["data"]["b"] = m_color.Value.z;
j["data"]["a"] = m_color.Value.w;
}
void load(const nlohmann::json &j) override {
const auto &color = j.at("data");
this->m_color = ImVec4(color.at("r"), color.at("g"), color.at("b"), color.at("a"));
m_color = ImVec4(color.at("r"), color.at("g"), color.at("b"), color.at("a"));
}
private:
@@ -188,7 +188,7 @@ namespace hex::plugin::builtin {
}
void drawNode() override {
ImGui::InputTextMultiline("##string", this->m_comment, scaled(ImVec2(150, 100)));
ImGui::InputTextMultiline("##string", m_comment, scaled(ImVec2(150, 100)));
}
void process() override {
@@ -197,11 +197,11 @@ namespace hex::plugin::builtin {
void store(nlohmann::json &j) const override {
j = nlohmann::json::object();
j["comment"] = this->m_comment;
j["comment"] = m_comment;
}
void load(const nlohmann::json &j) override {
this->m_comment = j["comment"].get<std::string>();
m_comment = j["comment"].get<std::string>();
}
private:

View File

@@ -19,8 +19,8 @@ namespace hex::plugin::builtin {
void drawNode() override {
ImGui::PushItemWidth(100_scaled);
ImGui::Combo("hex.builtin.nodes.crypto.aes.mode"_lang, &this->m_mode, "ECB\0CBC\0CFB128\0CTR\0GCM\0CCM\0OFB\0");
ImGui::Combo("hex.builtin.nodes.crypto.aes.key_length"_lang, &this->m_keyLength, "128 Bits\000192 Bits\000256 Bits\000");
ImGui::Combo("hex.builtin.nodes.crypto.aes.mode"_lang, &m_mode, "ECB\0CBC\0CFB128\0CTR\0GCM\0CCM\0OFB\0");
ImGui::Combo("hex.builtin.nodes.crypto.aes.key_length"_lang, &m_keyLength, "128 Bits\000192 Bits\000256 Bits\000");
ImGui::PopItemWidth();
}
@@ -41,7 +41,7 @@ namespace hex::plugin::builtin {
std::copy(iv.begin(), iv.end(), ivData.begin());
std::copy(nonce.begin(), nonce.end(), nonceData.begin());
auto output = crypt::aesDecrypt(static_cast<crypt::AESMode>(this->m_mode), static_cast<crypt::KeyLength>(this->m_keyLength), key, nonceData, ivData, input);
auto output = crypt::aesDecrypt(static_cast<crypt::AESMode>(m_mode), static_cast<crypt::KeyLength>(m_keyLength), key, nonceData, ivData, input);
this->setBufferOnOutput(4, output);
}
@@ -50,13 +50,13 @@ namespace hex::plugin::builtin {
j = nlohmann::json::object();
j["data"] = nlohmann::json::object();
j["data"]["mode"] = this->m_mode;
j["data"]["key_length"] = this->m_keyLength;
j["data"]["mode"] = m_mode;
j["data"]["key_length"] = m_keyLength;
}
void load(const nlohmann::json &j) override {
this->m_mode = j["data"]["mode"];
this->m_keyLength = j["data"]["key_length"];
m_mode = j["data"]["mode"];
m_keyLength = j["data"]["key_length"];
}
private:

View File

@@ -61,8 +61,8 @@ namespace hex::plugin::builtin {
public:
NodeDataSelection() : Node("hex.builtin.nodes.data_access.selection.header", { dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.data_access.selection.address"), dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Integer, "hex.builtin.nodes.data_access.selection.size") }) {
EventRegionSelected::subscribe(this, [this](const auto &region) {
this->m_address = region.address;
this->m_size = region.size;
m_address = region.address;
m_size = region.size;
});
}
@@ -71,8 +71,8 @@ namespace hex::plugin::builtin {
}
void process() override {
this->setIntegerOnOutput(0, this->m_address);
this->setIntegerOnOutput(1, this->m_size);
this->setIntegerOnOutput(0, m_address);
this->setIntegerOnOutput(1, m_size);
}
private:
@@ -232,17 +232,17 @@ namespace hex::plugin::builtin {
NodeVisualizerDigram() : Node("hex.builtin.nodes.visualizer.digram.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input") }) { }
void drawNode() override {
this->m_digram.draw(scaled({ 200, 200 }));
m_digram.draw(scaled({ 200, 200 }));
if (ImGui::IsItemHovered() && ImGui::IsKeyDown(ImGuiKey_LeftShift)) {
ImGui::BeginTooltip();
this->m_digram.draw(scaled({ 600, 600 }));
m_digram.draw(scaled({ 600, 600 }));
ImGui::EndTooltip();
}
}
void process() override {
this->m_digram.process(this->getBufferOnInput(0));
m_digram.process(this->getBufferOnInput(0));
}
private:
@@ -254,16 +254,16 @@ namespace hex::plugin::builtin {
NodeVisualizerLayeredDistribution() : Node("hex.builtin.nodes.visualizer.layered_dist.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input") }) { }
void drawNode() override {
this->m_layeredDistribution.draw(scaled({ 200, 200 }));
m_layeredDistribution.draw(scaled({ 200, 200 }));
if (ImGui::IsItemHovered() && ImGui::IsKeyDown(ImGuiKey_LeftShift)) {
ImGui::BeginTooltip();
this->m_layeredDistribution.draw(scaled({ 600, 600 }));
m_layeredDistribution.draw(scaled({ 600, 600 }));
ImGui::EndTooltip();
}
}
void process() override {
this->m_layeredDistribution.process(this->getBufferOnInput(0));
m_layeredDistribution.process(this->getBufferOnInput(0));
}
private:
@@ -275,10 +275,10 @@ namespace hex::plugin::builtin {
NodeVisualizerImage() : Node("hex.builtin.nodes.visualizer.image.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input") }) { }
void drawNode() override {
ImGui::Image(this->m_texture, scaled(ImVec2(this->m_texture.getAspectRatio() * 200, 200)));
ImGui::Image(m_texture, scaled(ImVec2(m_texture.getAspectRatio() * 200, 200)));
if (ImGui::IsItemHovered() && ImGui::IsKeyDown(ImGuiKey_LeftShift)) {
ImGui::BeginTooltip();
ImGui::Image(this->m_texture, scaled(ImVec2(this->m_texture.getAspectRatio() * 600, 600)));
ImGui::Image(m_texture, scaled(ImVec2(m_texture.getAspectRatio() * 600, 600)));
ImGui::EndTooltip();
}
}
@@ -286,7 +286,7 @@ namespace hex::plugin::builtin {
void process() override {
const auto &rawData = this->getBufferOnInput(0);
this->m_texture = ImGuiExt::Texture(rawData.data(), rawData.size(), ImGuiExt::Texture::Filter::Nearest);
m_texture = ImGuiExt::Texture(rawData.data(), rawData.size(), ImGuiExt::Texture::Filter::Nearest);
}
private:
@@ -298,16 +298,16 @@ namespace hex::plugin::builtin {
NodeVisualizerImageRGBA() : Node("hex.builtin.nodes.visualizer.image_rgba.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input"), dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.common.width"), dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Integer, "hex.builtin.nodes.common.height") }) { }
void drawNode() override {
ImGui::Image(this->m_texture, scaled(ImVec2(this->m_texture.getAspectRatio() * 200, 200)));
ImGui::Image(m_texture, scaled(ImVec2(m_texture.getAspectRatio() * 200, 200)));
if (ImGui::IsItemHovered() && ImGui::IsKeyDown(ImGuiKey_LeftShift)) {
ImGui::BeginTooltip();
ImGui::Image(this->m_texture, scaled(ImVec2(this->m_texture.getAspectRatio() * 600, 600)));
ImGui::Image(m_texture, scaled(ImVec2(m_texture.getAspectRatio() * 600, 600)));
ImGui::EndTooltip();
}
}
void process() override {
this->m_texture = { };
m_texture = { };
const auto &rawData = this->getBufferOnInput(0);
const auto &width = this->getIntegerOnInput(1);
@@ -317,7 +317,7 @@ namespace hex::plugin::builtin {
if (requiredBytes > rawData.size())
throwNodeError(hex::format("Image requires at least {} bytes of data, but only {} bytes are available", requiredBytes, rawData.size()));
this->m_texture = ImGuiExt::Texture(rawData.data(), rawData.size(), ImGuiExt::Texture::Filter::Nearest, width, height);
m_texture = ImGuiExt::Texture(rawData.data(), rawData.size(), ImGuiExt::Texture::Filter::Nearest, width, height);
}
private:
@@ -342,7 +342,7 @@ namespace hex::plugin::builtin {
if (ImPlot::BeginPlot("##distribution", viewSize, ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect)) {
ImPlot::SetupAxes("Address", "Count", ImPlotAxisFlags_Lock, ImPlotAxisFlags_Lock);
ImPlot::SetupAxisScale(ImAxis_Y1, ImPlotScale_Log10);
ImPlot::SetupAxesLimits(0, 256, 1, double(*std::max_element(this->m_counts.begin(), this->m_counts.end())) * 1.1F, ImGuiCond_Always);
ImPlot::SetupAxesLimits(0, 256, 1, double(*std::max_element(m_counts.begin(), m_counts.end())) * 1.1F, ImGuiCond_Always);
static auto x = [] {
std::array<ImU64, 256> result { 0 };
@@ -351,7 +351,7 @@ namespace hex::plugin::builtin {
}();
ImPlot::PlotBars<ImU64>("##bytes", x.data(), this->m_counts.data(), x.size(), 1);
ImPlot::PlotBars<ImU64>("##bytes", x.data(), m_counts.data(), x.size(), 1);
ImPlot::EndPlot();
}
@@ -360,9 +360,9 @@ namespace hex::plugin::builtin {
void process() override {
const auto &buffer = this->getBufferOnInput(0);
this->m_counts.fill(0x00);
m_counts.fill(0x00);
for (const auto &byte : buffer) {
this->m_counts[byte]++;
m_counts[byte]++;
}
}
@@ -377,7 +377,7 @@ namespace hex::plugin::builtin {
void drawNode() override {
ImGui::PushItemWidth(100_scaled);
ImGui::InputText("##name", this->m_name);
ImGui::InputText("##name", m_name);
ImGui::PopItemWidth();
}
@@ -387,7 +387,7 @@ namespace hex::plugin::builtin {
const auto &outVars = runtime.getOutVariables();
if (outVars.contains(this->m_name)) {
if (outVars.contains(m_name)) {
std::visit(wolv::util::overloaded {
[](const std::string &) {},
[](pl::ptrn::Pattern *) {},
@@ -397,20 +397,20 @@ namespace hex::plugin::builtin {
this->setBufferOnOutput(0, buffer);
}
}, outVars.at(this->m_name));
}, outVars.at(m_name));
} else {
throwNodeError(hex::format("Out variable '{}' has not been defined!", this->m_name));
throwNodeError(hex::format("Out variable '{}' has not been defined!", m_name));
}
}
void store(nlohmann::json &j) const override {
j = nlohmann::json::object();
j["name"] = this->m_name;
j["name"] = m_name;
}
void load(const nlohmann::json &j) override {
this->m_name = j["name"].get<std::string>();
m_name = j["name"].get<std::string>();
}
private:

View File

@@ -11,18 +11,18 @@ namespace hex::plugin::builtin {
void drawNode() override {
ImGui::PushItemWidth(150_scaled);
if (this->m_value.has_value())
ImGuiExt::TextFormatted("0x{0:X}", this->m_value.value());
if (m_value.has_value())
ImGuiExt::TextFormatted("0x{0:X}", m_value.value());
else
ImGui::TextUnformatted("???");
ImGui::PopItemWidth();
}
void process() override {
this->m_value.reset();
m_value.reset();
const auto &input = this->getIntegerOnInput(0);
this->m_value = input;
m_value = input;
}
private:
@@ -35,18 +35,18 @@ namespace hex::plugin::builtin {
void drawNode() override {
ImGui::PushItemWidth(150_scaled);
if (this->m_value.has_value())
ImGuiExt::TextFormatted("{0}", this->m_value.value());
if (m_value.has_value())
ImGuiExt::TextFormatted("{0}", m_value.value());
else
ImGui::TextUnformatted("???");
ImGui::PopItemWidth();
}
void process() override {
this->m_value.reset();
m_value.reset();
const auto &input = this->getFloatOnInput(0);
this->m_value = input;
m_value = input;
}
private:
@@ -63,7 +63,7 @@ namespace hex::plugin::builtin {
if (ImGui::BeginChild("##hex_view", scaled(ImVec2(ImGui::CalcTextSize(Header.c_str()).x, 200)), true)) {
ImGui::TextUnformatted(Header.c_str());
auto size = this->m_buffer.size();
auto size = m_buffer.size();
ImGuiListClipper clipper;
clipper.Begin((size + 0x0F) / 0x10);
@@ -75,7 +75,7 @@ namespace hex::plugin::builtin {
std::string line = hex::format(" {:08X}: ", y * 0x10);
for (u32 x = 0; x < 0x10; x++) {
if (x < lineSize)
line += hex::format("{:02X} ", this->m_buffer[y * 0x10 + x]);
line += hex::format("{:02X} ", m_buffer[y * 0x10 + x]);
else
line += " ";
@@ -85,7 +85,7 @@ namespace hex::plugin::builtin {
line += " ";
for (u32 x = 0; x < lineSize; x++) {
auto c = char(this->m_buffer[y * 0x10 + x]);
auto c = char(m_buffer[y * 0x10 + x]);
if (std::isprint(c))
line += c;
else
@@ -100,7 +100,7 @@ namespace hex::plugin::builtin {
}
void process() override {
this->m_buffer = this->getBufferOnInput(0);
m_buffer = this->getBufferOnInput(0);
}
private:
@@ -114,7 +114,7 @@ namespace hex::plugin::builtin {
void drawNode() override {
constexpr static auto LineLength = 50;
if (ImGui::BeginChild("##string_view", scaled(ImVec2(ImGui::CalcTextSize(" ").x * (LineLength + 4), 150)), true)) {
std::string_view string = this->m_value;
std::string_view string = m_value;
ImGuiListClipper clipper;
clipper.Begin((string.length() + (LineLength - 1)) / LineLength);
@@ -135,7 +135,7 @@ namespace hex::plugin::builtin {
void process() override {
const auto &input = this->getBufferOnInput(0);
this->m_value = hex::encodeByteString(input);
m_value = hex::encodeByteString(input);
}
private:
@@ -148,7 +148,7 @@ namespace hex::plugin::builtin {
void drawNode() override {
ImGui::PushItemWidth(100_scaled);
ImGui::Text("%s", this->m_display.c_str());
ImGui::Text("%s", m_display.c_str());
ImGui::PopItemWidth();
}
@@ -165,7 +165,7 @@ namespace hex::plugin::builtin {
display += (byte & (1 << i)) != 0 ? '1' : '0';
}
}
this->m_display = wolv::util::trim(display);
m_display = wolv::util::trim(display);
}
private:

View File

@@ -236,16 +236,16 @@ namespace hex::plugin::builtin {
hex::unused(address, data, size, upperCase);
if (startedEditing) {
this->m_currColor = { float(data[0]) / 0xFF, float(data[1]) / 0xFF, float(data[2]) / 0xFF, float(data[3]) / 0xFF };
m_currColor = { float(data[0]) / 0xFF, float(data[1]) / 0xFF, float(data[2]) / 0xFF, float(data[3]) / 0xFF };
ImGui::OpenPopup("##color_popup");
}
ImGui::ColorButton("##color", ImColor(this->m_currColor[0], this->m_currColor[1], this->m_currColor[2], this->m_currColor[3]), ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
ImGui::ColorButton("##color", ImColor(m_currColor[0], m_currColor[1], m_currColor[2], m_currColor[3]), ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
if (ImGui::BeginPopup("##color_popup")) {
if (ImGui::ColorPicker4("##picker", this->m_currColor.data(), ImGuiColorEditFlags_AlphaBar)) {
if (ImGui::ColorPicker4("##picker", m_currColor.data(), ImGuiColorEditFlags_AlphaBar)) {
for (u8 i = 0; i < 4; i++)
data[i] = this->m_currColor[i] * 0xFF;
data[i] = m_currColor[i] * 0xFF;
}
ImGui::EndPopup();
} else {
@@ -274,11 +274,11 @@ namespace hex::plugin::builtin {
hex::unused(address, startedEditing);
if (startedEditing) {
this->m_inputBuffer = hex::format("{:08b}", *data);
m_inputBuffer = hex::format("{:08b}", *data);
}
if (drawDefaultTextEditingTextBox(address, this->m_inputBuffer, ImGuiInputTextFlags_None)) {
if (auto result = hex::parseBinaryString(wolv::util::trim(this->m_inputBuffer)); result.has_value()) {
if (drawDefaultTextEditingTextBox(address, m_inputBuffer, ImGuiInputTextFlags_None)) {
if (auto result = hex::parseBinaryString(wolv::util::trim(m_inputBuffer)); result.has_value()) {
*data = result.value();
return true;
}

View File

@@ -112,14 +112,14 @@ namespace hex::plugin::builtin {
: Hash(name), m_crcFunction(crcFunction), m_polynomial(polynomial), m_initialValue(initialValue), m_xorOut(xorOut), m_reflectIn(reflectIn), m_reflectOut(reflectOut) {}
void draw() override {
ImGuiExt::InputHexadecimal("hex.builtin.hash.crc.poly"_lang, &this->m_polynomial);
ImGuiExt::InputHexadecimal("hex.builtin.hash.crc.iv"_lang, &this->m_initialValue);
ImGuiExt::InputHexadecimal("hex.builtin.hash.crc.xor_out"_lang, &this->m_xorOut);
ImGuiExt::InputHexadecimal("hex.builtin.hash.crc.poly"_lang, &m_polynomial);
ImGuiExt::InputHexadecimal("hex.builtin.hash.crc.iv"_lang, &m_initialValue);
ImGuiExt::InputHexadecimal("hex.builtin.hash.crc.xor_out"_lang, &m_xorOut);
ImGui::NewLine();
ImGui::Checkbox("hex.builtin.hash.crc.refl_in"_lang, &this->m_reflectIn);
ImGui::Checkbox("hex.builtin.hash.crc.refl_out"_lang, &this->m_reflectOut);
ImGui::Checkbox("hex.builtin.hash.crc.refl_in"_lang, &m_reflectIn);
ImGui::Checkbox("hex.builtin.hash.crc.refl_out"_lang, &m_reflectOut);
}
Function create(std::string name) override {
@@ -139,22 +139,22 @@ namespace hex::plugin::builtin {
[[nodiscard]] nlohmann::json store() const override {
nlohmann::json result;
result["polynomial"] = this->m_polynomial;
result["initialValue"] = this->m_initialValue;
result["xorOut"] = this->m_xorOut;
result["reflectIn"] = this->m_reflectIn;
result["reflectOut"] = this->m_reflectOut;
result["polynomial"] = m_polynomial;
result["initialValue"] = m_initialValue;
result["xorOut"] = m_xorOut;
result["reflectIn"] = m_reflectIn;
result["reflectOut"] = m_reflectOut;
return result;
}
void load(const nlohmann::json &json) override {
try {
this->m_polynomial = json.at("polynomial");
this->m_initialValue = json.at("initialValue");
this->m_xorOut = json.at("xorOut");
this->m_reflectIn = json.at("reflectIn");
this->m_reflectOut = json.at("reflectOut");
m_polynomial = json.at("polynomial");
m_initialValue = json.at("initialValue");
m_xorOut = json.at("xorOut");
m_reflectIn = json.at("reflectIn");
m_reflectOut = json.at("reflectOut");
} catch (std::exception&) { }
}

View File

@@ -50,21 +50,21 @@ namespace hex::plugin::builtin {
bool DiskProvider::isAvailable() const {
#if defined(OS_WINDOWS)
return this->m_diskHandle != INVALID_HANDLE_VALUE;
return m_diskHandle != INVALID_HANDLE_VALUE;
#else
return this->m_diskHandle != -1;
return m_diskHandle != -1;
#endif
}
bool DiskProvider::isReadable() const {
return this->m_readable;
return m_readable;
}
bool DiskProvider::isWritable() const {
return this->m_writable;
return m_writable;
}
bool DiskProvider::isResizable() const {
@@ -77,7 +77,7 @@ namespace hex::plugin::builtin {
void DiskProvider::setPath(const std::fs::path &path) {
this->m_path = path;
m_path = path;
}
#if defined (OS_LINUX)
@@ -143,19 +143,19 @@ namespace hex::plugin::builtin {
#endif
bool DiskProvider::open() {
this->m_readable = true;
this->m_writable = true;
m_readable = true;
m_writable = true;
#if defined(OS_WINDOWS)
const auto &path = this->m_path.native();
const auto &path = m_path.native();
this->m_diskHandle = CreateFileW(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (this->m_diskHandle == INVALID_HANDLE_VALUE) {
this->m_diskHandle = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
this->m_writable = false;
m_diskHandle = CreateFileW(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (m_diskHandle == INVALID_HANDLE_VALUE) {
m_diskHandle = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
m_writable = false;
if (this->m_diskHandle == INVALID_HANDLE_VALUE)
if (m_diskHandle == INVALID_HANDLE_VALUE)
return false;
}
@@ -163,7 +163,7 @@ namespace hex::plugin::builtin {
DISK_GEOMETRY_EX diskGeometry = { };
DWORD bytesRead = 0;
if (DeviceIoControl(
this->m_diskHandle,
m_diskHandle,
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
nullptr,
0,
@@ -171,45 +171,45 @@ namespace hex::plugin::builtin {
sizeof(DISK_GEOMETRY_EX),
&bytesRead,
nullptr)) {
this->m_diskSize = diskGeometry.DiskSize.QuadPart;
this->m_sectorSize = diskGeometry.Geometry.BytesPerSector;
this->m_sectorBuffer.resize(this->m_sectorSize);
m_diskSize = diskGeometry.DiskSize.QuadPart;
m_sectorSize = diskGeometry.Geometry.BytesPerSector;
m_sectorBuffer.resize(m_sectorSize);
}
}
if (this->m_diskHandle == nullptr || this->m_diskHandle == INVALID_HANDLE_VALUE) {
this->m_readable = false;
this->m_diskHandle = nullptr;
CloseHandle(this->m_diskHandle);
if (m_diskHandle == nullptr || m_diskHandle == INVALID_HANDLE_VALUE) {
m_readable = false;
m_diskHandle = nullptr;
CloseHandle(m_diskHandle);
return false;
}
#else
const auto &path = this->m_path.native();
const auto &path = m_path.native();
this->m_diskHandle = ::open(path.c_str(), O_RDWR);
if (this->m_diskHandle == -1) {
m_diskHandle = ::open(path.c_str(), O_RDWR);
if (m_diskHandle == -1) {
this->setErrorMessage(hex::format("hex.builtin.provider.disk.error.read_rw"_lang, path, ::strerror(errno)));
log::warn(this->getErrorMessage());
this->m_diskHandle = ::open(path.c_str(), O_RDONLY);
this->m_writable = false;
m_diskHandle = ::open(path.c_str(), O_RDONLY);
m_writable = false;
}
if (this->m_diskHandle == -1) {
if (m_diskHandle == -1) {
this->setErrorMessage(hex::format("hex.builtin.provider.disk.error.read_ro"_lang, path, ::strerror(errno)));
log::warn(this->getErrorMessage());
this->m_readable = false;
m_readable = false;
return false;
}
u64 diskSize = 0;
blkdev_get_size(this->m_diskHandle, &diskSize);
this->m_diskSize = diskSize;
blkdev_get_sector_size(this->m_diskHandle, reinterpret_cast<int *>(&this->m_sectorSize));
blkdev_get_size(m_diskHandle, &diskSize);
m_diskSize = diskSize;
blkdev_get_sector_size(m_diskHandle, reinterpret_cast<int *>(&m_sectorSize));
this->m_sectorBuffer.resize(this->m_sectorSize);
m_sectorBuffer.resize(m_sectorSize);
#endif
@@ -219,17 +219,17 @@ namespace hex::plugin::builtin {
void DiskProvider::close() {
#if defined(OS_WINDOWS)
if (this->m_diskHandle != INVALID_HANDLE_VALUE)
::CloseHandle(this->m_diskHandle);
if (m_diskHandle != INVALID_HANDLE_VALUE)
::CloseHandle(m_diskHandle);
this->m_diskHandle = INVALID_HANDLE_VALUE;
m_diskHandle = INVALID_HANDLE_VALUE;
#else
if (this->m_diskHandle != -1)
::close(this->m_diskHandle);
if (m_diskHandle != -1)
::close(m_diskHandle);
this->m_diskHandle = -1;
m_diskHandle = -1;
#endif
}
@@ -243,19 +243,19 @@ namespace hex::plugin::builtin {
while (size > 0) {
LARGE_INTEGER seekPosition;
seekPosition.LowPart = (offset & 0xFFFF'FFFF) - (offset % this->m_sectorSize);
seekPosition.LowPart = (offset & 0xFFFF'FFFF) - (offset % m_sectorSize);
seekPosition.HighPart = LONG(offset >> 32);
if (this->m_sectorBufferAddress != static_cast<u64>(seekPosition.QuadPart)) {
::SetFilePointer(this->m_diskHandle, seekPosition.LowPart, &seekPosition.HighPart, FILE_BEGIN);
::ReadFile(this->m_diskHandle, this->m_sectorBuffer.data(), this->m_sectorBuffer.size(), &bytesRead, nullptr);
this->m_sectorBufferAddress = seekPosition.QuadPart;
if (m_sectorBufferAddress != static_cast<u64>(seekPosition.QuadPart)) {
::SetFilePointer(m_diskHandle, seekPosition.LowPart, &seekPosition.HighPart, FILE_BEGIN);
::ReadFile(m_diskHandle, m_sectorBuffer.data(), m_sectorBuffer.size(), &bytesRead, nullptr);
m_sectorBufferAddress = seekPosition.QuadPart;
}
std::memcpy(static_cast<u8 *>(buffer) + (offset - startOffset), this->m_sectorBuffer.data() + (offset & (this->m_sectorSize - 1)), std::min<u64>(this->m_sectorSize, size));
std::memcpy(static_cast<u8 *>(buffer) + (offset - startOffset), m_sectorBuffer.data() + (offset & (m_sectorSize - 1)), std::min<u64>(m_sectorSize, size));
size = std::max<ssize_t>(static_cast<ssize_t>(size) - this->m_sectorSize, 0);
offset += this->m_sectorSize;
size = std::max<ssize_t>(static_cast<ssize_t>(size) - m_sectorSize, 0);
offset += m_sectorSize;
}
#else
@@ -263,22 +263,22 @@ namespace hex::plugin::builtin {
u64 startOffset = offset;
while (size > 0) {
u64 seekPosition = offset - (offset % this->m_sectorSize);
u64 seekPosition = offset - (offset % m_sectorSize);
if (this->m_sectorBufferAddress != seekPosition || this->m_sectorBufferAddress == 0) {
::lseek(this->m_diskHandle, seekPosition, SEEK_SET);
if (::read(this->m_diskHandle, this->m_sectorBuffer.data(), this->m_sectorBuffer.size()) == -1)
if (m_sectorBufferAddress != seekPosition || m_sectorBufferAddress == 0) {
::lseek(m_diskHandle, seekPosition, SEEK_SET);
if (::read(m_diskHandle, m_sectorBuffer.data(), m_sectorBuffer.size()) == -1)
break;
this->m_sectorBufferAddress = seekPosition;
m_sectorBufferAddress = seekPosition;
}
std::memcpy(reinterpret_cast<u8 *>(buffer) + (offset - startOffset),
this->m_sectorBuffer.data() + (offset & (this->m_sectorSize - 1)),
std::min<u64>(this->m_sectorSize, size));
m_sectorBuffer.data() + (offset & (m_sectorSize - 1)),
std::min<u64>(m_sectorSize, size));
size = std::max<ssize_t>(static_cast<ssize_t>(size) - this->m_sectorSize, 0);
offset += this->m_sectorSize;
size = std::max<ssize_t>(static_cast<ssize_t>(size) - m_sectorSize, 0);
offset += m_sectorSize;
}
#endif
@@ -292,21 +292,21 @@ namespace hex::plugin::builtin {
u64 startOffset = offset;
std::vector<u8> modifiedSectorBuffer;
modifiedSectorBuffer.resize(this->m_sectorSize);
modifiedSectorBuffer.resize(m_sectorSize);
while (size > 0) {
u64 sectorBase = offset - (offset % this->m_sectorSize);
size_t currSize = std::min<u64>(size, this->m_sectorSize);
u64 sectorBase = offset - (offset % m_sectorSize);
size_t currSize = std::min<u64>(size, m_sectorSize);
this->readRaw(sectorBase, modifiedSectorBuffer.data(), modifiedSectorBuffer.size());
std::memcpy(modifiedSectorBuffer.data() + ((offset - sectorBase) % this->m_sectorSize), reinterpret_cast<const u8 *>(buffer) + (startOffset - offset), currSize);
std::memcpy(modifiedSectorBuffer.data() + ((offset - sectorBase) % m_sectorSize), reinterpret_cast<const u8 *>(buffer) + (startOffset - offset), currSize);
LARGE_INTEGER seekPosition;
seekPosition.LowPart = (offset & 0xFFFF'FFFF) - (offset % this->m_sectorSize);
seekPosition.LowPart = (offset & 0xFFFF'FFFF) - (offset % m_sectorSize);
seekPosition.HighPart = offset >> 32;
::SetFilePointer(this->m_diskHandle, seekPosition.LowPart, &seekPosition.HighPart, FILE_BEGIN);
::WriteFile(this->m_diskHandle, modifiedSectorBuffer.data(), modifiedSectorBuffer.size(), &bytesWritten, nullptr);
::SetFilePointer(m_diskHandle, seekPosition.LowPart, &seekPosition.HighPart, FILE_BEGIN);
::WriteFile(m_diskHandle, modifiedSectorBuffer.data(), modifiedSectorBuffer.size(), &bytesWritten, nullptr);
offset += currSize;
size -= currSize;
@@ -317,17 +317,17 @@ namespace hex::plugin::builtin {
u64 startOffset = offset;
std::vector<u8> modifiedSectorBuffer;
modifiedSectorBuffer.resize(this->m_sectorSize);
modifiedSectorBuffer.resize(m_sectorSize);
while (size > 0) {
u64 sectorBase = offset - (offset % this->m_sectorSize);
size_t currSize = std::min<u64>(size, this->m_sectorSize);
u64 sectorBase = offset - (offset % m_sectorSize);
size_t currSize = std::min<u64>(size, m_sectorSize);
this->readRaw(sectorBase, modifiedSectorBuffer.data(), modifiedSectorBuffer.size());
std::memcpy(modifiedSectorBuffer.data() + ((offset - sectorBase) % this->m_sectorSize), reinterpret_cast<const u8 *>(buffer) + (startOffset - offset), currSize);
std::memcpy(modifiedSectorBuffer.data() + ((offset - sectorBase) % m_sectorSize), reinterpret_cast<const u8 *>(buffer) + (startOffset - offset), currSize);
::lseek(this->m_diskHandle, sectorBase, SEEK_SET);
if (::write(this->m_diskHandle, modifiedSectorBuffer.data(), modifiedSectorBuffer.size()) < 0)
::lseek(m_diskHandle, sectorBase, SEEK_SET);
if (::write(m_diskHandle, modifiedSectorBuffer.data(), modifiedSectorBuffer.size()) < 0)
break;
offset += currSize;
@@ -338,21 +338,21 @@ namespace hex::plugin::builtin {
}
u64 DiskProvider::getActualSize() const {
return this->m_diskSize;
return m_diskSize;
}
std::string DiskProvider::getName() const {
if (this->m_friendlyName.empty())
return wolv::util::toUTF8String(this->m_path);
if (m_friendlyName.empty())
return wolv::util::toUTF8String(m_path);
else
return this->m_friendlyName;
return m_friendlyName;
}
std::vector<DiskProvider::Description> DiskProvider::getDataDescription() const {
return {
{ "hex.builtin.provider.disk.selected_disk"_lang, wolv::util::toUTF8String(this->m_path) },
{ "hex.builtin.provider.disk.disk_size"_lang, hex::toByteString(this->m_diskSize) },
{ "hex.builtin.provider.disk.sector_size"_lang, hex::toByteString(this->m_sectorSize) }
{ "hex.builtin.provider.disk.selected_disk"_lang, wolv::util::toUTF8String(m_path) },
{ "hex.builtin.provider.disk.disk_size"_lang, hex::toByteString(m_diskSize) },
{ "hex.builtin.provider.disk.sector_size"_lang, hex::toByteString(m_sectorSize) }
};
}
@@ -360,7 +360,7 @@ namespace hex::plugin::builtin {
void DiskProvider::reloadDrives() {
#if defined(OS_WINDOWS)
this->m_availableDrives.clear();
m_availableDrives.clear();
std::array<TCHAR, MAX_DEVICE_ID_LEN> deviceInstanceID = {};
std::array<TCHAR, 1024> description = {};
@@ -412,7 +412,7 @@ namespace hex::plugin::builtin {
auto friendlyName = description.data();
this->m_availableDrives.insert({ path, friendlyName });
m_availableDrives.insert({ path, friendlyName });
}
// Add all logical drives
@@ -420,7 +420,7 @@ namespace hex::plugin::builtin {
for (char i = 0; i < 26; i++) {
if (drives[i]) {
char letter = 'A' + i;
this->m_availableDrives.insert({ hex::format(R"(\\.\{:c}:)", letter), hex::format(R"({:c}:/)", letter) });
m_availableDrives.insert({ hex::format(R"(\\.\{:c}:)", letter), hex::format(R"({:c}:/)", letter) });
}
}
@@ -430,12 +430,12 @@ namespace hex::plugin::builtin {
bool DiskProvider::drawLoadInterface() {
#if defined(OS_WINDOWS)
if (this->m_availableDrives.empty()) {
if (m_availableDrives.empty()) {
this->reloadDrives();
this->m_elevated = hex::isProcessElevated();
m_elevated = hex::isProcessElevated();
}
if (!this->m_elevated) {
if (!m_elevated) {
ImGui::PushTextWrapPos(0);
ImGuiExt::TextFormattedColored(ImGuiExt::GetCustomColorU32(ImGuiCustomCol_LoggerError), ICON_VS_SHIELD "{}", "hex.builtin.provider.disk.elevation"_lang);
ImGui::PopTextWrapPos();
@@ -445,10 +445,10 @@ namespace hex::plugin::builtin {
ImGui::PushItemWidth(300_scaled);
if (ImGui::BeginListBox("hex.builtin.provider.disk.selected_disk"_lang)) {
ImGui::PushID(1);
for (const auto &[path, friendlyName] : this->m_availableDrives) {
if (ImGui::Selectable(friendlyName.c_str(), this->m_path == path)) {
this->m_path = path;
this->m_friendlyName = friendlyName;
for (const auto &[path, friendlyName] : m_availableDrives) {
if (ImGui::Selectable(friendlyName.c_str(), m_path == path)) {
m_path = path;
m_friendlyName = friendlyName;
}
ImGuiExt::InfoTooltip(path.c_str());
@@ -467,20 +467,20 @@ namespace hex::plugin::builtin {
#else
if (ImGui::InputText("hex.builtin.provider.disk.selected_disk"_lang, this->m_pathBuffer.data(), this->m_pathBuffer.size(), ImGuiInputTextFlags_CallbackResize, ImGuiExt::UpdateStringSizeCallback, &this->m_pathBuffer)) {
this->m_path = this->m_pathBuffer;
this->m_friendlyName = this->m_pathBuffer;
if (ImGui::InputText("hex.builtin.provider.disk.selected_disk"_lang, m_pathBuffer.data(), m_pathBuffer.size(), ImGuiInputTextFlags_CallbackResize, ImGuiExt::UpdateStringSizeCallback, &m_pathBuffer)) {
m_path = m_pathBuffer;
m_friendlyName = m_pathBuffer;
}
#endif
return !this->m_path.empty();
return !m_path.empty();
}
nlohmann::json DiskProvider::storeSettings(nlohmann::json settings) const {
settings["path"] = wolv::util::toUTF8String(this->m_path);
settings["path"] = wolv::util::toUTF8String(m_path);
settings["friendly_name"] = this->m_friendlyName;
settings["friendly_name"] = m_friendlyName;
return Provider::storeSettings(settings);
}
@@ -491,7 +491,7 @@ namespace hex::plugin::builtin {
auto path = settings.at("path").get<std::string>();
if (settings.contains("friendly_name"))
this->m_friendlyName = settings.at("friendly_name").get<std::string>();
m_friendlyName = settings.at("friendly_name").get<std::string>();
this->setPath(std::u8string(path.begin(), path.end()));
this->reloadDrives();
@@ -508,11 +508,11 @@ namespace hex::plugin::builtin {
std::variant<std::string, i128> DiskProvider::queryInformation(const std::string &category, const std::string &argument) {
if (category == "file_path")
return wolv::util::toUTF8String(this->m_path);
return wolv::util::toUTF8String(m_path);
else if (category == "sector_size")
return this->m_sectorSize;
return m_sectorSize;
else if (category == "friendly_name")
return this->m_friendlyName;
return m_friendlyName;
else
return Provider::queryInformation(category, argument);
}

View File

@@ -27,11 +27,11 @@ namespace hex::plugin::builtin {
}
bool FileProvider::isReadable() const {
return isAvailable() && this->m_readable;
return isAvailable() && m_readable;
}
bool FileProvider::isWritable() const {
return isAvailable() && this->m_writable;
return isAvailable() && m_writable;
}
bool FileProvider::isResizable() const {
@@ -39,7 +39,7 @@ namespace hex::plugin::builtin {
}
bool FileProvider::isSavable() const {
return this->m_undoRedoStack.canUndo();
return m_undoRedoStack.canUndo();
}
void FileProvider::readRaw(u64 offset, void *buffer, size_t size) {
@@ -47,14 +47,14 @@ namespace hex::plugin::builtin {
if (actualSize == 0 || (offset + size) > actualSize || buffer == nullptr || size == 0)
return;
std::memcpy(buffer, this->m_file.getMapping() + offset, size);
std::memcpy(buffer, m_file.getMapping() + offset, size);
}
void FileProvider::writeRaw(u64 offset, const void *buffer, size_t size) {
if ((offset + size) > this->getActualSize() || buffer == nullptr || size == 0)
return;
std::memcpy(this->m_file.getMapping() + offset, buffer, size);
std::memcpy(m_file.getMapping() + offset, buffer, size);
}
void FileProvider::save() {
@@ -62,7 +62,7 @@ namespace hex::plugin::builtin {
FILETIME ft;
SYSTEMTIME st;
wolv::io::File file(this->m_path, wolv::io::File::Mode::Write);
wolv::io::File file(m_path, wolv::io::File::Mode::Write);
if (file.isValid()) {
GetSystemTime(&st);
if (SystemTimeToFileTime(&st, &ft)) {
@@ -76,7 +76,7 @@ namespace hex::plugin::builtin {
}
void FileProvider::saveAs(const std::fs::path &path) {
if (path == this->m_path)
if (path == m_path)
this->save();
else
Provider::saveAs(path);
@@ -86,7 +86,7 @@ namespace hex::plugin::builtin {
this->close();
{
wolv::io::File file(this->m_path, wolv::io::File::Mode::Write);
wolv::io::File file(m_path, wolv::io::File::Mode::Write);
file.setSize(newSize);
}
@@ -139,29 +139,29 @@ namespace hex::plugin::builtin {
}
u64 FileProvider::getActualSize() const {
return this->m_fileSize;
return m_fileSize;
}
std::string FileProvider::getName() const {
return wolv::util::toUTF8String(this->m_path.filename());
return wolv::util::toUTF8String(m_path.filename());
}
std::vector<FileProvider::Description> FileProvider::getDataDescription() const {
std::vector<Description> result;
result.emplace_back("hex.builtin.provider.file.path"_lang, wolv::util::toUTF8String(this->m_path));
result.emplace_back("hex.builtin.provider.file.path"_lang, wolv::util::toUTF8String(m_path));
result.emplace_back("hex.builtin.provider.file.size"_lang, hex::toByteString(this->getActualSize()));
if (this->m_fileStats.has_value()) {
if (m_fileStats.has_value()) {
std::string creationTime, accessTime, modificationTime;
try { creationTime = hex::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(this->m_fileStats->st_ctime)); }
try { creationTime = hex::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(m_fileStats->st_ctime)); }
catch (const std::exception&) { creationTime = "???"; }
try { accessTime = hex::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(this->m_fileStats->st_atime)); }
try { accessTime = hex::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(m_fileStats->st_atime)); }
catch (const std::exception&) { accessTime = "???"; }
try { modificationTime = hex::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(this->m_fileStats->st_mtime)); }
try { modificationTime = hex::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(m_fileStats->st_mtime)); }
catch (const std::exception&) { modificationTime = "???"; }
result.emplace_back("hex.builtin.provider.file.creation"_lang, creationTime);
@@ -174,19 +174,19 @@ namespace hex::plugin::builtin {
std::variant<std::string, i128> FileProvider::queryInformation(const std::string &category, const std::string &argument) {
if (category == "file_path")
return wolv::util::toUTF8String(this->m_path);
return wolv::util::toUTF8String(m_path);
else if (category == "file_name")
return wolv::util::toUTF8String(this->m_path.filename());
return wolv::util::toUTF8String(m_path.filename());
else if (category == "file_extension")
return wolv::util::toUTF8String(this->m_path.extension());
return wolv::util::toUTF8String(m_path.extension());
else if (category == "creation_time")
return this->m_fileStats->st_ctime;
return m_fileStats->st_ctime;
else if (category == "access_time")
return this->m_fileStats->st_atime;
return m_fileStats->st_atime;
else if (category == "modification_time")
return this->m_fileStats->st_mtime;
return m_fileStats->st_mtime;
else if (category == "permissions")
return this->m_fileStats->st_mode & 0777;
return m_fileStats->st_mode & 0777;
else
return Provider::queryInformation(category, argument);
}
@@ -199,50 +199,50 @@ namespace hex::plugin::builtin {
std::vector<FileProvider::MenuEntry> FileProvider::getMenuEntries(){
return {
{ "hex.builtin.provider.file.menu.open_folder"_lang, [this] { fs::openFolderWithSelectionExternal(this->m_path); } },
{ "hex.builtin.provider.file.menu.open_file"_lang, [this] { fs::openFileExternal(this->m_path); } },
{ "hex.builtin.provider.file.menu.open_folder"_lang, [this] { fs::openFolderWithSelectionExternal(m_path); } },
{ "hex.builtin.provider.file.menu.open_file"_lang, [this] { fs::openFileExternal(m_path); } },
{ "hex.builtin.provider.file.menu.into_memory"_lang, [this] { this->convertToMemoryFile(); } }
};
}
void FileProvider::setPath(const std::fs::path &path) {
this->m_path = path;
m_path = path;
}
bool FileProvider::open() {
this->m_readable = true;
this->m_writable = true;
m_readable = true;
m_writable = true;
if (!std::fs::exists(this->m_path)) {
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, this->m_path.string(), ::strerror(ENOENT)));
if (!std::fs::exists(m_path)) {
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, m_path.string(), ::strerror(ENOENT)));
return false;
}
wolv::io::File file(this->m_path, wolv::io::File::Mode::Write);
wolv::io::File file(m_path, wolv::io::File::Mode::Write);
if (!file.isValid()) {
this->m_writable = false;
m_writable = false;
file = wolv::io::File(this->m_path, wolv::io::File::Mode::Read);
file = wolv::io::File(m_path, wolv::io::File::Mode::Read);
if (!file.isValid()) {
this->m_readable = false;
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, this->m_path.string(), ::strerror(errno)));
m_readable = false;
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, m_path.string(), ::strerror(errno)));
return false;
}
}
this->m_fileStats = file.getFileInfo();
this->m_file = std::move(file);
m_fileStats = file.getFileInfo();
m_file = std::move(file);
this->m_file.map();
this->m_fileSize = this->m_file.getSize();
m_file.map();
m_fileSize = m_file.getSize();
this->m_file.close();
m_file.close();
return true;
}
void FileProvider::close() {
this->m_file.unmap();
m_file.unmap();
}
void FileProvider::loadSettings(const nlohmann::json &settings) {
@@ -258,7 +258,7 @@ namespace hex::plugin::builtin {
try {
this->setPath(projectPath.parent_path() / path);
} catch (const std::fs::filesystem_error &e) {
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, this->m_path.string(), e.what()));
this->setErrorMessage(hex::format("hex.builtin.provider.file.error.open"_lang, m_path.string(), e.what()));
}
}
}
@@ -269,9 +269,9 @@ namespace hex::plugin::builtin {
nlohmann::json FileProvider::storeSettings(nlohmann::json settings) const {
std::string path;
if (auto projectPath = ProjectFile::getPath(); !projectPath.empty())
path = wolv::util::toUTF8String(std::fs::proximate(this->m_path, projectPath.parent_path()));
path = wolv::util::toUTF8String(std::fs::proximate(m_path, projectPath.parent_path()));
if (path.empty())
path = wolv::util::toUTF8String(this->m_path);
path = wolv::util::toUTF8String(m_path);
settings["path"] = path;

View File

@@ -127,11 +127,11 @@ namespace hex::plugin::builtin {
}
bool GDBProvider::isAvailable() const {
return this->m_socket.isConnected();
return m_socket.isConnected();
}
bool GDBProvider::isReadable() const {
return this->m_socket.isConnected();
return m_socket.isConnected();
}
bool GDBProvider::isWritable() const {
@@ -155,28 +155,28 @@ namespace hex::plugin::builtin {
u64 alignedOffset = offset - (offset % CacheLineSize);
if (size <= CacheLineSize) {
std::scoped_lock lock(this->m_cacheLock);
std::scoped_lock lock(m_cacheLock);
const auto &cacheLine = std::find_if(this->m_cache.begin(), this->m_cache.end(), [&](auto &line) {
const auto &cacheLine = std::find_if(m_cache.begin(), m_cache.end(), [&](auto &line) {
return line.address == alignedOffset;
});
if (cacheLine != this->m_cache.end()) {
if (cacheLine != m_cache.end()) {
// Cache hit
} else {
// Cache miss
this->m_cache.push_back({ alignedOffset, { 0 } });
m_cache.push_back({ alignedOffset, { 0 } });
}
if (cacheLine != this->m_cache.end())
if (cacheLine != m_cache.end())
std::memcpy(buffer, &cacheLine->data[0] + (offset % CacheLineSize), std::min<u64>(size, cacheLine->data.size()));
} else {
while (size > 0) {
size_t readSize = std::min<u64>(size, CacheLineSize);
auto data = gdb::readMemory(this->m_socket, offset, size);
auto data = gdb::readMemory(m_socket, offset, size);
if (!data.empty())
std::memcpy(buffer, &data[0], data.size());
@@ -192,7 +192,7 @@ namespace hex::plugin::builtin {
offset -= this->getBaseAddress();
gdb::writeMemory(this->m_socket, offset, buffer, size);
gdb::writeMemory(m_socket, offset, buffer, size);
}
void GDBProvider::save() {
@@ -200,7 +200,7 @@ namespace hex::plugin::builtin {
}
u64 GDBProvider::getActualSize() const {
return this->m_size;
return m_size;
}
std::string GDBProvider::getName() const {
@@ -208,8 +208,8 @@ namespace hex::plugin::builtin {
std::string port = "-";
if (this->isConnected()) {
address = this->m_ipAddress;
port = std::to_string(this->m_port);
address = m_ipAddress;
port = std::to_string(m_port);
}
return hex::format("hex.builtin.provider.gdb.name"_lang, address, port);
@@ -217,46 +217,46 @@ namespace hex::plugin::builtin {
std::vector<GDBProvider::Description> GDBProvider::getDataDescription() const {
return {
{"hex.builtin.provider.gdb.server"_lang, hex::format("{}:{}", this->m_ipAddress, this->m_port)},
{"hex.builtin.provider.gdb.server"_lang, hex::format("{}:{}", m_ipAddress, m_port)},
};
}
bool GDBProvider::open() {
this->m_socket = wolv::net::SocketClient(wolv::net::SocketClient::Type::TCP);
this->m_socket.connect(this->m_ipAddress, this->m_port);
if (!gdb::enableNoAckMode(this->m_socket)) {
this->m_socket.disconnect();
m_socket = wolv::net::SocketClient(wolv::net::SocketClient::Type::TCP);
m_socket.connect(m_ipAddress, m_port);
if (!gdb::enableNoAckMode(m_socket)) {
m_socket.disconnect();
return false;
}
if (this->m_socket.isConnected()) {
gdb::continueExecution(this->m_socket);
if (m_socket.isConnected()) {
gdb::continueExecution(m_socket);
this->m_cacheUpdateThread = std::thread([this] {
auto cacheLine = this->m_cache.begin();
m_cacheUpdateThread = std::thread([this] {
auto cacheLine = m_cache.begin();
while (this->isConnected()) {
{
std::scoped_lock lock(this->m_cacheLock);
std::scoped_lock lock(m_cacheLock);
if (this->m_resetCache) {
this->m_cache.clear();
this->m_resetCache = false;
cacheLine = this->m_cache.begin();
if (m_resetCache) {
m_cache.clear();
m_resetCache = false;
cacheLine = m_cache.begin();
}
if (cacheLine != this->m_cache.end()) {
std::vector<u8> data = gdb::readMemory(this->m_socket, cacheLine->address, CacheLineSize);
if (cacheLine != m_cache.end()) {
std::vector<u8> data = gdb::readMemory(m_socket, cacheLine->address, CacheLineSize);
while (std::count_if(this->m_cache.begin(), this->m_cache.end(), [&](auto &line) { return !line.data.empty(); }) > 100) {
this->m_cache.pop_front();
cacheLine = this->m_cache.begin();
while (std::count_if(m_cache.begin(), m_cache.end(), [&](auto &line) { return !line.data.empty(); }) > 100) {
m_cache.pop_front();
cacheLine = m_cache.begin();
}
std::memcpy(cacheLine->data.data(), data.data(), data.size());
}
if (cacheLine == this->m_cache.end())
cacheLine = this->m_cache.begin();
if (cacheLine == m_cache.end())
cacheLine = m_cache.begin();
else
++cacheLine;
}
@@ -271,46 +271,46 @@ namespace hex::plugin::builtin {
}
void GDBProvider::close() {
this->m_socket.disconnect();
m_socket.disconnect();
if (this->m_cacheUpdateThread.joinable()) {
this->m_cacheUpdateThread.join();
if (m_cacheUpdateThread.joinable()) {
m_cacheUpdateThread.join();
}
}
bool GDBProvider::isConnected() const {
return this->m_socket.isConnected();
return m_socket.isConnected();
}
bool GDBProvider::drawLoadInterface() {
ImGui::InputText("hex.builtin.provider.gdb.ip"_lang, this->m_ipAddress);
ImGui::InputInt("hex.builtin.provider.gdb.port"_lang, &this->m_port, 0, 0);
ImGui::InputText("hex.builtin.provider.gdb.ip"_lang, m_ipAddress);
ImGui::InputInt("hex.builtin.provider.gdb.port"_lang, &m_port, 0, 0);
ImGui::Separator();
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &this->m_size, ImGuiInputTextFlags_CharsHexadecimal);
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &m_size, ImGuiInputTextFlags_CharsHexadecimal);
if (this->m_port < 0)
this->m_port = 0;
else if (this->m_port > 0xFFFF)
this->m_port = 0xFFFF;
if (m_port < 0)
m_port = 0;
else if (m_port > 0xFFFF)
m_port = 0xFFFF;
return !this->m_ipAddress.empty() && this->m_port != 0;
return !m_ipAddress.empty() && m_port != 0;
}
void GDBProvider::loadSettings(const nlohmann::json &settings) {
Provider::loadSettings(settings);
this->m_ipAddress = settings.at("ip").get<std::string>();
this->m_port = settings.at("port").get<int>();
this->m_size = settings.at("size").get<size_t>();
m_ipAddress = settings.at("ip").get<std::string>();
m_port = settings.at("port").get<int>();
m_size = settings.at("size").get<size_t>();
}
nlohmann::json GDBProvider::storeSettings(nlohmann::json settings) const {
settings["ip"] = this->m_ipAddress;
settings["port"] = this->m_port;
settings["size"] = this->m_size;
settings["ip"] = m_ipAddress;
settings["port"] = m_port;
settings["size"] = m_size;
return Provider::storeSettings(settings);
}
@@ -326,9 +326,9 @@ namespace hex::plugin::builtin {
std::variant<std::string, i128> GDBProvider::queryInformation(const std::string &category, const std::string &argument) {
if (category == "ip")
return this->m_ipAddress;
return m_ipAddress;
else if (category == "port")
return this->m_port;
return m_port;
else
return Provider::queryInformation(category, argument);
}

View File

@@ -160,19 +160,19 @@ namespace hex::plugin::builtin {
void IntelHexProvider::setBaseAddress(u64 address) {
auto oldBase = this->getBaseAddress();
auto regions = this->m_data.overlapping({ oldBase, oldBase + this->getActualSize() });
auto regions = m_data.overlapping({ oldBase, oldBase + this->getActualSize() });
decltype(this->m_data) newIntervals;
decltype(m_data) newIntervals;
for (auto &[interval, data] : regions) {
newIntervals.insert({ interval.start - oldBase + address, interval.end - oldBase + address }, *data);
}
this->m_data = newIntervals;
m_data = newIntervals;
Provider::setBaseAddress(address);
}
void IntelHexProvider::readRaw(u64 offset, void *buffer, size_t size) {
auto intervals = this->m_data.overlapping({ offset, (offset + size) - 1 });
auto intervals = m_data.overlapping({ offset, (offset + size) - 1 });
std::memset(buffer, 0x00, size);
auto bytes = static_cast<u8*>(buffer);
@@ -188,11 +188,11 @@ namespace hex::plugin::builtin {
}
u64 IntelHexProvider::getActualSize() const {
return this->m_dataSize;
return m_dataSize;
}
bool IntelHexProvider::open() {
auto file = wolv::io::File(this->m_sourceFilePath, wolv::io::File::Mode::Read);
auto file = wolv::io::File(m_sourceFilePath, wolv::io::File::Mode::Read);
if (!file.isValid())
return false;
@@ -203,14 +203,14 @@ namespace hex::plugin::builtin {
u64 maxAddress = 0x00;
for (auto &[address, bytes] : data) {
auto endAddress = (address + bytes.size()) - 1;
this->m_data.emplace({ address, endAddress }, std::move(bytes));
m_data.emplace({ address, endAddress }, std::move(bytes));
if (endAddress > maxAddress)
maxAddress = endAddress;
}
this->m_dataSize = maxAddress + 1;
this->m_dataValid = true;
m_dataSize = maxAddress + 1;
m_dataValid = true;
return true;
}
@@ -220,13 +220,13 @@ namespace hex::plugin::builtin {
}
[[nodiscard]] std::string IntelHexProvider::getName() const {
return hex::format("hex.builtin.provider.intel_hex.name"_lang, wolv::util::toUTF8String(this->m_sourceFilePath.filename()));
return hex::format("hex.builtin.provider.intel_hex.name"_lang, wolv::util::toUTF8String(m_sourceFilePath.filename()));
}
[[nodiscard]] std::vector<IntelHexProvider::Description> IntelHexProvider::getDataDescription() const {
std::vector<Description> result;
result.emplace_back("hex.builtin.provider.file.path"_lang, wolv::util::toUTF8String(this->m_sourceFilePath));
result.emplace_back("hex.builtin.provider.file.path"_lang, wolv::util::toUTF8String(m_sourceFilePath));
result.emplace_back("hex.builtin.provider.file.size"_lang, hex::toByteString(this->getActualSize()));
return result;
@@ -247,25 +247,25 @@ namespace hex::plugin::builtin {
{ "Intel Hex File", "a43" },
{ "Intel Hex File", "a90" }
}, [this](const std::fs::path &path) {
this->m_sourceFilePath = path;
m_sourceFilePath = path;
}
);
if (!picked)
return false;
if (!wolv::io::fs::isRegularFile(this->m_sourceFilePath))
if (!wolv::io::fs::isRegularFile(m_sourceFilePath))
return false;
return true;
}
std::pair<Region, bool> IntelHexProvider::getRegionValidity(u64 address) const {
auto intervals = this->m_data.overlapping({ address, address });
auto intervals = m_data.overlapping({ address, address });
if (intervals.empty()) {
return Provider::getRegionValidity(address);
}
decltype(this->m_data)::Interval closestInterval = { 0, 0 };
decltype(m_data)::Interval closestInterval = { 0, 0 };
for (const auto &[interval, data] : intervals) {
if (interval.start <= closestInterval.end)
closestInterval = interval;
@@ -278,11 +278,11 @@ namespace hex::plugin::builtin {
Provider::loadSettings(settings);
auto path = settings.at("path").get<std::string>();
this->m_sourceFilePath = std::u8string(path.begin(), path.end());
m_sourceFilePath = std::u8string(path.begin(), path.end());
}
nlohmann::json IntelHexProvider::storeSettings(nlohmann::json settings) const {
settings["path"] = wolv::util::toUTF8String(this->m_sourceFilePath);
settings["path"] = wolv::util::toUTF8String(m_sourceFilePath);
return Provider::storeSettings(settings);
}

View File

@@ -15,8 +15,8 @@
namespace hex::plugin::builtin {
bool MemoryFileProvider::open() {
if (this->m_data.empty()) {
this->m_data.resize(1);
if (m_data.empty()) {
m_data.resize(1);
this->markDirty();
}
@@ -28,18 +28,18 @@ namespace hex::plugin::builtin {
if (actualSize == 0 || (offset + size) > actualSize || buffer == nullptr || size == 0)
return;
std::memcpy(buffer, &this->m_data.front() + offset, size);
std::memcpy(buffer, &m_data.front() + offset, size);
}
void MemoryFileProvider::writeRaw(u64 offset, const void *buffer, size_t size) {
if ((offset + size) > this->getActualSize() || buffer == nullptr || size == 0)
return;
std::memcpy(&this->m_data.front() + offset, buffer, size);
std::memcpy(&m_data.front() + offset, buffer, size);
}
void MemoryFileProvider::save() {
if (!this->m_name.empty())
if (!m_name.empty())
return;
fs::openFileBrowser(fs::DialogMode::Save, { }, [this](const std::fs::path &path) {
@@ -67,7 +67,7 @@ namespace hex::plugin::builtin {
}
void MemoryFileProvider::resizeRaw(u64 newSize) {
this->m_data.resize(newSize);
m_data.resize(newSize);
}
void MemoryFileProvider::insertRaw(u64 offset, u64 size) {
@@ -108,10 +108,10 @@ namespace hex::plugin::builtin {
}
[[nodiscard]] std::string MemoryFileProvider::getName() const {
if (this->m_name.empty())
if (m_name.empty())
return Lang("hex.builtin.provider.mem_file.unsaved");
else
return this->m_name;
return m_name;
}
std::vector<MemoryFileProvider::MenuEntry> MemoryFileProvider::getMenuEntries() {
@@ -132,22 +132,22 @@ namespace hex::plugin::builtin {
void MemoryFileProvider::loadSettings(const nlohmann::json &settings) {
Provider::loadSettings(settings);
this->m_data = settings["data"].get<std::vector<u8>>();
this->m_name = settings["name"].get<std::string>();
this->m_readOnly = settings["readOnly"].get<bool>();
m_data = settings["data"].get<std::vector<u8>>();
m_name = settings["name"].get<std::string>();
m_readOnly = settings["readOnly"].get<bool>();
}
[[nodiscard]] nlohmann::json MemoryFileProvider::storeSettings(nlohmann::json settings) const {
settings["data"] = this->m_data;
settings["name"] = this->m_name;
settings["readOnly"] = this->m_readOnly;
settings["data"] = m_data;
settings["name"] = m_name;
settings["readOnly"] = m_readOnly;
return Provider::storeSettings(settings);
}
void MemoryFileProvider::renameFile() {
PopupTextInput::open("hex.builtin.provider.mem_file.rename", "hex.builtin.provider.mem_file.rename.desc", [this](const std::string &name) {
this->m_name = name;
m_name = name;
RequestUpdateWindowTitle::post();
});
}

View File

@@ -171,7 +171,7 @@ namespace hex::plugin::builtin {
}
bool MotorolaSRECProvider::open() {
auto file = wolv::io::File(this->m_sourceFilePath, wolv::io::File::Mode::Read);
auto file = wolv::io::File(m_sourceFilePath, wolv::io::File::Mode::Read);
if (!file.isValid())
return false;
@@ -182,14 +182,14 @@ namespace hex::plugin::builtin {
u64 maxAddress = 0x00;
for (auto &[address, bytes] : data) {
auto endAddress = (address + bytes.size()) - 1;
this->m_data.emplace({ address, endAddress }, std::move(bytes));
m_data.emplace({ address, endAddress }, std::move(bytes));
if (endAddress > maxAddress)
maxAddress = endAddress;
}
this->m_dataSize = maxAddress + 1;
this->m_dataValid = true;
m_dataSize = maxAddress + 1;
m_dataValid = true;
return true;
}
@@ -199,14 +199,14 @@ namespace hex::plugin::builtin {
}
[[nodiscard]] std::string MotorolaSRECProvider::getName() const {
return hex::format("hex.builtin.provider.motorola_srec.name"_lang, wolv::util::toUTF8String(this->m_sourceFilePath.filename()));
return hex::format("hex.builtin.provider.motorola_srec.name"_lang, wolv::util::toUTF8String(m_sourceFilePath.filename()));
}
[[nodiscard]] std::vector<MotorolaSRECProvider::Description> MotorolaSRECProvider::getDataDescription() const {
std::vector<Description> result;
result.emplace_back("hex.builtin.provider.file.path"_lang, wolv::util::toUTF8String(this->m_sourceFilePath));
result.emplace_back("hex.builtin.provider.file.path"_lang, wolv::util::toUTF8String(m_sourceFilePath));
result.emplace_back("hex.builtin.provider.file.size"_lang, hex::toByteString(this->getActualSize()));
return result;
@@ -228,13 +228,13 @@ namespace hex::plugin::builtin {
{ "Motorola SREC File", "mxt" }
},
[this](const std::fs::path &path) {
this->m_sourceFilePath = path;
m_sourceFilePath = path;
}
);
if (!picked)
return false;
if (!wolv::io::fs::isRegularFile(this->m_sourceFilePath))
if (!wolv::io::fs::isRegularFile(m_sourceFilePath))
return false;
return true;

View File

@@ -24,11 +24,11 @@ namespace hex::plugin::builtin {
bool ProcessMemoryProvider::open() {
#if defined(OS_WINDOWS)
this->m_processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, this->m_selectedProcess->id);
if (this->m_processHandle == nullptr)
m_processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_selectedProcess->id);
if (m_processHandle == nullptr)
return false;
#elif defined(OS_LINUX)
this->m_processId = pid_t(this->m_selectedProcess->id);
m_processId = pid_t(m_selectedProcess->id);
#endif
this->reloadProcessModules();
@@ -38,16 +38,16 @@ namespace hex::plugin::builtin {
void ProcessMemoryProvider::close() {
#if defined(OS_WINDOWS)
CloseHandle(this->m_processHandle);
this->m_processHandle = nullptr;
CloseHandle(m_processHandle);
m_processHandle = nullptr;
#elif defined(OS_LINUX)
this->m_processId = -1;
m_processId = -1;
#endif
}
void ProcessMemoryProvider::readRaw(u64 address, void *buffer, size_t size) {
#if defined(OS_WINDOWS)
ReadProcessMemory(this->m_processHandle, reinterpret_cast<LPCVOID>(address), buffer, size, nullptr);
ReadProcessMemory(m_processHandle, reinterpret_cast<LPCVOID>(address), buffer, size, nullptr);
#elif defined(OS_LINUX)
const iovec local {
.iov_base = buffer,
@@ -58,7 +58,7 @@ namespace hex::plugin::builtin {
.iov_len = size,
};
auto read = process_vm_readv(this->m_processId, &local, 1, &remote, 1, 0);
auto read = process_vm_readv(m_processId, &local, 1, &remote, 1, 0);
if (read == -1) {
// TODO error handling strerror(errno)
@@ -67,7 +67,7 @@ namespace hex::plugin::builtin {
}
void ProcessMemoryProvider::writeRaw(u64 address, const void *buffer, size_t size) {
#if defined(OS_WINDOWS)
WriteProcessMemory(this->m_processHandle, reinterpret_cast<LPVOID>(address), buffer, size, nullptr);
WriteProcessMemory(m_processHandle, reinterpret_cast<LPVOID>(address), buffer, size, nullptr);
#elif defined(OS_LINUX)
const iovec local {
.iov_base = const_cast<void*>(buffer),
@@ -78,7 +78,7 @@ namespace hex::plugin::builtin {
.iov_len = size,
};
auto read = process_vm_writev(this->m_processId, &local, 1, &remote, 1, 0);
auto read = process_vm_writev(m_processId, &local, 1, &remote, 1, 0);
if (read == -1) {
// TODO error handling strerror(errno)
}
@@ -86,13 +86,13 @@ namespace hex::plugin::builtin {
}
std::pair<Region, bool> ProcessMemoryProvider::getRegionValidity(u64 address) const {
for (const auto &memoryRegion : this->m_memoryRegions) {
for (const auto &memoryRegion : m_memoryRegions) {
if (memoryRegion.region.overlaps({ address, 1 }))
return { memoryRegion.region, true };
}
Region lastRegion = Region::Invalid();
for (const auto &memoryRegion : this->m_memoryRegions) {
for (const auto &memoryRegion : m_memoryRegions) {
if (address < memoryRegion.region.getStartAddress())
return { Region { lastRegion.getEndAddress() + 1, memoryRegion.region.getStartAddress() - lastRegion.getEndAddress() }, false };
@@ -104,7 +104,7 @@ namespace hex::plugin::builtin {
}
bool ProcessMemoryProvider::drawLoadInterface() {
if (this->m_processes.empty() && !this->m_enumerationFailed) {
if (m_processes.empty() && !m_enumerationFailed) {
#if defined(OS_WINDOWS)
DWORD numProcesses = 0;
std::vector<DWORD> processIds;
@@ -113,7 +113,7 @@ namespace hex::plugin::builtin {
processIds.resize(processIds.size() + 1024);
if (EnumProcesses(processIds.data(), processIds.size() * sizeof(DWORD), &numProcesses) == FALSE) {
processIds.clear();
this->m_enumerationFailed = true;
m_enumerationFailed = true;
break;
}
} while (numProcesses == processIds.size() * sizeof(DWORD));
@@ -172,7 +172,7 @@ namespace hex::plugin::builtin {
}
}
this->m_processes.push_back({ u32(processId), processName, std::move(texture) });
m_processes.push_back({ u32(processId), processName, std::move(texture) });
}
#elif defined(OS_LINUX)
for (const auto& entry : std::fs::directory_iterator("/proc")) {
@@ -192,16 +192,16 @@ namespace hex::plugin::builtin {
std::string processName = file.readString(0xF'FFFF);
this->m_processes.emplace_back(processId, processName, ImGuiExt::Texture());
m_processes.emplace_back(processId, processName, ImGuiExt::Texture());
}
#endif
}
if (this->m_enumerationFailed) {
if (m_enumerationFailed) {
ImGui::TextUnformatted("hex.builtin.provider.process_memory.enumeration_failed"_lang);
} else {
ImGui::PushItemWidth(500_scaled);
const auto &filtered = this->m_processSearchWidget.draw(this->m_processes);
const auto &filtered = m_processSearchWidget.draw(m_processes);
ImGui::PopItemWidth();
if (ImGui::BeginTable("##process_table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY, ImVec2(500_scaled, 500_scaled))) {
ImGui::TableSetupColumn("##icon");
@@ -222,8 +222,8 @@ namespace hex::plugin::builtin {
ImGui::Text("%d", process->id);
ImGui::TableNextColumn();
if (ImGui::Selectable(process->name.c_str(), this->m_selectedProcess != nullptr && process->id == this->m_selectedProcess->id, ImGuiSelectableFlags_SpanAllColumns, ImVec2(0, process->icon.getSize().y)))
this->m_selectedProcess = process;
if (ImGui::Selectable(process->name.c_str(), m_selectedProcess != nullptr && process->id == m_selectedProcess->id, ImGuiSelectableFlags_SpanAllColumns, ImVec2(0, process->icon.getSize().y)))
m_selectedProcess = process;
ImGui::PopID();
}
@@ -233,7 +233,7 @@ namespace hex::plugin::builtin {
}
return this->m_selectedProcess != nullptr;
return m_selectedProcess != nullptr;
}
void ProcessMemoryProvider::drawInterface() {
@@ -241,7 +241,7 @@ namespace hex::plugin::builtin {
auto availableX = ImGui::GetContentRegionAvail().x;
ImGui::PushItemWidth(availableX);
const auto &filtered = this->m_regionSearchWidget.draw(this->m_memoryRegions);
const auto &filtered = m_regionSearchWidget.draw(m_memoryRegions);
ImGui::PopItemWidth();
#if defined(OS_WINDOWS)
@@ -288,11 +288,11 @@ namespace hex::plugin::builtin {
const auto &dllPath = path.native();
const auto dllPathLength = (dllPath.length() + 1) * sizeof(std::fs::path::value_type);
if (auto pathAddress = VirtualAllocEx(this->m_processHandle, nullptr, dllPathLength, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); pathAddress != nullptr) {
if (WriteProcessMemory(this->m_processHandle, pathAddress, dllPath.c_str(), dllPathLength, nullptr) != FALSE) {
if (auto pathAddress = VirtualAllocEx(m_processHandle, nullptr, dllPathLength, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); pathAddress != nullptr) {
if (WriteProcessMemory(m_processHandle, pathAddress, dllPath.c_str(), dllPathLength, nullptr) != FALSE) {
auto loadLibraryW = reinterpret_cast<LPTHREAD_START_ROUTINE>(reinterpret_cast<void*>(GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryW")));
if (loadLibraryW != nullptr) {
if (auto threadHandle = CreateRemoteThread(this->m_processHandle, nullptr, 0, loadLibraryW, pathAddress, 0, nullptr); threadHandle != nullptr) {
if (auto threadHandle = CreateRemoteThread(m_processHandle, nullptr, 0, loadLibraryW, pathAddress, 0, nullptr); threadHandle != nullptr) {
WaitForSingleObject(threadHandle, INFINITE);
RequestOpenErrorPopup::post(hex::format("hex.builtin.provider.process_memory.utils.inject_dll.success"_lang, path.filename().string()));
this->reloadProcessModules();
@@ -310,7 +310,7 @@ namespace hex::plugin::builtin {
}
void ProcessMemoryProvider::reloadProcessModules() {
this->m_memoryRegions.clear();
m_memoryRegions.clear();
#if defined(OS_WINDOWS)
DWORD numModules = 0;
@@ -318,7 +318,7 @@ namespace hex::plugin::builtin {
do {
modules.resize(modules.size() + 1024);
if (EnumProcessModules(this->m_processHandle, modules.data(), modules.size() * sizeof(HMODULE), &numModules) == FALSE) {
if (EnumProcessModules(m_processHandle, modules.data(), modules.size() * sizeof(HMODULE), &numModules) == FALSE) {
modules.clear();
break;
}
@@ -328,19 +328,19 @@ namespace hex::plugin::builtin {
for (auto &module : modules) {
MODULEINFO moduleInfo;
if (GetModuleInformation(this->m_processHandle, module, &moduleInfo, sizeof(MODULEINFO)) == FALSE)
if (GetModuleInformation(m_processHandle, module, &moduleInfo, sizeof(MODULEINFO)) == FALSE)
continue;
char moduleName[MAX_PATH];
if (GetModuleFileNameExA(this->m_processHandle, module, moduleName, MAX_PATH) == FALSE)
if (GetModuleFileNameExA(m_processHandle, module, moduleName, MAX_PATH) == FALSE)
continue;
this->m_memoryRegions.insert({ { u64(moduleInfo.lpBaseOfDll), size_t(moduleInfo.SizeOfImage) }, std::fs::path(moduleName).filename().string() });
m_memoryRegions.insert({ { u64(moduleInfo.lpBaseOfDll), size_t(moduleInfo.SizeOfImage) }, std::fs::path(moduleName).filename().string() });
}
MEMORY_BASIC_INFORMATION memoryInfo;
for (u64 address = 0; address < this->getActualSize(); address += memoryInfo.RegionSize) {
if (VirtualQueryEx(this->m_processHandle, reinterpret_cast<LPCVOID>(address), &memoryInfo, sizeof(MEMORY_BASIC_INFORMATION)) == 0)
if (VirtualQueryEx(m_processHandle, reinterpret_cast<LPCVOID>(address), &memoryInfo, sizeof(MEMORY_BASIC_INFORMATION)) == 0)
break;
std::string name;
@@ -351,12 +351,12 @@ namespace hex::plugin::builtin {
if (memoryInfo.State & MEM_PRIVATE) name += hex::format("{} ", "hex.builtin.provider.process_memory.region.private"_lang);
if (memoryInfo.State & MEM_MAPPED) name += hex::format("{} ", "hex.builtin.provider.process_memory.region.mapped"_lang);
this->m_memoryRegions.insert({ { reinterpret_cast<u64>(memoryInfo.BaseAddress), reinterpret_cast<u64>(memoryInfo.BaseAddress) + memoryInfo.RegionSize }, name });
m_memoryRegions.insert({ { reinterpret_cast<u64>(memoryInfo.BaseAddress), reinterpret_cast<u64>(memoryInfo.BaseAddress) + memoryInfo.RegionSize }, name });
}
#elif defined(OS_LINUX)
wolv::io::File file(std::fs::path("/proc") / std::to_string(this->m_processId) / "maps", wolv::io::File::Mode::Read);
wolv::io::File file(std::fs::path("/proc") / std::to_string(m_processId) / "maps", wolv::io::File::Mode::Read);
if (!file.isValid())
return;
@@ -370,7 +370,7 @@ namespace hex::plugin::builtin {
const u64 end = std::stoull(split[0].substr(split[0].find('-') + 1), nullptr, 16);
const auto &name = split[5];
this->m_memoryRegions.insert({ { start, end - start }, name });
m_memoryRegions.insert({ { start, end - start }, name });
}
#endif
}
@@ -378,26 +378,26 @@ namespace hex::plugin::builtin {
std::variant<std::string, i128> ProcessMemoryProvider::queryInformation(const std::string &category, const std::string &argument) {
auto findRegionByName = [this](const std::string &name) {
return std::find_if(this->m_memoryRegions.begin(), this->m_memoryRegions.end(),
return std::find_if(m_memoryRegions.begin(), m_memoryRegions.end(),
[name](const auto &region) {
return region.name == name;
});
};
if (category == "region_address") {
if (auto iter = findRegionByName(argument); iter != this->m_memoryRegions.end())
if (auto iter = findRegionByName(argument); iter != m_memoryRegions.end())
return iter->region.getStartAddress();
else
return 0;
} else if (category == "region_size") {
if (auto iter = findRegionByName(argument); iter != this->m_memoryRegions.end())
if (auto iter = findRegionByName(argument); iter != m_memoryRegions.end())
return iter->region.getSize();
else
return 0;
} else if (category == "process_id") {
return this->m_selectedProcess->id;
return m_selectedProcess->id;
} else if (category == "process_name") {
return this->m_selectedProcess->name;
return m_selectedProcess->name;
} else
return Provider::queryInformation(category, argument);
}

View File

@@ -43,7 +43,7 @@ namespace hex::plugin::builtin::recent {
if (entry.is_regular_file() && entry.path().extension() == ".hexproj") {
wolv::io::File backupFile(entry.path(), wolv::io::File::Mode::Read);
this->m_backups.emplace_back(
m_backups.emplace_back(
hex::format("hex.builtin.welcome.start.recent.auto_backups.backup"_lang, fmt::gmtime(backupFile.getFileInfo()->st_ctime)),
entry.path()
);
@@ -54,7 +54,7 @@ namespace hex::plugin::builtin::recent {
void drawContent() override {
if (ImGui::BeginTable("AutoBackups", 1, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersInnerV, ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 5))) {
for (const auto &backup : this->m_backups | std::views::reverse | std::views::take(10)) {
for (const auto &backup : m_backups | std::views::reverse | std::views::take(10)) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::Selectable(backup.displayName.c_str())) {

View File

@@ -31,10 +31,10 @@ namespace hex::plugin::builtin {
class ServerContactWidget : public ContentRegistry::Settings::Widgets::Widget {
public:
bool draw(const std::string &name) override {
bool enabled = this->m_value == 1;
bool enabled = m_value == 1;
if (ImGui::Checkbox(name.data(), &enabled)) {
this->m_value = enabled ? 1 : 0;
m_value = enabled ? 1 : 0;
return true;
}
@@ -43,11 +43,11 @@ namespace hex::plugin::builtin {
void load(const nlohmann::json &data) override {
if (data.is_number())
this->m_value = data.get<int>();
m_value = data.get<int>();
}
nlohmann::json store() override {
return this->m_value;
return m_value;
}
private:
@@ -58,15 +58,15 @@ namespace hex::plugin::builtin {
public:
bool draw(const std::string &name) override {
auto format = [this] -> std::string {
if (this->m_value > 200)
if (m_value > 200)
return "hex.builtin.setting.interface.fps.unlocked"_lang;
else if (this->m_value < 15)
else if (m_value < 15)
return "hex.builtin.setting.interface.fps.native"_lang;
else
return "%d FPS";
}();
if (ImGui::SliderInt(name.data(), &this->m_value, 14, 201, format.c_str(), ImGuiSliderFlags_AlwaysClamp)) {
if (ImGui::SliderInt(name.data(), &m_value, 14, 201, format.c_str(), ImGuiSliderFlags_AlwaysClamp)) {
return true;
}
@@ -75,11 +75,11 @@ namespace hex::plugin::builtin {
void load(const nlohmann::json &data) override {
if (data.is_number())
this->m_value = data.get<int>();
m_value = data.get<int>();
}
nlohmann::json store() override {
return this->m_value;
return m_value;
}
private:
@@ -94,10 +94,10 @@ namespace hex::plugin::builtin {
if (!ImGui::BeginListBox("", ImVec2(-40_scaled, 280_scaled))) {
return false;
} else {
for (size_t n = 0; n < this->m_paths.size(); n++) {
const bool isSelected = (this->m_itemIndex == n);
if (ImGui::Selectable(wolv::util::toUTF8String(this->m_paths[n]).c_str(), isSelected)) {
this->m_itemIndex = n;
for (size_t n = 0; n < m_paths.size(); n++) {
const bool isSelected = (m_itemIndex == n);
if (ImGui::Selectable(wolv::util::toUTF8String(m_paths[n]).c_str(), isSelected)) {
m_itemIndex = n;
}
if (isSelected) {
@@ -111,9 +111,9 @@ namespace hex::plugin::builtin {
if (ImGuiExt::IconButton(ICON_VS_NEW_FOLDER, ImGui::GetStyleColorVec4(ImGuiCol_Text), ImVec2(30, 30))) {
fs::openFileBrowser(fs::DialogMode::Folder, {}, [&](const std::fs::path &path) {
if (std::find(this->m_paths.begin(), this->m_paths.end(), path) == this->m_paths.end()) {
this->m_paths.emplace_back(path);
ImHexApi::System::setAdditionalFolderPaths(this->m_paths);
if (std::find(m_paths.begin(), m_paths.end(), path) == m_paths.end()) {
m_paths.emplace_back(path);
ImHexApi::System::setAdditionalFolderPaths(m_paths);
result = true;
}
@@ -122,9 +122,9 @@ namespace hex::plugin::builtin {
ImGuiExt::InfoTooltip("hex.builtin.setting.folders.add_folder"_lang);
if (ImGuiExt::IconButton(ICON_VS_REMOVE_CLOSE, ImGui::GetStyleColorVec4(ImGuiCol_Text), ImVec2(30, 30))) {
if (!this->m_paths.empty()) {
this->m_paths.erase(std::next(this->m_paths.begin(), this->m_itemIndex));
ImHexApi::System::setAdditionalFolderPaths(this->m_paths);
if (!m_paths.empty()) {
m_paths.erase(std::next(m_paths.begin(), m_itemIndex));
ImHexApi::System::setAdditionalFolderPaths(m_paths);
result = true;
}
@@ -141,7 +141,7 @@ namespace hex::plugin::builtin {
std::vector<std::string> pathStrings = data;
for (const auto &pathString : pathStrings) {
this->m_paths.emplace_back(pathString);
m_paths.emplace_back(pathString);
}
}
}
@@ -149,7 +149,7 @@ namespace hex::plugin::builtin {
nlohmann::json store() override {
std::vector<std::string> pathStrings;
for (const auto &path : this->m_paths) {
for (const auto &path : m_paths) {
pathStrings.push_back(wolv::util::toUTF8String(path));
}
@@ -165,13 +165,13 @@ namespace hex::plugin::builtin {
public:
bool draw(const std::string &name) override {
auto format = [this] -> std::string {
if (this->m_value == 0)
if (m_value == 0)
return "hex.builtin.setting.interface.scaling.native"_lang;
else
return "x%.1f";
}();
if (ImGui::SliderFloat(name.data(), &this->m_value, 0, 10, format.c_str(), ImGuiSliderFlags_AlwaysClamp)) {
if (ImGui::SliderFloat(name.data(), &m_value, 0, 10, format.c_str(), ImGuiSliderFlags_AlwaysClamp)) {
return true;
}
@@ -180,11 +180,11 @@ namespace hex::plugin::builtin {
void load(const nlohmann::json &data) override {
if (data.is_number())
this->m_value = data.get<float>();
m_value = data.get<float>();
}
nlohmann::json store() override {
return this->m_value;
return m_value;
}
private:
@@ -195,7 +195,7 @@ namespace hex::plugin::builtin {
public:
bool draw(const std::string &name) override {
auto format = [this] -> std::string {
auto value = this->m_value * 30;
auto value = m_value * 30;
if (value == 0)
return "hex.builtin.common.off"_lang;
else if (value < 60)
@@ -204,7 +204,7 @@ namespace hex::plugin::builtin {
return hex::format("hex.builtin.setting.general.auto_backup_time.format.extended"_lang, value / 60, value % 60);
}();
if (ImGui::SliderInt(name.data(), &this->m_value, 0, (30 * 60) / 30, format.c_str(), ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_NoInput)) {
if (ImGui::SliderInt(name.data(), &m_value, 0, (30 * 60) / 30, format.c_str(), ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_NoInput)) {
return true;
}
@@ -213,11 +213,11 @@ namespace hex::plugin::builtin {
void load(const nlohmann::json &data) override {
if (data.is_number())
this->m_value = data.get<int>();
m_value = data.get<int>();
}
nlohmann::json store() override {
return this->m_value;
return m_value;
}
private:
@@ -231,8 +231,8 @@ namespace hex::plugin::builtin {
bool draw(const std::string &name) override {
std::string label;
if (!this->m_editing)
label = this->m_drawShortcut.toString();
if (!m_editing)
label = m_drawShortcut.toString();
else
label = "...";
@@ -240,14 +240,14 @@ namespace hex::plugin::builtin {
label = "???";
if (this->m_hasDuplicate)
if (m_hasDuplicate)
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_LoggerError));
ImGui::PushID(this);
if (ImGui::Button(label.c_str(), ImVec2(250_scaled, 0))) {
this->m_editing = !this->m_editing;
m_editing = !m_editing;
if (this->m_editing)
if (m_editing)
ShortcutManager::pauseShortcuts();
else
ShortcutManager::resumeShortcuts();
@@ -255,18 +255,18 @@ namespace hex::plugin::builtin {
ImGui::SameLine();
if (this->m_hasDuplicate)
if (m_hasDuplicate)
ImGui::PopStyleColor();
bool settingChanged = false;
ImGui::BeginDisabled(this->m_drawShortcut == this->m_defaultShortcut);
ImGui::BeginDisabled(m_drawShortcut == m_defaultShortcut);
if (ImGuiExt::IconButton(ICON_VS_X, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
this->m_hasDuplicate = !ShortcutManager::updateShortcut(this->m_shortcut, this->m_defaultShortcut, this->m_view);
m_hasDuplicate = !ShortcutManager::updateShortcut(m_shortcut, m_defaultShortcut, m_view);
this->m_drawShortcut = this->m_defaultShortcut;
if (!this->m_hasDuplicate) {
this->m_shortcut = this->m_defaultShortcut;
m_drawShortcut = m_defaultShortcut;
if (!m_hasDuplicate) {
m_shortcut = m_defaultShortcut;
settingChanged = true;
}
@@ -274,7 +274,7 @@ namespace hex::plugin::builtin {
ImGui::EndDisabled();
if (!ImGui::IsItemHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
this->m_editing = false;
m_editing = false;
ShortcutManager::resumeShortcuts();
}
@@ -284,13 +284,13 @@ namespace hex::plugin::builtin {
ImGui::PopID();
if (this->m_editing) {
if (m_editing) {
if (this->detectShortcut()) {
this->m_editing = false;
m_editing = false;
ShortcutManager::resumeShortcuts();
settingChanged = true;
if (!this->m_hasDuplicate) {
if (!m_hasDuplicate) {
}
}
}
@@ -308,15 +308,15 @@ namespace hex::plugin::builtin {
return;
auto newShortcut = Shortcut(keys);
this->m_hasDuplicate = !ShortcutManager::updateShortcut(this->m_shortcut, newShortcut, this->m_view);
this->m_shortcut = std::move(newShortcut);
this->m_drawShortcut = this->m_shortcut;
m_hasDuplicate = !ShortcutManager::updateShortcut(m_shortcut, newShortcut, m_view);
m_shortcut = std::move(newShortcut);
m_drawShortcut = m_shortcut;
}
nlohmann::json store() override {
std::vector<u32> keys;
for (const auto &key : this->m_shortcut.getKeys()) {
for (const auto &key : m_shortcut.getKeys()) {
if (key != CurrentView)
keys.push_back(key.getKeyCode());
}
@@ -327,7 +327,7 @@ namespace hex::plugin::builtin {
private:
bool detectShortcut() {
if (const auto &shortcut = ShortcutManager::getPreviousShortcut(); shortcut.has_value()) {
auto keys = this->m_shortcut.getKeys();
auto keys = m_shortcut.getKeys();
std::erase_if(keys, [](Key key) {
return key != AllowWhileTyping && key != CurrentView;
});
@@ -337,11 +337,11 @@ namespace hex::plugin::builtin {
}
auto newShortcut = Shortcut(std::move(keys));
this->m_hasDuplicate = !ShortcutManager::updateShortcut(this->m_shortcut, newShortcut, this->m_view);
this->m_drawShortcut = std::move(newShortcut);
m_hasDuplicate = !ShortcutManager::updateShortcut(m_shortcut, newShortcut, m_view);
m_drawShortcut = std::move(newShortcut);
if (!this->m_hasDuplicate) {
this->m_shortcut = this->m_drawShortcut;
if (!m_hasDuplicate) {
m_shortcut = m_drawShortcut;
log::info("Changed shortcut to {}", shortcut->toString());
} else {
log::warn("Changing shortcut failed as it overlapped with another one", shortcut->toString());

View File

@@ -100,18 +100,18 @@ namespace hex::plugin::builtin {
ImGui::TableNextColumn();
// Draw the ImHex icon
if (!this->m_logoTexture.isValid())
this->m_logoTexture = ImGuiExt::Texture(romfs::get("assets/common/logo.png").span(), ImGuiExt::Texture::Filter::Linear);
if (!m_logoTexture.isValid())
m_logoTexture = ImGuiExt::Texture(romfs::get("assets/common/logo.png").span(), ImGuiExt::Texture::Filter::Linear);
ImGui::Image(this->m_logoTexture, scaled({ 100, 100 }));
ImGui::Image(m_logoTexture, scaled({ 100, 100 }));
if (ImGui::IsItemClicked()) {
this->m_clickCount += 1;
m_clickCount += 1;
}
if (this->m_clickCount >= (2 * 3 + 4)) {
if (m_clickCount >= (2 * 3 + 4)) {
this->getWindowOpenState() = false;
PopupEE::open();
this->m_clickCount = 0;
m_clickCount = 0;
}
ImGui::TableNextColumn();
@@ -451,13 +451,13 @@ namespace hex::plugin::builtin {
AT_FIRST_TIME {
static HttpRequest request("GET", GitHubApiURL + std::string("/releases/tags/v") + ImHexApi::System::getImHexVersion(false));
this->m_releaseNoteRequest = request.execute();
m_releaseNoteRequest = request.execute();
};
// Wait for the request to finish and parse the response
if (this->m_releaseNoteRequest.valid()) {
if (this->m_releaseNoteRequest.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
auto response = this->m_releaseNoteRequest.get();
if (m_releaseNoteRequest.valid()) {
if (m_releaseNoteRequest.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
auto response = m_releaseNoteRequest.get();
nlohmann::json json;
if (response.isSuccess()) {
@@ -553,13 +553,13 @@ namespace hex::plugin::builtin {
// Set up the request to get the commit history the first time the page is opened
AT_FIRST_TIME {
static HttpRequest request("GET", GitHubApiURL + std::string("/commits?per_page=100"));
this->m_commitHistoryRequest = request.execute();
m_commitHistoryRequest = request.execute();
};
// Wait for the request to finish and parse the response
if (this->m_commitHistoryRequest.valid()) {
if (this->m_commitHistoryRequest.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
auto response = this->m_commitHistoryRequest.get();
if (m_commitHistoryRequest.valid()) {
if (m_commitHistoryRequest.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
auto response = m_commitHistoryRequest.get();
nlohmann::json json;
if (response.isSuccess()) {

View File

@@ -17,7 +17,7 @@ namespace hex::plugin::builtin {
// Add newly unlocked achievements to the display queue
EventAchievementUnlocked::subscribe(this, [this](const Achievement &achievement) {
this->m_achievementUnlockQueue.push_back(&achievement);
m_achievementUnlockQueue.push_back(&achievement);
});
RequestOpenWindow::subscribe(this, [this](const std::string &name) {
@@ -29,7 +29,7 @@ namespace hex::plugin::builtin {
});
// Load settings
this->m_showPopup = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup", true);
m_showPopup = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup", true);
}
ViewAchievements::~ViewAchievements() {
@@ -273,9 +273,9 @@ namespace hex::plugin::builtin {
drawList->AddBezierQuadratic(start, middle, end, color, 2_scaled);
// Handle jumping to an achievement
if (this->m_achievementToGoto != nullptr) {
if (this->m_achievementToGoto == node->achievement) {
this->m_offset = position - scaled({ 100, 100 });
if (m_achievementToGoto != nullptr) {
if (m_achievementToGoto == node->achievement) {
m_offset = position - scaled({ 100, 100 });
}
}
}
@@ -331,8 +331,8 @@ namespace hex::plugin::builtin {
ImGuiTabItemFlags flags = ImGuiTabItemFlags_None;
// Handle jumping to the category of an achievement
if (this->m_achievementToGoto != nullptr) {
if (this->m_achievementToGoto->getUnlocalizedCategory() == categoryName) {
if (m_achievementToGoto != nullptr) {
if (m_achievementToGoto->getUnlocalizedCategory() == categoryName) {
flags |= ImGuiTabItemFlags_SetSelected;
}
}
@@ -358,10 +358,10 @@ namespace hex::plugin::builtin {
drawList->ChannelsSetCurrent(0);
// Draw achievement background
drawBackground(drawList, innerWindowPos, innerWindowPos + innerWindowSize, this->m_offset);
drawBackground(drawList, innerWindowPos, innerWindowPos + innerWindowSize, m_offset);
// Draw the achievement tree
auto maxPos = drawAchievementTree(drawList, nullptr, achievements, innerWindowPos + scaled({ 100, 100 }) + this->m_offset);
auto maxPos = drawAchievementTree(drawList, nullptr, achievements, innerWindowPos + scaled({ 100, 100 }) + m_offset);
drawList->ChannelsSetCurrent(3);
@@ -373,12 +373,12 @@ namespace hex::plugin::builtin {
// Handle dragging the achievement tree around
if (ImGui::IsMouseHoveringRect(innerWindowPos, innerWindowPos + innerWindowSize)) {
auto dragDelta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Left);
this->m_offset += dragDelta;
m_offset += dragDelta;
ImGui::ResetMouseDragDelta(ImGuiMouseButton_Left);
}
// Clamp the achievement tree to the window
this->m_offset = -ImClamp(-this->m_offset, { 0, 0 }, ImMax(maxPos - innerWindowPos - innerWindowSize, { 0, 0 }));
m_offset = -ImClamp(-m_offset, { 0, 0 }, ImMax(maxPos - innerWindowPos - innerWindowSize, { 0, 0 }));
drawList->PopClipRect();
@@ -386,8 +386,8 @@ namespace hex::plugin::builtin {
ImGui::SetCursorScreenPos(innerWindowPos + ImVec2(0, innerWindowSize.y + windowPadding.y));
ImGui::BeginGroup();
{
if (ImGui::Checkbox("Show popup", &this->m_showPopup))
ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup", this->m_showPopup);
if (ImGui::Checkbox("Show popup", &m_showPopup))
ContentRegistry::Settings::write("hex.builtin.setting.interface", "hex.builtin.setting.interface.achievement_popup", m_showPopup);
}
ImGui::EndGroup();
@@ -398,17 +398,17 @@ namespace hex::plugin::builtin {
ImGui::EndTabBar();
}
this->m_achievementToGoto = nullptr;
m_achievementToGoto = nullptr;
}
void ViewAchievements::drawAlwaysVisibleContent() {
// Handle showing the achievement unlock popup
if (this->m_achievementUnlockQueueTimer >= 0 && this->m_showPopup) {
this->m_achievementUnlockQueueTimer -= ImGui::GetIO().DeltaTime;
if (m_achievementUnlockQueueTimer >= 0 && m_showPopup) {
m_achievementUnlockQueueTimer -= ImGui::GetIO().DeltaTime;
// Check if there's an achievement that can be drawn
if (this->m_currAchievement != nullptr) {
if (m_currAchievement != nullptr) {
const ImVec2 windowSize = scaled({ 200, 55 });
ImGui::SetNextWindowPos(ImHexApi::System::getMainWindowPosition() + ImVec2 { ImHexApi::System::getMainWindowSize().x - windowSize.x - 100_scaled, 0 });
@@ -420,34 +420,34 @@ namespace hex::plugin::builtin {
ImGuiExt::TextFormattedColored(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_AchievementUnlocked), "{}", "hex.builtin.view.achievements.unlocked"_lang);
// Draw achievement icon
ImGui::Image(this->m_currAchievement->getIcon(), scaled({ 20, 20 }));
ImGui::Image(m_currAchievement->getIcon(), scaled({ 20, 20 }));
ImGui::SameLine();
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
ImGui::SameLine();
// Draw name of achievement
ImGuiExt::TextFormattedWrapped("{}", Lang(this->m_currAchievement->getUnlocalizedName()));
ImGuiExt::TextFormattedWrapped("{}", Lang(m_currAchievement->getUnlocalizedName()));
// Handle clicking on the popup
if (ImGui::IsWindowHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
// Open the achievement window and jump to the achievement
this->getWindowOpenState() = true;
this->m_achievementToGoto = this->m_currAchievement;
m_achievementToGoto = m_currAchievement;
}
}
ImGui::End();
}
} else {
// Reset the achievement unlock queue timer
this->m_achievementUnlockQueueTimer = -1.0F;
this->m_currAchievement = nullptr;
m_achievementUnlockQueueTimer = -1.0F;
m_currAchievement = nullptr;
// If there are more achievements to draw, draw the next one
if (!this->m_achievementUnlockQueue.empty()) {
this->m_currAchievement = this->m_achievementUnlockQueue.front();
this->m_achievementUnlockQueue.pop_front();
this->m_achievementUnlockQueueTimer = 5.0F;
if (!m_achievementUnlockQueue.empty()) {
m_currAchievement = m_achievementUnlockQueue.front();
m_achievementUnlockQueue.pop_front();
m_achievementUnlockQueueTimer = 5.0F;
}
}
}

View File

@@ -28,8 +28,8 @@ namespace hex::plugin::builtin {
if (color == 0x00)
color = ImGui::GetColorU32(ImGuiCol_Header);
this->m_currBookmarkId += 1;
u64 bookmarkId = this->m_currBookmarkId;
m_currBookmarkId += 1;
u64 bookmarkId = m_currBookmarkId;
if (id != nullptr)
*id = bookmarkId;
@@ -42,16 +42,16 @@ namespace hex::plugin::builtin {
bookmarkId
};
this->m_bookmarks->emplace_back(std::move(bookmark), TextEditor());
m_bookmarks->emplace_back(std::move(bookmark), TextEditor());
ImHexApi::Provider::markDirty();
EventBookmarkCreated::post(this->m_bookmarks->back().entry);
EventBookmarkCreated::post(m_bookmarks->back().entry);
EventHighlightingChanged::post();
});
RequestRemoveBookmark::subscribe([this](u64 id) {
std::erase_if(this->m_bookmarks.get(), [id](const auto &bookmark) {
std::erase_if(m_bookmarks.get(), [id](const auto &bookmark) {
return bookmark.entry.id == id;
});
});
@@ -61,7 +61,7 @@ namespace hex::plugin::builtin {
hex::unused(data);
// Check all bookmarks for potential overlaps with the current address
for (const auto &bookmark : *this->m_bookmarks) {
for (const auto &bookmark : *m_bookmarks) {
if (Region { address, size }.isWithin(bookmark.entry.region))
return bookmark.entry.color;
}
@@ -74,7 +74,7 @@ namespace hex::plugin::builtin {
hex::unused(data);
// Loop over all bookmarks
for (const auto &[bookmark, editor] : *this->m_bookmarks) {
for (const auto &[bookmark, editor] : *m_bookmarks) {
// Make sure the bookmark overlaps the currently hovered address
if (!Region { address, size }.isWithin(bookmark.region))
continue;
@@ -147,7 +147,7 @@ namespace hex::plugin::builtin {
return true;
auto data = nlohmann::json::parse(fileContent.begin(), fileContent.end());
this->m_bookmarks.get(provider).clear();
m_bookmarks.get(provider).clear();
return this->importBookmarks(provider, data);
},
.store = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) -> bool {
@@ -163,7 +163,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Reports::addReportProvider([this](prv::Provider *provider) -> std::string {
std::string result;
const auto &bookmarks = this->m_bookmarks.get(provider);
const auto &bookmarks = m_bookmarks.get(provider);
if (bookmarks.empty())
return "";
@@ -243,27 +243,27 @@ namespace hex::plugin::builtin {
// Draw filter input
ImGui::PushItemWidth(-1);
ImGuiExt::InputTextIcon("##filter", ICON_VS_FILTER, this->m_currFilter);
ImGuiExt::InputTextIcon("##filter", ICON_VS_FILTER, m_currFilter);
ImGui::PopItemWidth();
ImGui::NewLine();
if (ImGui::BeginChild("##bookmarks")) {
if (this->m_bookmarks->empty()) {
if (m_bookmarks->empty()) {
ImGuiExt::TextFormattedCentered("hex.builtin.view.bookmarks.no_bookmarks"_lang);
}
int id = 1;
auto bookmarkToRemove = this->m_bookmarks->end();
auto bookmarkToRemove = m_bookmarks->end();
// Draw all bookmarks
for (auto it = this->m_bookmarks->begin(); it != this->m_bookmarks->end(); ++it) {
for (auto it = m_bookmarks->begin(); it != m_bookmarks->end(); ++it) {
auto &[bookmark, editor] = *it;
auto &[region, name, comment, color, locked, bookmarkId] = bookmark;
// Apply filter
if (!this->m_currFilter.empty()) {
if (!name.contains(this->m_currFilter) && !comment.contains(this->m_currFilter))
if (!m_currFilter.empty()) {
if (!name.contains(m_currFilter) && !comment.contains(m_currFilter))
continue;
}
@@ -288,18 +288,18 @@ namespace hex::plugin::builtin {
// Handle dragging bookmarks up and down when they're collapsed
// Set the currently held bookmark as the one being dragged
if (ImGui::IsMouseClicked(0) && ImGui::IsItemActivated() && this->m_dragStartIterator == this->m_bookmarks->end())
this->m_dragStartIterator = it;
if (ImGui::IsMouseClicked(0) && ImGui::IsItemActivated() && m_dragStartIterator == m_bookmarks->end())
m_dragStartIterator = it;
// When the mouse moved away from the current bookmark, swap the dragged bookmark with the current one
if (ImGui::IsItemHovered() && this->m_dragStartIterator != this->m_bookmarks->end()) {
std::iter_swap(it, this->m_dragStartIterator);
this->m_dragStartIterator = it;
if (ImGui::IsItemHovered() && m_dragStartIterator != m_bookmarks->end()) {
std::iter_swap(it, m_dragStartIterator);
m_dragStartIterator = it;
}
// When the mouse is released, reset the dragged bookmark
if (!ImGui::IsMouseDown(0))
this->m_dragStartIterator = this->m_bookmarks->end();
m_dragStartIterator = m_bookmarks->end();
} else {
const auto rowHeight = ImGui::GetTextLineHeightWithSpacing() + 2 * ImGui::GetStyle().FramePadding.y;
if (ImGui::BeginTable("##bookmark_table", 3, ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit)) {
@@ -436,8 +436,8 @@ namespace hex::plugin::builtin {
}
// Remove the bookmark that was marked for removal
if (bookmarkToRemove != this->m_bookmarks->end()) {
this->m_bookmarks->erase(bookmarkToRemove);
if (bookmarkToRemove != m_bookmarks->end()) {
m_bookmarks->erase(bookmarkToRemove);
EventHighlightingChanged::post();
}
}
@@ -458,22 +458,22 @@ namespace hex::plugin::builtin {
TextEditor editor;
editor.SetText(bookmark["comment"]);
this->m_bookmarks.get(provider).push_back({
m_bookmarks.get(provider).push_back({
{
.region = { region["address"], region["size"] },
.name = bookmark["name"],
.comment = bookmark["comment"],
.color = bookmark["color"],
.locked = bookmark["locked"],
.id = bookmark.contains("id") ? bookmark["id"].get<u64>() : *this->m_currBookmarkId
.id = bookmark.contains("id") ? bookmark["id"].get<u64>() : *m_currBookmarkId
},
editor
});
if (bookmark.contains("id"))
this->m_currBookmarkId = std::max<u64>(this->m_currBookmarkId, bookmark["id"].get<i64>() + 1);
m_currBookmarkId = std::max<u64>(m_currBookmarkId, bookmark["id"].get<i64>() + 1);
else
this->m_currBookmarkId += 1;
m_currBookmarkId += 1;
}
return true;
@@ -482,7 +482,7 @@ namespace hex::plugin::builtin {
bool ViewBookmarks::exportBookmarks(prv::Provider *provider, nlohmann::json &json) {
json["bookmarks"] = nlohmann::json::array();
size_t index = 0;
for (const auto &[bookmark, editor] : this->m_bookmarks.get(provider)) {
for (const auto &[bookmark, editor] : m_bookmarks.get(provider)) {
json["bookmarks"][index] = {
{ "name", bookmark.name },
{ "comment", editor.GetText() },
@@ -536,7 +536,7 @@ namespace hex::plugin::builtin {
wolv::io::File(path, wolv::io::File::Mode::Create).writeString(json.dump(4));
});
}, [this]{
return ImHexApi::Provider::isValid() && !this->m_bookmarks->empty();
return ImHexApi::Provider::isValid() && !m_bookmarks->empty();
});
}

View File

@@ -9,22 +9,22 @@ namespace hex::plugin::builtin {
// Add global shortcut to open the command palette
ShortcutManager::addGlobalShortcut(CTRLCMD + SHIFT + Keys::P, "hex.builtin.view.command_palette.name", [this] {
RequestOpenPopup::post("hex.builtin.view.command_palette.name"_lang);
this->m_commandPaletteOpen = true;
this->m_justOpened = true;
m_commandPaletteOpen = true;
m_justOpened = true;
});
EventSearchBoxClicked::subscribe([this](ImGuiMouseButton button) {
if (button == ImGuiMouseButton_Left) {
RequestOpenPopup::post("hex.builtin.view.command_palette.name"_lang);
this->m_commandPaletteOpen = true;
this->m_justOpened = true;
m_commandPaletteOpen = true;
m_justOpened = true;
}
});
}
void ViewCommandPalette::drawAlwaysVisibleContent() {
// If the command palette is hidden, don't draw it
if (!this->m_commandPaletteOpen) return;
if (!m_commandPaletteOpen) return;
auto windowPos = ImHexApi::System::getMainWindowPosition();
auto windowSize = ImHexApi::System::getMainWindowSize();
@@ -52,8 +52,8 @@ namespace hex::plugin::builtin {
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0_scaled);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4_scaled);
if (ImGui::InputText("##command_input", this->m_commandBuffer)) {
this->m_lastResults = this->getCommandResults(this->m_commandBuffer);
if (ImGui::InputText("##command_input", m_commandBuffer)) {
m_lastResults = this->getCommandResults(m_commandBuffer);
}
ImGui::PopStyleVar(2);
@@ -61,40 +61,40 @@ namespace hex::plugin::builtin {
ImGui::PopItemWidth();
ImGui::SetItemDefaultFocus();
if (this->m_moveCursorToEnd) {
if (m_moveCursorToEnd) {
auto textState = ImGui::GetInputTextState(ImGui::GetID("##command_input"));
if (textState != nullptr) {
textState->Stb.cursor =
textState->Stb.select_start =
textState->Stb.select_end = this->m_commandBuffer.size();
textState->Stb.select_end = m_commandBuffer.size();
}
this->m_moveCursorToEnd = false;
m_moveCursorToEnd = false;
}
// Handle giving back focus to the input text box
if (this->m_focusInputTextBox) {
if (m_focusInputTextBox) {
ImGui::SetKeyboardFocusHere(-1);
ImGui::ActivateItemByID(ImGui::GetID("##command_input"));
this->m_focusInputTextBox = false;
this->m_moveCursorToEnd = true;
m_focusInputTextBox = false;
m_moveCursorToEnd = true;
}
// Execute the currently selected command when pressing enter
if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter, false) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter, false))) {
if (!this->m_lastResults.empty()) {
auto &[displayResult, matchedCommand, callback] = this->m_lastResults.front();
if (!m_lastResults.empty()) {
auto &[displayResult, matchedCommand, callback] = m_lastResults.front();
callback(matchedCommand);
}
ImGui::CloseCurrentPopup();
}
// Focus the input text box when the popup is opened
if (this->m_justOpened) {
if (m_justOpened) {
focusInputTextBox();
this->m_lastResults = this->getCommandResults("");
this->m_commandBuffer.clear();
this->m_justOpened = false;
m_lastResults = this->getCommandResults("");
m_commandBuffer.clear();
m_justOpened = false;
}
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetStyle().FramePadding.y);
@@ -103,7 +103,7 @@ namespace hex::plugin::builtin {
// Draw the results
if (ImGui::BeginChild("##results", ImGui::GetContentRegionAvail(), false, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_NavFlattened)) {
for (const auto &[displayResult, matchedCommand, callback] : this->m_lastResults) {
for (const auto &[displayResult, matchedCommand, callback] : m_lastResults) {
ImGui::PushTabStop(true);
ON_SCOPE_EXIT { ImGui::PopTabStop(); };
@@ -122,7 +122,7 @@ namespace hex::plugin::builtin {
ImGui::EndPopup();
} else {
this->m_commandPaletteOpen = false;
m_commandPaletteOpen = false;
}
}
@@ -155,8 +155,8 @@ namespace hex::plugin::builtin {
auto AutoComplete = [this, currCommand = command](auto) {
this->focusInputTextBox();
this->m_commandBuffer = currCommand + " ";
this->m_lastResults = this->getCommandResults(currCommand);
m_commandBuffer = currCommand + " ";
m_lastResults = this->getCommandResults(currCommand);
};
if (type == ContentRegistry::CommandPaletteCommands::Type::SymbolCommand) {

View File

@@ -17,8 +17,8 @@ namespace hex::plugin::builtin {
}
void ViewConstants::reloadConstants() {
this->m_constants.clear();
this->m_filterIndices.clear();
m_constants.clear();
m_filterIndices.clear();
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Constants)) {
if (!wolv::io::fs::exists(path)) continue;
@@ -52,8 +52,8 @@ namespace hex::plugin::builtin {
else
throw std::runtime_error("Invalid type");
this->m_filterIndices.push_back(this->m_constants.size());
this->m_constants.push_back(constant);
m_filterIndices.push_back(m_constants.size());
m_constants.push_back(constant);
}
} catch (...) {
log::error("Failed to parse constants file {}", wolv::util::toUTF8String(file.path()));
@@ -65,17 +65,17 @@ namespace hex::plugin::builtin {
void ViewConstants::drawContent() {
ImGui::PushItemWidth(-1);
if (ImGuiExt::InputTextIcon("##search", ICON_VS_FILTER, this->m_filter)) {
this->m_filterIndices.clear();
if (ImGuiExt::InputTextIcon("##search", ICON_VS_FILTER, m_filter)) {
m_filterIndices.clear();
// Filter the constants according to the entered value
for (u64 i = 0; i < this->m_constants.size(); i++) {
auto &constant = this->m_constants[i];
if (hex::containsIgnoreCase(constant.name, this->m_filter) ||
hex::containsIgnoreCase(constant.category, this->m_filter) ||
hex::containsIgnoreCase(constant.description, this->m_filter) ||
hex::containsIgnoreCase(constant.value, this->m_filter))
this->m_filterIndices.push_back(i);
for (u64 i = 0; i < m_constants.size(); i++) {
auto &constant = m_constants[i];
if (hex::containsIgnoreCase(constant.name, m_filter) ||
hex::containsIgnoreCase(constant.category, m_filter) ||
hex::containsIgnoreCase(constant.description, m_filter) ||
hex::containsIgnoreCase(constant.value, m_filter))
m_filterIndices.push_back(i);
}
}
@@ -92,7 +92,7 @@ namespace hex::plugin::builtin {
// Handle table sorting
if (sortSpecs->SpecsDirty) {
std::sort(this->m_constants.begin(), this->m_constants.end(), [&sortSpecs](const Constant &left, const Constant &right) -> bool {
std::sort(m_constants.begin(), m_constants.end(), [&sortSpecs](const Constant &left, const Constant &right) -> bool {
if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("category")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left.category > right.category;
@@ -124,12 +124,12 @@ namespace hex::plugin::builtin {
ImGui::TableHeadersRow();
ImGuiListClipper clipper;
clipper.Begin(this->m_filterIndices.size());
clipper.Begin(m_filterIndices.size());
// Draw the constants table
while (clipper.Step()) {
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
auto &constant = this->m_constants[this->m_filterIndices[i]];
auto &constant = m_constants[m_filterIndices[i]];
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(constant.category.c_str());

View File

@@ -25,26 +25,26 @@ namespace hex::plugin::builtin {
// Save current selection
if (!ImHexApi::Provider::isValid() || region == Region::Invalid()) {
this->m_validBytes = 0;
this->m_selectedProvider = nullptr;
m_validBytes = 0;
m_selectedProvider = nullptr;
} else {
this->m_validBytes = u64(region.getProvider()->getActualSize() - region.address);
this->m_startAddress = region.address;
this->m_selectedProvider = region.getProvider();
m_validBytes = u64(region.getProvider()->getActualSize() - region.address);
m_startAddress = region.address;
m_selectedProvider = region.getProvider();
}
// Invalidate inspector rows
this->m_shouldInvalidate = true;
m_shouldInvalidate = true;
});
EventProviderClosed::subscribe(this, [this](const auto*) {
this->m_selectedProvider = nullptr;
m_selectedProvider = nullptr;
});
EventSettingsChanged::subscribe(this, [this] {
auto filterValues = ContentRegistry::Settings::read("hex.builtin.setting.data_inspector", "hex.builtin.setting.data_inspector.hidden_rows", nlohmann::json::array()).get<std::vector<std::string>>();
this->m_hiddenValues = std::set(filterValues.begin(), filterValues.end());
m_hiddenValues = std::set(filterValues.begin(), filterValues.end());
});
}
@@ -56,10 +56,10 @@ namespace hex::plugin::builtin {
void ViewDataInspector::updateInspectorRows() {
this->m_updateTask = TaskManager::createBackgroundTask("Update Inspector", [this, validBytes = this->m_validBytes, startAddress = this->m_startAddress, endian = this->m_endian, invert = this->m_invert, numberDisplayStyle = this->m_numberDisplayStyle](auto &) {
this->m_workData.clear();
m_updateTask = TaskManager::createBackgroundTask("Update Inspector", [this, validBytes = m_validBytes, startAddress = m_startAddress, endian = m_endian, invert = m_invert, numberDisplayStyle = m_numberDisplayStyle](auto &) {
m_workData.clear();
if (this->m_selectedProvider == nullptr)
if (m_selectedProvider == nullptr)
return;
// Decode bytes using registered inspectors
@@ -69,7 +69,7 @@ namespace hex::plugin::builtin {
// Try to read as many bytes as requested and possible
std::vector<u8> buffer(validBytes > entry.maxSize ? entry.maxSize : validBytes);
this->m_selectedProvider->read(startAddress, buffer.data(), buffer.size());
m_selectedProvider->read(startAddress, buffer.data(), buffer.size());
// Handle invert setting
if (invert) {
@@ -78,7 +78,7 @@ namespace hex::plugin::builtin {
}
// Insert processed data into the inspector list
this->m_workData.push_back({
m_workData.push_back({
entry.unlocalizedName,
entry.generatorFunction(buffer, endian, numberDisplayStyle),
entry.editingFunction,
@@ -94,13 +94,13 @@ namespace hex::plugin::builtin {
};
// Setup a new pattern language runtime
ContentRegistry::PatternLanguage::configureRuntime(this->m_runtime, this->m_selectedProvider);
ContentRegistry::PatternLanguage::configureRuntime(m_runtime, m_selectedProvider);
// Setup the runtime to read from the selected provider
this->m_runtime.setDataSource(this->m_selectedProvider->getBaseAddress(), this->m_selectedProvider->getActualSize(),
m_runtime.setDataSource(m_selectedProvider->getBaseAddress(), m_selectedProvider->getActualSize(),
[this, invert](u64 offset, u8 *buffer, size_t size) {
// Read bytes from the selected provider
this->m_selectedProvider->read(offset, buffer, size);
m_selectedProvider->read(offset, buffer, size);
// Handle invert setting
if (invert) {
@@ -110,13 +110,13 @@ namespace hex::plugin::builtin {
});
// Prevent dangerous function calls
this->m_runtime.setDangerousFunctionCallHandler([] { return false; });
m_runtime.setDangerousFunctionCallHandler([] { return false; });
// Set the default endianness based on the endian setting
this->m_runtime.setDefaultEndian(endian);
m_runtime.setDefaultEndian(endian);
// Set start address to the selected address
this->m_runtime.setStartAddress(startAddress);
m_runtime.setStartAddress(startAddress);
// Loop over all files in the inspectors folder and execute them
for (const auto &folderPath : fs::getDefaultPaths(fs::ImHexPath::Inspectors)) {
@@ -133,10 +133,10 @@ namespace hex::plugin::builtin {
// Execute the inspector file
if (!inspectorCode.empty()) {
if (this->m_runtime.executeString(inspectorCode, {}, inVariables, true)) {
if (m_runtime.executeString(inspectorCode, {}, inVariables, true)) {
// Loop over patterns produced by the runtime
const auto &patterns = this->m_runtime.getPatterns();
const auto &patterns = m_runtime.getPatterns();
for (const auto &pattern : patterns) {
// Skip hidden patterns
if (pattern->getVisibility() == pl::ptrn::Visibility::Hidden)
@@ -166,7 +166,7 @@ namespace hex::plugin::builtin {
};
// Insert the inspector into the list
this->m_workData.push_back({
m_workData.push_back({
pattern->getDisplayName(),
displayFunction,
editingFunction,
@@ -180,7 +180,7 @@ namespace hex::plugin::builtin {
}
}
} else {
const auto& error = this->m_runtime.getError();
const auto& error = m_runtime.getError();
log::error("Failed to execute custom inspector file '{}'!", wolv::util::toUTF8String(filePath));
if (error.has_value())
@@ -191,46 +191,46 @@ namespace hex::plugin::builtin {
}
}
this->m_dataValid = true;
m_dataValid = true;
});
}
void ViewDataInspector::drawContent() {
if (this->m_dataValid && !this->m_updateTask.isRunning()) {
this->m_dataValid = false;
this->m_cachedData = std::move(this->m_workData);
if (m_dataValid && !m_updateTask.isRunning()) {
m_dataValid = false;
m_cachedData = std::move(m_workData);
}
if (this->m_shouldInvalidate && !this->m_updateTask.isRunning()) {
this->m_shouldInvalidate = false;
if (m_shouldInvalidate && !m_updateTask.isRunning()) {
m_shouldInvalidate = false;
this->updateInspectorRows();
}
if (this->m_selectedProvider != nullptr && this->m_selectedProvider->isReadable() && this->m_validBytes > 0) {
u32 validLineCount = this->m_cachedData.size();
if (!this->m_tableEditingModeEnabled) {
validLineCount = std::count_if(this->m_cachedData.begin(), this->m_cachedData.end(), [this](const auto &entry) {
return !this->m_hiddenValues.contains(entry.filterValue);
if (m_selectedProvider != nullptr && m_selectedProvider->isReadable() && m_validBytes > 0) {
u32 validLineCount = m_cachedData.size();
if (!m_tableEditingModeEnabled) {
validLineCount = std::count_if(m_cachedData.begin(), m_cachedData.end(), [this](const auto &entry) {
return !m_hiddenValues.contains(entry.filterValue);
});
}
if (ImGui::BeginTable("##datainspector", this->m_tableEditingModeEnabled ? 3 : 2, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg, ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * (validLineCount + 1)))) {
if (ImGui::BeginTable("##datainspector", m_tableEditingModeEnabled ? 3 : 2, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg, ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * (validLineCount + 1)))) {
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableSetupColumn("hex.builtin.view.data_inspector.table.name"_lang, ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("hex.builtin.view.data_inspector.table.value"_lang, ImGuiTableColumnFlags_WidthStretch);
if (this->m_tableEditingModeEnabled)
if (m_tableEditingModeEnabled)
ImGui::TableSetupColumn("##favorite", ImGuiTableColumnFlags_WidthFixed, ImGui::GetTextLineHeight());
ImGui::TableHeadersRow();
int inspectorRowId = 1;
for (auto &[unlocalizedName, displayFunction, editingFunction, editing, filterValue] : this->m_cachedData) {
for (auto &[unlocalizedName, displayFunction, editingFunction, editing, filterValue] : m_cachedData) {
bool grayedOut = false;
if (this->m_hiddenValues.contains(filterValue)) {
if (!this->m_tableEditingModeEnabled)
if (m_hiddenValues.contains(filterValue)) {
if (!m_tableEditingModeEnabled)
continue;
else
grayedOut = true;
@@ -262,7 +262,7 @@ namespace hex::plugin::builtin {
// Enter editing mode when double-clicking the row
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && editingFunction.has_value()) {
editing = true;
this->m_editingValue = copyValue;
m_editingValue = copyValue;
}
} else {
@@ -273,49 +273,49 @@ namespace hex::plugin::builtin {
ImGui::SetKeyboardFocusHere();
// Draw input text box
if (ImGui::InputText("##InspectorLineEditing", this->m_editingValue, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
if (ImGui::InputText("##InspectorLineEditing", m_editingValue, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
// Turn the entered value into bytes
auto bytes = editingFunction.value()(this->m_editingValue, this->m_endian);
auto bytes = editingFunction.value()(m_editingValue, m_endian);
if (this->m_invert)
if (m_invert)
std::ranges::transform(bytes, bytes.begin(), [](auto byte) { return byte ^ 0xFF; });
// Write those bytes to the selected provider at the current address
this->m_selectedProvider->write(this->m_startAddress, bytes.data(), bytes.size());
m_selectedProvider->write(m_startAddress, bytes.data(), bytes.size());
// Disable editing mode
this->m_editingValue.clear();
m_editingValue.clear();
editing = false;
// Reload all inspector rows
this->m_shouldInvalidate = true;
m_shouldInvalidate = true;
}
ImGui::PopStyleVar();
// Disable editing mode when clicking outside the input text box
if (!ImGui::IsItemHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
this->m_editingValue.clear();
m_editingValue.clear();
editing = false;
}
}
ImGui::EndDisabled();
if (this->m_tableEditingModeEnabled) {
if (m_tableEditingModeEnabled) {
ImGui::TableNextColumn();
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::GetStyleColorVec4(ImGuiCol_Text));
bool hidden = this->m_hiddenValues.contains(filterValue);
bool hidden = m_hiddenValues.contains(filterValue);
if (ImGuiExt::DimmedButton(hidden ? ICON_VS_EYE : ICON_VS_EYE_CLOSED)) {
if (hidden)
this->m_hiddenValues.erase(filterValue);
m_hiddenValues.erase(filterValue);
else
this->m_hiddenValues.insert(filterValue);
m_hiddenValues.insert(filterValue);
{
std::vector filterValues(this->m_hiddenValues.begin(), this->m_hiddenValues.end());
std::vector filterValues(m_hiddenValues.begin(), m_hiddenValues.end());
ContentRegistry::Settings::write("hex.builtin.setting.data_inspector", "hex.builtin.setting.data_inspector.hidden_rows", filterValues);
}
@@ -332,7 +332,7 @@ namespace hex::plugin::builtin {
ImGui::EndTable();
}
ImGuiExt::DimmedButtonToggle("hex.builtin.common.edit"_lang, &this->m_tableEditingModeEnabled, ImVec2(ImGui::GetContentRegionAvail().x, 0));
ImGuiExt::DimmedButtonToggle("hex.builtin.common.edit"_lang, &m_tableEditingModeEnabled, ImVec2(ImGui::GetContentRegionAvail().x, 0));
ImGui::NewLine();
ImGui::Separator();
@@ -343,7 +343,7 @@ namespace hex::plugin::builtin {
// Draw endian setting
{
int selection = [this] {
switch (this->m_endian) {
switch (m_endian) {
default:
case std::endian::little: return 0;
case std::endian::big: return 1;
@@ -353,12 +353,12 @@ namespace hex::plugin::builtin {
std::array options = { "hex.builtin.common.little"_lang, "hex.builtin.common.big"_lang };
if (ImGui::SliderInt("hex.builtin.common.endian"_lang, &selection, 0, options.size() - 1, options[selection], ImGuiSliderFlags_NoInput)) {
this->m_shouldInvalidate = true;
m_shouldInvalidate = true;
switch (selection) {
default:
case 0: this->m_endian = std::endian::little; break;
case 1: this->m_endian = std::endian::big; break;
case 0: m_endian = std::endian::little; break;
case 1: m_endian = std::endian::big; break;
}
}
}
@@ -366,7 +366,7 @@ namespace hex::plugin::builtin {
// Draw radix setting
{
int selection = [this] {
switch (this->m_numberDisplayStyle) {
switch (m_numberDisplayStyle) {
default:
case NumberDisplayStyle::Decimal: return 0;
case NumberDisplayStyle::Hexadecimal: return 1;
@@ -376,26 +376,26 @@ namespace hex::plugin::builtin {
std::array options = { "hex.builtin.common.decimal"_lang, "hex.builtin.common.hexadecimal"_lang, "hex.builtin.common.octal"_lang };
if (ImGui::SliderInt("hex.builtin.common.number_format"_lang, &selection, 0, options.size() - 1, options[selection], ImGuiSliderFlags_NoInput)) {
this->m_shouldInvalidate = true;
m_shouldInvalidate = true;
switch (selection) {
default:
case 0: this->m_numberDisplayStyle = NumberDisplayStyle::Decimal; break;
case 1: this->m_numberDisplayStyle = NumberDisplayStyle::Hexadecimal; break;
case 2: this->m_numberDisplayStyle = NumberDisplayStyle::Octal; break;
case 0: m_numberDisplayStyle = NumberDisplayStyle::Decimal; break;
case 1: m_numberDisplayStyle = NumberDisplayStyle::Hexadecimal; break;
case 2: m_numberDisplayStyle = NumberDisplayStyle::Octal; break;
}
}
}
// Draw invert setting
{
int selection = this->m_invert ? 1 : 0;
int selection = m_invert ? 1 : 0;
std::array options = { "hex.builtin.common.no"_lang, "hex.builtin.common.yes"_lang };
if (ImGui::SliderInt("hex.builtin.view.data_inspector.invert"_lang, &selection, 0, options.size() - 1, options[selection], ImGuiSliderFlags_NoInput)) {
this->m_shouldInvalidate = true;
m_shouldInvalidate = true;
this->m_invert = selection == 1;
m_invert = selection == 1;
}
}
} else {

View File

@@ -29,26 +29,26 @@ namespace hex::plugin::builtin {
void drawNode() override {
ImGui::PushItemWidth(100_scaled);
// Draw combo box to select the type of the input
if (ImGui::Combo("##type", &this->m_type, "Integer\0Float\0Buffer\0")) {
if (ImGui::Combo("##type", &m_type, "Integer\0Float\0Buffer\0")) {
this->setAttributes({
{ dp::Attribute(dp::Attribute::IOType::Out, this->getType(), "hex.builtin.nodes.common.input") }
});
}
// Draw text input to set the name of the input
if (ImGui::InputText("##name", this->m_name)) {
this->setUnlocalizedTitle(this->m_name);
if (ImGui::InputText("##name", m_name)) {
this->setUnlocalizedTitle(m_name);
}
ImGui::PopItemWidth();
}
void setValue(auto value) { this->m_value = std::move(value); }
void setValue(auto value) { m_value = std::move(value); }
const std::string &getName() const { return this->m_name; }
const std::string &getName() const { return m_name; }
dp::Attribute::Type getType() const {
switch (this->m_type) {
switch (m_type) {
default:
case 0: return dp::Attribute::Type::Integer;
case 1: return dp::Attribute::Type::Float;
@@ -61,21 +61,21 @@ namespace hex::plugin::builtin {
[this](i128 value) { this->setIntegerOnOutput(0, value); },
[this](long double value) { this->setFloatOnOutput(0, value); },
[this](const std::vector<u8> &value) { this->setBufferOnOutput(0, value); }
}, this->m_value);
}, m_value);
}
void store(nlohmann::json &j) const override {
j = nlohmann::json::object();
j["name"] = this->m_name;
j["type"] = this->m_type;
j["name"] = m_name;
j["type"] = m_type;
}
void load(const nlohmann::json &j) override {
this->m_name = j.at("name").get<std::string>();
this->m_type = j.at("type");
m_name = j.at("name").get<std::string>();
m_type = j.at("type");
this->setUnlocalizedTitle(this->m_name);
this->setUnlocalizedTitle(m_name);
this->setAttributes({
{ dp::Attribute(dp::Attribute::IOType::Out, this->getType(), "hex.builtin.nodes.common.input") }
});
@@ -100,23 +100,23 @@ namespace hex::plugin::builtin {
ImGui::PushItemWidth(100_scaled);
// Draw combo box to select the type of the output
if (ImGui::Combo("##type", &this->m_type, "Integer\0Float\0Buffer\0")) {
if (ImGui::Combo("##type", &m_type, "Integer\0Float\0Buffer\0")) {
this->setAttributes({
{ dp::Attribute(dp::Attribute::IOType::In, this->getType(), "hex.builtin.nodes.common.output") }
});
}
// Draw text input to set the name of the output
if (ImGui::InputText("##name", this->m_name)) {
this->setUnlocalizedTitle(this->m_name);
if (ImGui::InputText("##name", m_name)) {
this->setUnlocalizedTitle(m_name);
}
ImGui::PopItemWidth();
}
const std::string &getName() const { return this->m_name; }
const std::string &getName() const { return m_name; }
dp::Attribute::Type getType() const {
switch (this->m_type) {
switch (m_type) {
case 0: return dp::Attribute::Type::Integer;
case 1: return dp::Attribute::Type::Float;
case 2: return dp::Attribute::Type::Buffer;
@@ -126,26 +126,26 @@ namespace hex::plugin::builtin {
void process() override {
switch (this->getType()) {
case dp::Attribute::Type::Integer: this->m_value = this->getIntegerOnInput(0); break;
case dp::Attribute::Type::Float: this->m_value = this->getFloatOnInput(0); break;
case dp::Attribute::Type::Buffer: this->m_value = this->getBufferOnInput(0); break;
case dp::Attribute::Type::Integer: m_value = this->getIntegerOnInput(0); break;
case dp::Attribute::Type::Float: m_value = this->getFloatOnInput(0); break;
case dp::Attribute::Type::Buffer: m_value = this->getBufferOnInput(0); break;
}
}
const auto& getValue() const { return this->m_value; }
const auto& getValue() const { return m_value; }
void store(nlohmann::json &j) const override {
j = nlohmann::json::object();
j["name"] = this->m_name;
j["type"] = this->m_type;
j["name"] = m_name;
j["type"] = m_type;
}
void load(const nlohmann::json &j) override {
this->m_name = j.at("name").get<std::string>();
this->m_type = j.at("type");
m_name = j.at("name").get<std::string>();
m_type = j.at("type");
this->setUnlocalizedTitle(this->m_name);
this->setUnlocalizedTitle(m_name);
this->setAttributes({
{ dp::Attribute(dp::Attribute::IOType::In, this->getType(), "hex.builtin.nodes.common.output") }
});
@@ -168,8 +168,8 @@ namespace hex::plugin::builtin {
void drawNode() override {
// Update attributes if we have to
if (this->m_requiresAttributeUpdate) {
this->m_requiresAttributeUpdate = false;
if (m_requiresAttributeUpdate) {
m_requiresAttributeUpdate = false;
// Find all input and output nodes that are used by the workspace of this node
// and set the attributes of this node to the attributes of the input and output nodes
@@ -179,9 +179,9 @@ namespace hex::plugin::builtin {
ImGui::PushItemWidth(200_scaled);
bool editing = false;
if (this->m_editable) {
if (m_editable) {
// Draw name input field
ImGuiExt::InputTextIcon("##name", ICON_VS_SYMBOL_KEY, this->m_name);
ImGuiExt::InputTextIcon("##name", ICON_VS_SYMBOL_KEY, m_name);
// Prevent editing mode from deactivating when the input field is focused
editing = ImGui::IsItemActive();
@@ -191,12 +191,12 @@ namespace hex::plugin::builtin {
AchievementManager::unlockAchievement("hex.builtin.achievement.data_processor", "hex.builtin.achievement.data_processor.custom_node.name");
// Open the custom node's workspace
this->m_dataProcessor->getWorkspaceStack().push_back(&this->m_workspace);
m_dataProcessor->getWorkspaceStack().push_back(&m_workspace);
this->m_requiresAttributeUpdate = true;
m_requiresAttributeUpdate = true;
}
} else {
this->setUnlocalizedTitle(this->m_name);
this->setUnlocalizedTitle(m_name);
if (this->getAttributes().empty()) {
ImGui::TextUnformatted("hex.builtin.nodes.custom.custom.edit_hint"_lang);
@@ -204,7 +204,7 @@ namespace hex::plugin::builtin {
}
// Enable editing mode when the shift button is pressed
this->m_editable = ImGui::GetIO().KeyShift || editing;
m_editable = ImGui::GetIO().KeyShift || editing;
ImGui::PopItemWidth();
}
@@ -220,7 +220,7 @@ namespace hex::plugin::builtin {
};
auto prevContext = ImNodes::GetCurrentContext();
ImNodes::SetCurrentContext(this->m_workspace.context.get());
ImNodes::SetCurrentContext(m_workspace.context.get());
ON_SCOPE_EXIT { ImNodes::SetCurrentContext(prevContext); };
// Forward inputs to input nodes values
@@ -251,11 +251,11 @@ namespace hex::plugin::builtin {
}
// Process all nodes in our workspace
for (auto &endNode : this->m_workspace.endNodes) {
for (auto &endNode : m_workspace.endNodes) {
endNode->resetOutputData();
// Reset processed inputs of all nodes
for (auto &node : this->m_workspace.nodes)
for (auto &node : m_workspace.nodes)
node->resetProcessedInputs();
endNode->process();
@@ -294,14 +294,14 @@ namespace hex::plugin::builtin {
void store(nlohmann::json &j) const override {
j = nlohmann::json::object();
j["nodes"] = this->m_dataProcessor->saveNodes(this->m_workspace);
j["nodes"] = m_dataProcessor->saveNodes(m_workspace);
}
void load(const nlohmann::json &j) override {
this->m_dataProcessor->loadNodes(this->m_workspace, j.at("nodes"));
m_dataProcessor->loadNodes(m_workspace, j.at("nodes"));
this->m_name = Lang(this->getUnlocalizedTitle()).get();
this->m_requiresAttributeUpdate = true;
m_name = Lang(this->getUnlocalizedTitle()).get();
m_requiresAttributeUpdate = true;
}
private:
@@ -309,7 +309,7 @@ namespace hex::plugin::builtin {
std::vector<dp::Attribute> result;
// Search through all nodes in the workspace and add all input and output nodes to the result
for (auto &node : this->m_workspace.nodes) {
for (auto &node : m_workspace.nodes) {
if (auto *inputNode = dynamic_cast<NodeCustomInput*>(node.get()); inputNode != nullptr)
result.emplace_back(dp::Attribute::IOType::In, inputNode->getType(), inputNode->getName());
else if (auto *outputNode = dynamic_cast<NodeCustomOutput*>(node.get()); outputNode != nullptr)
@@ -320,7 +320,7 @@ namespace hex::plugin::builtin {
}
NodeCustomInput* findInput(const std::string &name) const {
for (auto &node : this->m_workspace.nodes) {
for (auto &node : m_workspace.nodes) {
if (auto *inputNode = dynamic_cast<NodeCustomInput*>(node.get()); inputNode != nullptr && inputNode->getName() == name)
return inputNode;
}
@@ -329,7 +329,7 @@ namespace hex::plugin::builtin {
}
NodeCustomOutput* findOutput(const std::string &name) const {
for (auto &node : this->m_workspace.nodes) {
for (auto &node : m_workspace.nodes) {
if (auto *outputNode = dynamic_cast<NodeCustomOutput*>(node.get()); outputNode != nullptr && outputNode->getName() == name)
return outputNode;
}
@@ -358,25 +358,25 @@ namespace hex::plugin::builtin {
.load = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) {
std::string save = tar.readString(basePath);
ViewDataProcessor::loadNodes(this->m_mainWorkspace.get(provider), nlohmann::json::parse(save));
this->m_updateNodePositions = true;
ViewDataProcessor::loadNodes(m_mainWorkspace.get(provider), nlohmann::json::parse(save));
m_updateNodePositions = true;
return true;
},
.store = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) {
tar.writeString(basePath, ViewDataProcessor::saveNodes(this->m_mainWorkspace.get(provider)).dump(4));
tar.writeString(basePath, ViewDataProcessor::saveNodes(m_mainWorkspace.get(provider)).dump(4));
return true;
}
});
EventProviderCreated::subscribe(this, [this](auto *provider) {
this->m_mainWorkspace.get(provider) = { };
this->m_workspaceStack.get(provider).push_back(&this->m_mainWorkspace.get(provider));
m_mainWorkspace.get(provider) = { };
m_workspaceStack.get(provider).push_back(&m_mainWorkspace.get(provider));
});
EventProviderChanged::subscribe(this, [this](const auto *, const auto *) {
for (auto *workspace : *this->m_workspaceStack) {
for (auto *workspace : *m_workspaceStack) {
for (auto &node : workspace->nodes) {
node->setCurrentOverlay(nullptr);
}
@@ -384,11 +384,11 @@ namespace hex::plugin::builtin {
workspace->dataOverlays.clear();
}
this->m_updateNodePositions = true;
m_updateNodePositions = true;
});
EventDataChanged::subscribe(this, [this] {
ViewDataProcessor::processNodes(*this->m_workspaceStack->back());
ViewDataProcessor::processNodes(*m_workspaceStack->back());
});
/* Import Nodes */
@@ -397,8 +397,8 @@ namespace hex::plugin::builtin {
[&](const std::fs::path &path) {
wolv::io::File file(path, wolv::io::File::Mode::Read);
if (file.isValid()) {
ViewDataProcessor::loadNodes(*this->m_mainWorkspace, nlohmann::json::parse(file.readString()));
this->m_updateNodePositions = true;
ViewDataProcessor::loadNodes(*m_mainWorkspace, nlohmann::json::parse(file.readString()));
m_updateNodePositions = true;
}
});
}, ImHexApi::Provider::isValid);
@@ -409,18 +409,18 @@ namespace hex::plugin::builtin {
[&, this](const std::fs::path &path) {
wolv::io::File file(path, wolv::io::File::Mode::Create);
if (file.isValid())
file.writeString(ViewDataProcessor::saveNodes(*this->m_mainWorkspace).dump(4));
file.writeString(ViewDataProcessor::saveNodes(*m_mainWorkspace).dump(4));
});
}, [this]{
return !this->m_workspaceStack->empty() && !this->m_workspaceStack->back()->nodes.empty() && ImHexApi::Provider::isValid();
return !m_workspaceStack->empty() && !m_workspaceStack->back()->nodes.empty() && ImHexApi::Provider::isValid();
});
ContentRegistry::FileHandler::add({ ".hexnode" }, [this](const auto &path) {
wolv::io::File file(path, wolv::io::File::Mode::Read);
if (!file.isValid()) return false;
ViewDataProcessor::loadNodes(*this->m_mainWorkspace, file.readString());
this->m_updateNodePositions = true;
ViewDataProcessor::loadNodes(*m_mainWorkspace, file.readString());
m_updateNodePositions = true;
return true;
});
@@ -563,7 +563,7 @@ namespace hex::plugin::builtin {
void ViewDataProcessor::reloadCustomNodes() {
// Delete all custom nodes
this->m_customNodes.clear();
m_customNodes.clear();
// Loop over all custom node folders
for (const auto &basePath : fs::getDefaultPaths(fs::ImHexPath::Nodes)) {
@@ -579,7 +579,7 @@ namespace hex::plugin::builtin {
nlohmann::json nodeJson = nlohmann::json::parse(file.readString());
// Add the loaded node to the list of custom nodes
this->m_customNodes.push_back(CustomNode { Lang(nodeJson.at("name").get<std::string>()), nodeJson });
m_customNodes.push_back(CustomNode { Lang(nodeJson.at("name").get<std::string>()), nodeJson });
} catch (nlohmann::json::exception &e) {
log::warn("Failed to load custom node '{}': {}", entry.path().string(), e.what());
}
@@ -595,13 +595,13 @@ namespace hex::plugin::builtin {
ImNodes::ClearLinkSelection();
// Save the current mouse position
this->m_rightClickedCoords = ImGui::GetMousePos();
m_rightClickedCoords = ImGui::GetMousePos();
// Show a different context menu depending on if a node, a link
// or the background was right-clicked
if (ImNodes::IsNodeHovered(&this->m_rightClickedId))
if (ImNodes::IsNodeHovered(&m_rightClickedId))
ImGui::OpenPopup("Node Menu");
else if (ImNodes::IsLinkHovered(&this->m_rightClickedId))
else if (ImNodes::IsLinkHovered(&m_rightClickedId))
ImGui::OpenPopup("Link Menu");
else {
ImGui::OpenPopup("Context Menu");
@@ -665,7 +665,7 @@ namespace hex::plugin::builtin {
ImGui::Separator();
// Draw entries for each custom node
for (auto &customNode : this->m_customNodes) {
for (auto &customNode : m_customNodes) {
if (ImGui::MenuItem(customNode.name.c_str())) {
node = loadNode(customNode.data);
}
@@ -694,7 +694,7 @@ namespace hex::plugin::builtin {
workspace.endNodes.push_back(node.get());
// Set the position of the node to the position where the user right-clicked
ImNodes::SetNodeScreenSpacePos(node->getId(), this->m_rightClickedCoords);
ImNodes::SetNodeScreenSpacePos(node->getId(), m_rightClickedCoords);
workspace.nodes.push_back(std::move(node));
ImHexApi::Provider::markDirty();
@@ -710,7 +710,7 @@ namespace hex::plugin::builtin {
// Find the node that was right-clicked
auto it = std::find_if(workspace.nodes.begin(), workspace.nodes.end(),
[this](const auto &node) {
return node->getId() == this->m_rightClickedId;
return node->getId() == m_rightClickedId;
});
// Check if the node was found
@@ -728,7 +728,7 @@ namespace hex::plugin::builtin {
ImGui::Separator();
if (ImGui::MenuItem("hex.builtin.view.data_processor.menu.remove_node"_lang))
this->eraseNodes(workspace, { this->m_rightClickedId });
this->eraseNodes(workspace, { m_rightClickedId });
ImGui::EndPopup();
}
@@ -736,7 +736,7 @@ namespace hex::plugin::builtin {
// Draw link right click menu
if (ImGui::BeginPopup("Link Menu")) {
if (ImGui::MenuItem("hex.builtin.view.data_processor.menu.remove_link"_lang))
this->eraseLink(workspace, this->m_rightClickedId);
this->eraseLink(workspace, m_rightClickedId);
ImGui::EndPopup();
}
@@ -745,7 +745,7 @@ namespace hex::plugin::builtin {
void ViewDataProcessor::drawNode(dp::Node &node) const {
// If a node position update is pending, update the node position
int nodeId = node.getId();
if (this->m_updateNodePositions) {
if (m_updateNodePositions) {
ImNodes::SetNodeGridSpacePos(nodeId, node.getPosition());
} else {
if (ImNodes::ObjectPoolFind(ImNodes::EditorContextGet().Nodes, nodeId) >= 0)
@@ -839,7 +839,7 @@ namespace hex::plugin::builtin {
}
void ViewDataProcessor::drawContent() {
auto &workspace = *this->m_workspaceStack->back();
auto &workspace = *m_workspaceStack->back();
bool popWorkspace = false;
// Set the ImNodes context to the current workspace context
@@ -879,7 +879,7 @@ namespace hex::plugin::builtin {
ImNodes::PopColorStyle();
}
this->m_updateNodePositions = false;
m_updateNodePositions = false;
// Handle removing links that are connected to attributes that don't exist anymore
{
@@ -908,7 +908,7 @@ namespace hex::plugin::builtin {
ImGuiExt::TextFormattedCentered("{}", "hex.builtin.view.data_processor.help_text"_lang);
// Draw a close button if there is more than one workspace on the stack
if (this->m_workspaceStack->size() > 1) {
if (m_workspaceStack->size() > 1) {
ImGui::SetCursorPos(ImVec2(ImGui::GetContentRegionAvail().x - ImGui::GetTextLineHeightWithSpacing() * 1.5F, ImGui::GetTextLineHeightWithSpacing() * 0.2F));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0F, 4.0F));
if (ImGuiExt::DimmedIconButton(ICON_VS_CLOSE, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
@@ -923,12 +923,12 @@ namespace hex::plugin::builtin {
// Draw the control bar at the bottom
{
if (ImGuiExt::IconButton(ICON_VS_DEBUG_START, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen)) || this->m_continuousEvaluation)
if (ImGuiExt::IconButton(ICON_VS_DEBUG_START, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen)) || m_continuousEvaluation)
this->processNodes(workspace);
ImGui::SameLine();
ImGui::Checkbox("Continuous evaluation", &this->m_continuousEvaluation);
ImGui::Checkbox("Continuous evaluation", &m_continuousEvaluation);
}
@@ -1016,8 +1016,8 @@ namespace hex::plugin::builtin {
// Remove the top-most workspace from the stack if requested
if (popWorkspace) {
this->m_workspaceStack->pop_back();
this->m_updateNodePositions = true;
m_workspaceStack->pop_back();
m_updateNodePositions = true;
}
}
@@ -1192,7 +1192,7 @@ namespace hex::plugin::builtin {
dp::Attribute::setIdCounter(maxAttrId + 1);
dp::Link::setIdCounter(maxLinkId + 1);
this->m_updateNodePositions = true;
m_updateNodePositions = true;
} catch (nlohmann::json::exception &e) {
PopupError::open(hex::format("Failed to load nodes: {}", e.what()));
}

View File

@@ -20,16 +20,16 @@ namespace hex::plugin::builtin {
// Clear the selected diff providers when a provider is closed
EventProviderClosed::subscribe(this, [this](prv::Provider *) {
for (u8 i = 0; i < 2; i++) {
this->m_columns[i].provider = -1;
this->m_columns[i].hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
m_columns[i].provider = -1;
m_columns[i].hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
}
this->m_diffs.clear();
m_diffs.clear();
});
// Set the background highlight callbacks for the two hex editor columns
this->m_columns[0].hexEditor.setBackgroundHighlightCallback(this->createCompareFunction(1));
this->m_columns[1].hexEditor.setBackgroundHighlightCallback(this->createCompareFunction(0));
m_columns[0].hexEditor.setBackgroundHighlightCallback(this->createCompareFunction(1));
m_columns[1].hexEditor.setBackgroundHighlightCallback(this->createCompareFunction(0));
}
ViewDiff::~ViewDiff() {
@@ -102,7 +102,7 @@ namespace hex::plugin::builtin {
return [this, otherIndex](u64 address, const u8 *data, size_t) -> std::optional<color_t> {
const auto &providers = ImHexApi::Provider::getProviders();
auto otherId = this->m_columns[otherIndex].provider;
auto otherId = m_columns[otherIndex].provider;
// Check if the other provider is valid
if (otherId < 0 || size_t(otherId) >= providers.size())
@@ -133,7 +133,7 @@ namespace hex::plugin::builtin {
void ViewDiff::analyze(prv::Provider *providerA, prv::Provider *providerB) {
auto commonSize = std::min(providerA->getActualSize(), providerB->getActualSize());
this->m_diffTask = TaskManager::createTask("Diffing...", commonSize, [this, providerA, providerB](Task &task) {
m_diffTask = TaskManager::createTask("Diffing...", commonSize, [this, providerA, providerB](Task &task) {
std::vector<Diff> differences;
// Set up readers for both providers
@@ -177,13 +177,13 @@ namespace hex::plugin::builtin {
}
// Move the calculated differences over so they can be displayed
this->m_diffs = std::move(differences);
this->m_analyzed = true;
m_diffs = std::move(differences);
m_analyzed = true;
});
}
void ViewDiff::drawContent() {
auto &[a, b] = this->m_columns;
auto &[a, b] = m_columns;
a.hexEditor.enableSyncScrolling(false);
b.hexEditor.enableSyncScrolling(false);
@@ -206,7 +206,7 @@ namespace hex::plugin::builtin {
}
// Analyze the providers if they are valid and the user selected a new provider
if (!this->m_analyzed && a.provider != -1 && b.provider != -1 && !this->m_diffTask.isRunning()) {
if (!m_analyzed && a.provider != -1 && b.provider != -1 && !m_diffTask.isRunning()) {
const auto &providers = ImHexApi::Provider::getProviders();
auto providerA = providers[a.provider];
auto providerB = providers[b.provider];
@@ -222,15 +222,15 @@ namespace hex::plugin::builtin {
ImGui::TableSetupColumn("hex.builtin.view.diff.provider_b"_lang);
ImGui::TableHeadersRow();
ImGui::BeginDisabled(this->m_diffTask.isRunning());
ImGui::BeginDisabled(m_diffTask.isRunning());
{
// Draw first provider selector
ImGui::TableNextColumn();
if (drawProviderSelector(a)) this->m_analyzed = false;
if (drawProviderSelector(a)) m_analyzed = false;
// Draw second provider selector
ImGui::TableNextColumn();
if (drawProviderSelector(b)) this->m_analyzed = false;
if (drawProviderSelector(b)) m_analyzed = false;
}
ImGui::EndDisabled();
@@ -268,21 +268,21 @@ namespace hex::plugin::builtin {
ImGui::TableHeadersRow();
// Draw the differences if the providers have been analyzed
if (this->m_analyzed) {
if (m_analyzed) {
ImGuiListClipper clipper;
clipper.Begin(int(this->m_diffs.size()));
clipper.Begin(int(m_diffs.size()));
while (clipper.Step())
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
ImGui::TableNextRow();
// Prevent the list from trying to access non-existing diffs
if (size_t(i) >= this->m_diffs.size())
if (size_t(i) >= m_diffs.size())
break;
ImGui::PushID(i);
const auto &diff = this->m_diffs[i];
const auto &diff = m_diffs[i];
// Draw a clickable row for each difference that will select the difference in both hex editors

View File

@@ -11,7 +11,7 @@ namespace hex::plugin::builtin {
ViewDisassembler::ViewDisassembler() : View::Window("hex.builtin.view.disassembler.name") {
EventProviderDeleted::subscribe(this, [this](const auto*) {
this->m_disassembly.clear();
m_disassembly.clear();
});
}
@@ -22,23 +22,23 @@ namespace hex::plugin::builtin {
}
void ViewDisassembler::disassemble() {
this->m_disassembly.clear();
m_disassembly.clear();
this->m_disassemblerTask = TaskManager::createTask("hex.builtin.view.disassembler.disassembling", this->m_codeRegion.getSize(), [this](auto &task) {
m_disassemblerTask = TaskManager::createTask("hex.builtin.view.disassembler.disassembling", m_codeRegion.getSize(), [this](auto &task) {
csh capstoneHandle;
cs_insn *instructions = nullptr;
cs_mode mode = this->m_mode;
cs_mode mode = m_mode;
// Create a capstone disassembler instance
if (cs_open(Disassembler::toCapstoneArchitecture(this->m_architecture), mode, &capstoneHandle) == CS_ERR_OK) {
if (cs_open(Disassembler::toCapstoneArchitecture(m_architecture), mode, &capstoneHandle) == CS_ERR_OK) {
// Tell capstone to skip data bytes
cs_option(capstoneHandle, CS_OPT_SKIPDATA, CS_OPT_ON);
auto provider = ImHexApi::Provider::get();
std::vector<u8> buffer(2048, 0x00);
size_t size = this->m_codeRegion.getSize();
size_t size = m_codeRegion.getSize();
// Read the data in chunks and disassemble it
for (u64 address = 0; address < size; address += 2048) {
@@ -46,15 +46,15 @@ namespace hex::plugin::builtin {
// Read a chunk of data
size_t bufferSize = std::min(u64(2048), (size - address));
provider->read(this->m_codeRegion.getStartAddress() + address, buffer.data(), bufferSize);
provider->read(m_codeRegion.getStartAddress() + address, buffer.data(), bufferSize);
// Ask capstone to disassemble the data
size_t instructionCount = cs_disasm(capstoneHandle, buffer.data(), bufferSize, this->m_baseAddress + address, 0, &instructions);
size_t instructionCount = cs_disasm(capstoneHandle, buffer.data(), bufferSize, m_baseAddress + address, 0, &instructions);
if (instructionCount == 0)
break;
// Reserve enough space for the disassembly
this->m_disassembly.reserve(this->m_disassembly.size() + instructionCount);
m_disassembly.reserve(m_disassembly.size() + instructionCount);
// Convert the capstone instructions to our disassembly format
u64 usedBytes = 0;
@@ -62,7 +62,7 @@ namespace hex::plugin::builtin {
const auto &instr = instructions[i];
Disassembly disassembly = { };
disassembly.address = instr.address;
disassembly.offset = this->m_codeRegion.getStartAddress() + address + usedBytes;
disassembly.offset = m_codeRegion.getStartAddress() + address + usedBytes;
disassembly.size = instr.size;
disassembly.mnemonic = instr.mnemonic;
disassembly.operators = instr.op_str;
@@ -71,7 +71,7 @@ namespace hex::plugin::builtin {
disassembly.bytes += hex::format("{0:02X} ", instr.bytes[j]);
disassembly.bytes.pop_back();
this->m_disassembly.push_back(disassembly);
m_disassembly.push_back(disassembly);
usedBytes += instr.size;
}
@@ -96,18 +96,18 @@ namespace hex::plugin::builtin {
ImGuiExt::Header("hex.builtin.view.disassembler.position"_lang, true);
// Draw base address input
ImGuiExt::InputHexadecimal("hex.builtin.view.disassembler.base"_lang, &this->m_baseAddress, ImGuiInputTextFlags_CharsHexadecimal);
ImGuiExt::InputHexadecimal("hex.builtin.view.disassembler.base"_lang, &m_baseAddress, ImGuiInputTextFlags_CharsHexadecimal);
// Draw region selection picker
ui::regionSelectionPicker(&this->m_codeRegion, provider, &this->m_range);
ui::regionSelectionPicker(&m_codeRegion, provider, &m_range);
// Draw settings
{
ImGuiExt::Header("hex.builtin.common.settings"_lang);
// Draw architecture selector
if (ImGui::Combo("hex.builtin.view.disassembler.arch"_lang, reinterpret_cast<int *>(&this->m_architecture), Disassembler::ArchitectureNames.data(), Disassembler::getArchitectureSupportedCount()))
this->m_mode = cs_mode(0);
if (ImGui::Combo("hex.builtin.view.disassembler.arch"_lang, reinterpret_cast<int *>(&m_architecture), Disassembler::ArchitectureNames.data(), Disassembler::getArchitectureSupportedCount()))
m_mode = cs_mode(0);
// Draw sub-settings for each architecture
if (ImGuiExt::BeginBox()) {
@@ -121,7 +121,7 @@ namespace hex::plugin::builtin {
ImGui::NewLine();
// Draw architecture specific settings
switch (this->m_architecture) {
switch (m_architecture) {
case Architecture::ARM:
{
static int mode = CS_MODE_ARM;
@@ -136,7 +136,7 @@ namespace hex::plugin::builtin {
ImGui::SameLine();
ImGui::RadioButton("hex.builtin.view.disassembler.arm.armv8"_lang, &extraMode, CS_MODE_V8);
this->m_mode = cs_mode(mode | extraMode);
m_mode = cs_mode(mode | extraMode);
}
break;
case Architecture::MIPS:
@@ -155,7 +155,7 @@ namespace hex::plugin::builtin {
static bool microMode;
ImGui::Checkbox("hex.builtin.view.disassembler.mips.micro"_lang, &microMode);
this->m_mode = cs_mode(mode | (microMode ? CS_MODE_MICRO : cs_mode(0)));
m_mode = cs_mode(mode | (microMode ? CS_MODE_MICRO : cs_mode(0)));
}
break;
case Architecture::X86:
@@ -167,7 +167,7 @@ namespace hex::plugin::builtin {
ImGui::SameLine();
ImGui::RadioButton("hex.builtin.view.disassembler.64bit"_lang, &mode, CS_MODE_64);
this->m_mode = cs_mode(mode);
m_mode = cs_mode(mode);
}
break;
case Architecture::PPC:
@@ -186,9 +186,9 @@ namespace hex::plugin::builtin {
static bool booke = false;
ImGui::Checkbox("hex.builtin.view.disassembler.ppc.booke"_lang, &booke);
this->m_mode = cs_mode(mode | (qpx ? CS_MODE_QPX : cs_mode(0)) | (spe ? CS_MODE_SPE : cs_mode(0)) | (booke ? CS_MODE_BOOKE : cs_mode(0)));
m_mode = cs_mode(mode | (qpx ? CS_MODE_QPX : cs_mode(0)) | (spe ? CS_MODE_SPE : cs_mode(0)) | (booke ? CS_MODE_BOOKE : cs_mode(0)));
#else
this->m_mode = cs_mode(mode | (qpx ? CS_MODE_QPX : cs_mode(0)));
m_mode = cs_mode(mode | (qpx ? CS_MODE_QPX : cs_mode(0)));
#endif
}
break;
@@ -197,7 +197,7 @@ namespace hex::plugin::builtin {
static bool v9Mode = false;
ImGui::Checkbox("hex.builtin.view.disassembler.sparc.v9"_lang, &v9Mode);
this->m_mode = cs_mode(v9Mode ? CS_MODE_V9 : cs_mode(0));
m_mode = cs_mode(v9Mode ? CS_MODE_V9 : cs_mode(0));
}
break;
#if CS_API_MAJOR >= 5
@@ -211,7 +211,7 @@ namespace hex::plugin::builtin {
static bool compressed = false;
ImGui::Checkbox("hex.builtin.view.disassembler.riscv.compressed"_lang, &compressed);
this->m_mode = cs_mode(mode | (compressed ? CS_MODE_RISCVC : cs_mode(0)));
m_mode = cs_mode(mode | (compressed ? CS_MODE_RISCVC : cs_mode(0)));
}
break;
#endif
@@ -236,7 +236,7 @@ namespace hex::plugin::builtin {
ImGui::EndCombo();
}
this->m_mode = cs_mode(modes[selectedMode].second);
m_mode = cs_mode(modes[selectedMode].second);
}
break;
case Architecture::M680X:
@@ -264,7 +264,7 @@ namespace hex::plugin::builtin {
ImGui::EndCombo();
}
this->m_mode = cs_mode(modes[selectedMode].second);
m_mode = cs_mode(modes[selectedMode].second);
}
break;
#if CS_API_MAJOR >= 5
@@ -290,7 +290,7 @@ namespace hex::plugin::builtin {
ImGui::EndCombo();
}
this->m_mode = cs_mode(modes[selectedMode].second);
m_mode = cs_mode(modes[selectedMode].second);
}
break;
#endif
@@ -302,7 +302,7 @@ namespace hex::plugin::builtin {
ImGui::SameLine();
ImGui::RadioButton("hex.builtin.view.disassembler.bpf.extended"_lang, &mode, CS_MODE_BPF_EXTENDED);
this->m_mode = cs_mode(mode);
m_mode = cs_mode(mode);
}
break;
case Architecture::SH:
@@ -331,7 +331,7 @@ namespace hex::plugin::builtin {
ImGui::SameLine();
ImGui::Checkbox("hex.builtin.view.disassembler.sh.dsp"_lang, &dsp);
this->m_mode = cs_mode(modes[selectionMode].second | (fpu ? CS_MODE_SHFPU : cs_mode(0)) | (dsp ? CS_MODE_SHDSP : cs_mode(0)));
m_mode = cs_mode(modes[selectionMode].second | (fpu ? CS_MODE_SHFPU : cs_mode(0)) | (dsp ? CS_MODE_SHDSP : cs_mode(0)));
}
break;
case Architecture::TRICORE:
@@ -356,7 +356,7 @@ namespace hex::plugin::builtin {
ImGui::EndCombo();
}
this->m_mode = cs_mode(modes[selectionMode].second);
m_mode = cs_mode(modes[selectionMode].second);
}
break;
case Architecture::WASM:
@@ -366,7 +366,7 @@ namespace hex::plugin::builtin {
case Architecture::ARM64:
case Architecture::SYSZ:
case Architecture::XCORE:
this->m_mode = cs_mode(0);
m_mode = cs_mode(0);
break;
}
@@ -375,7 +375,7 @@ namespace hex::plugin::builtin {
}
// Draw disassemble button
ImGui::BeginDisabled(this->m_disassemblerTask.isRunning());
ImGui::BeginDisabled(m_disassemblerTask.isRunning());
{
if (ImGui::Button("hex.builtin.view.disassembler.disassemble"_lang))
this->disassemble();
@@ -383,7 +383,7 @@ namespace hex::plugin::builtin {
ImGui::EndDisabled();
// Draw a spinner if the disassembler is running
if (this->m_disassemblerTask.isRunning()) {
if (m_disassemblerTask.isRunning()) {
ImGui::SameLine();
ImGuiExt::TextSpinner("hex.builtin.view.disassembler.disassembling"_lang);
}
@@ -401,14 +401,14 @@ namespace hex::plugin::builtin {
ImGui::TableSetupColumn("hex.builtin.view.disassembler.disassembly.bytes"_lang);
ImGui::TableSetupColumn("hex.builtin.view.disassembler.disassembly.title"_lang);
if (!this->m_disassemblerTask.isRunning()) {
if (!m_disassemblerTask.isRunning()) {
ImGuiListClipper clipper;
clipper.Begin(this->m_disassembly.size());
clipper.Begin(m_disassembly.size());
ImGui::TableHeadersRow();
while (clipper.Step()) {
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
const auto &instruction = this->m_disassembly[i];
const auto &instruction = m_disassembly[i];
ImGui::TableNextRow();
ImGui::TableNextColumn();

View File

@@ -20,10 +20,10 @@ namespace hex::plugin::builtin {
ImHexApi::HexEditor::addBackgroundHighlightingProvider([this](u64 address, const u8* data, size_t size, bool) -> std::optional<color_t> {
hex::unused(data, size);
if (this->m_searchTask.isRunning())
if (m_searchTask.isRunning())
return { };
if (!this->m_occurrenceTree->overlapping({ address, address + size }).empty())
if (!m_occurrenceTree->overlapping({ address, address + size }).empty())
return HighlightColor();
else
return std::nullopt;
@@ -32,10 +32,10 @@ namespace hex::plugin::builtin {
ImHexApi::HexEditor::addTooltipProvider([this](u64 address, const u8* data, size_t size) {
hex::unused(data, size);
if (this->m_searchTask.isRunning())
if (m_searchTask.isRunning())
return;
auto occurrences = this->m_occurrenceTree->overlapping({ address, address + size });
auto occurrences = m_occurrenceTree->overlapping({ address, address + size });
if (occurrences.empty())
return;
@@ -94,12 +94,12 @@ namespace hex::plugin::builtin {
});
ShortcutManager::addShortcut(this, CTRLCMD + Keys::A, "hex.builtin.view.find.shortcut.select_all", [this] {
if (this->m_filterTask.isRunning())
if (m_filterTask.isRunning())
return;
if (this->m_searchTask.isRunning())
if (m_searchTask.isRunning())
return;
for (auto &occurrence : *this->m_sortedOccurrences)
for (auto &occurrence : *m_sortedOccurrences)
occurrence.selected = true;
});
}
@@ -440,46 +440,46 @@ namespace hex::plugin::builtin {
}
void ViewFind::runSearch() {
Region searchRegion = this->m_searchSettings.region;
Region searchRegion = m_searchSettings.region;
if (this->m_searchSettings.mode == SearchSettings::Mode::Strings)
if (m_searchSettings.mode == SearchSettings::Mode::Strings)
AchievementManager::unlockAchievement("hex.builtin.achievement.find", "hex.builtin.achievement.find.find_strings.name");
else if (this->m_searchSettings.mode == SearchSettings::Mode::Sequence)
else if (m_searchSettings.mode == SearchSettings::Mode::Sequence)
AchievementManager::unlockAchievement("hex.builtin.achievement.find", "hex.builtin.achievement.find.find_specific_string.name");
else if (this->m_searchSettings.mode == SearchSettings::Mode::Value) {
if (this->m_searchSettings.value.inputMin == "250" && this->m_searchSettings.value.inputMax == "1000")
else if (m_searchSettings.mode == SearchSettings::Mode::Value) {
if (m_searchSettings.value.inputMin == "250" && m_searchSettings.value.inputMax == "1000")
AchievementManager::unlockAchievement("hex.builtin.achievement.find", "hex.builtin.achievement.find.find_numeric.name");
}
this->m_occurrenceTree->clear();
m_occurrenceTree->clear();
EventHighlightingChanged::post();
this->m_searchTask = TaskManager::createTask("hex.builtin.view.find.searching", searchRegion.getSize(), [this, settings = this->m_searchSettings, searchRegion](auto &task) {
m_searchTask = TaskManager::createTask("hex.builtin.view.find.searching", searchRegion.getSize(), [this, settings = m_searchSettings, searchRegion](auto &task) {
auto provider = ImHexApi::Provider::get();
switch (settings.mode) {
using enum SearchSettings::Mode;
case Strings:
this->m_foundOccurrences.get(provider) = searchStrings(task, provider, searchRegion, settings.strings);
m_foundOccurrences.get(provider) = searchStrings(task, provider, searchRegion, settings.strings);
break;
case Sequence:
this->m_foundOccurrences.get(provider) = searchSequence(task, provider, searchRegion, settings.bytes);
m_foundOccurrences.get(provider) = searchSequence(task, provider, searchRegion, settings.bytes);
break;
case Regex:
this->m_foundOccurrences.get(provider) = searchRegex(task, provider, searchRegion, settings.regex);
m_foundOccurrences.get(provider) = searchRegex(task, provider, searchRegion, settings.regex);
break;
case BinaryPattern:
this->m_foundOccurrences.get(provider) = searchBinaryPattern(task, provider, searchRegion, settings.binaryPattern);
m_foundOccurrences.get(provider) = searchBinaryPattern(task, provider, searchRegion, settings.binaryPattern);
break;
case Value:
this->m_foundOccurrences.get(provider) = searchValue(task, provider, searchRegion, settings.value);
m_foundOccurrences.get(provider) = searchValue(task, provider, searchRegion, settings.value);
break;
}
this->m_sortedOccurrences.get(provider) = this->m_foundOccurrences.get(provider);
m_sortedOccurrences.get(provider) = m_foundOccurrences.get(provider);
for (const auto &occurrence : this->m_foundOccurrences.get(provider))
this->m_occurrenceTree->insert({ occurrence.region.getStartAddress(), occurrence.region.getEndAddress() }, occurrence);
for (const auto &occurrence : m_foundOccurrences.get(provider))
m_occurrenceTree->insert({ occurrence.region.getStartAddress(), occurrence.region.getEndAddress() }, occurrence);
TaskManager::doLater([] {
EventHighlightingChanged::post();
@@ -492,7 +492,7 @@ namespace hex::plugin::builtin {
provider->read(occurrence.region.getStartAddress(), bytes.data(), bytes.size());
std::string result;
switch (this->m_decodeSettings.mode) {
switch (m_decodeSettings.mode) {
using enum SearchSettings::Mode;
case Value:
@@ -540,7 +540,7 @@ namespace hex::plugin::builtin {
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right) && ImGui::IsItemHovered()) {
ImGui::OpenPopup("FindContextMenu");
target.selected = true;
this->m_replaceBuffer.clear();
m_replaceBuffer.clear();
}
if (ImGui::BeginPopup("FindContextMenu")) {
@@ -551,14 +551,14 @@ namespace hex::plugin::builtin {
if (ImGui::BeginMenu("hex.builtin.view.find.context.replace"_lang)) {
if (ImGui::BeginTabBar("##replace_tabs")) {
if (ImGui::BeginTabItem("hex.builtin.view.find.context.replace.hex"_lang)) {
ImGuiExt::InputTextIcon("##replace_input", ICON_VS_SYMBOL_NAMESPACE, this->m_replaceBuffer);
ImGuiExt::InputTextIcon("##replace_input", ICON_VS_SYMBOL_NAMESPACE, m_replaceBuffer);
ImGui::BeginDisabled(this->m_replaceBuffer.empty());
ImGui::BeginDisabled(m_replaceBuffer.empty());
if (ImGui::Button("hex.builtin.view.find.context.replace"_lang)) {
auto provider = ImHexApi::Provider::get();
auto bytes = parseHexString(this->m_replaceBuffer);
auto bytes = parseHexString(m_replaceBuffer);
for (const auto &occurrence : *this->m_sortedOccurrences) {
for (const auto &occurrence : *m_sortedOccurrences) {
if (occurrence.selected) {
size_t size = std::min<size_t>(occurrence.region.size, bytes.size());
provider->write(occurrence.region.getStartAddress(), bytes.data(), size);
@@ -571,14 +571,14 @@ namespace hex::plugin::builtin {
}
if (ImGui::BeginTabItem("hex.builtin.view.find.context.replace.ascii"_lang)) {
ImGuiExt::InputTextIcon("##replace_input", ICON_VS_SYMBOL_KEY, this->m_replaceBuffer);
ImGuiExt::InputTextIcon("##replace_input", ICON_VS_SYMBOL_KEY, m_replaceBuffer);
ImGui::BeginDisabled(this->m_replaceBuffer.empty());
ImGui::BeginDisabled(m_replaceBuffer.empty());
if (ImGui::Button("hex.builtin.view.find.context.replace"_lang)) {
auto provider = ImHexApi::Provider::get();
auto bytes = decodeByteString(this->m_replaceBuffer);
auto bytes = decodeByteString(m_replaceBuffer);
for (const auto &occurrence : *this->m_sortedOccurrences) {
for (const auto &occurrence : *m_sortedOccurrences) {
if (occurrence.selected) {
size_t size = std::min<size_t>(occurrence.region.size, bytes.size());
provider->write(occurrence.region.getStartAddress(), bytes.data(), size);
@@ -603,9 +603,9 @@ namespace hex::plugin::builtin {
void ViewFind::drawContent() {
auto provider = ImHexApi::Provider::get();
ImGui::BeginDisabled(this->m_searchTask.isRunning());
ImGui::BeginDisabled(m_searchTask.isRunning());
{
ui::regionSelectionPicker(&this->m_searchSettings.region, provider, &this->m_searchSettings.range, true, true);
ui::regionSelectionPicker(&m_searchSettings.region, provider, &m_searchSettings.range, true, true);
ImGui::NewLine();
@@ -618,9 +618,9 @@ namespace hex::plugin::builtin {
hex::format("{} + {}", "hex.builtin.common.encoding.ascii"_lang, "hex.builtin.common.encoding.utf16be"_lang)
};
auto &mode = this->m_searchSettings.mode;
auto &mode = m_searchSettings.mode;
if (ImGui::BeginTabItem("hex.builtin.view.find.strings"_lang)) {
auto &settings = this->m_searchSettings.strings;
auto &settings = m_searchSettings.strings;
mode = SearchSettings::Mode::Strings;
ImGui::InputInt("hex.builtin.view.find.strings.min_length"_lang, &settings.minLength, 1, 1);
@@ -650,23 +650,23 @@ namespace hex::plugin::builtin {
ImGui::Checkbox(hex::format("{} [\\r\\n]", "hex.builtin.view.find.strings.line_feeds"_lang.get()).c_str(), &settings.lineFeeds);
}
this->m_settingsValid = true;
m_settingsValid = true;
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.view.find.sequences"_lang)) {
auto &settings = this->m_searchSettings.bytes;
auto &settings = m_searchSettings.bytes;
mode = SearchSettings::Mode::Sequence;
ImGuiExt::InputTextIcon("hex.builtin.common.value"_lang, ICON_VS_SYMBOL_KEY, settings.sequence);
this->m_settingsValid = !settings.sequence.empty() && !hex::decodeByteString(settings.sequence).empty();
m_settingsValid = !settings.sequence.empty() && !hex::decodeByteString(settings.sequence).empty();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.view.find.regex"_lang)) {
auto &settings = this->m_searchSettings.regex;
auto &settings = m_searchSettings.regex;
mode = SearchSettings::Mode::Regex;
@@ -692,20 +692,20 @@ namespace hex::plugin::builtin {
try {
std::regex regex(settings.pattern);
this->m_settingsValid = true;
m_settingsValid = true;
} catch (const std::regex_error &) {
this->m_settingsValid = false;
m_settingsValid = false;
}
if (settings.pattern.empty())
this->m_settingsValid = false;
m_settingsValid = false;
ImGui::Checkbox("hex.builtin.view.find.regex.full_match"_lang, &settings.fullMatch);
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.view.find.binary_pattern"_lang)) {
auto &settings = this->m_searchSettings.binaryPattern;
auto &settings = m_searchSettings.binaryPattern;
mode = SearchSettings::Mode::BinaryPattern;
@@ -715,12 +715,12 @@ namespace hex::plugin::builtin {
ImGui::SliderScalar("hex.builtin.view.find.binary_pattern.alignment"_lang, ImGuiDataType_U32, &settings.alignment, &min, &max);
settings.pattern = hex::BinaryPattern(settings.input);
this->m_settingsValid = settings.pattern.isValid() && settings.alignment > 0;
m_settingsValid = settings.pattern.isValid() && settings.alignment > 0;
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.view.find.value"_lang)) {
auto &settings = this->m_searchSettings.value;
auto &settings = m_searchSettings.value;
mode = SearchSettings::Mode::Value;
@@ -796,11 +796,11 @@ namespace hex::plugin::builtin {
auto [minValid, min, minSize] = parseNumericValueInput(settings.inputMin, settings.type);
auto [maxValid, max, maxSize] = parseNumericValueInput(settings.inputMax, settings.type);
this->m_settingsValid = minValid && maxValid && minSize == maxSize;
m_settingsValid = minValid && maxValid && minSize == maxSize;
}
if (settings.inputMin.empty())
this->m_settingsValid = false;
m_settingsValid = false;
ImGui::EndTabItem();
}
@@ -810,25 +810,25 @@ namespace hex::plugin::builtin {
ImGui::NewLine();
ImGui::BeginDisabled(!this->m_settingsValid);
ImGui::BeginDisabled(!m_settingsValid);
{
if (ImGui::Button("hex.builtin.view.find.search"_lang)) {
this->runSearch();
this->m_decodeSettings = this->m_searchSettings;
m_decodeSettings = m_searchSettings;
}
}
ImGui::EndDisabled();
ImGui::SameLine();
ImGuiExt::TextFormatted("hex.builtin.view.find.search.entries"_lang, this->m_foundOccurrences->size());
ImGuiExt::TextFormatted("hex.builtin.view.find.search.entries"_lang, m_foundOccurrences->size());
ImGui::BeginDisabled(this->m_foundOccurrences->empty());
ImGui::BeginDisabled(m_foundOccurrences->empty());
{
if (ImGui::Button("hex.builtin.view.find.search.reset"_lang)) {
this->m_foundOccurrences->clear();
this->m_sortedOccurrences->clear();
this->m_occurrenceTree->clear();
m_foundOccurrences->clear();
m_sortedOccurrences->clear();
m_occurrenceTree->clear();
EventHighlightingChanged::post();
}
@@ -841,25 +841,25 @@ namespace hex::plugin::builtin {
ImGui::Separator();
ImGui::NewLine();
auto &currOccurrences = *this->m_sortedOccurrences;
auto &currOccurrences = *m_sortedOccurrences;
ImGui::PushItemWidth(-1);
auto prevFilterLength = this->m_currFilter->length();
if (ImGuiExt::InputTextIcon("##filter", ICON_VS_FILTER, *this->m_currFilter)) {
if (prevFilterLength > this->m_currFilter->length())
*this->m_sortedOccurrences = *this->m_foundOccurrences;
auto prevFilterLength = m_currFilter->length();
if (ImGuiExt::InputTextIcon("##filter", ICON_VS_FILTER, *m_currFilter)) {
if (prevFilterLength > m_currFilter->length())
*m_sortedOccurrences = *m_foundOccurrences;
if (this->m_filterTask.isRunning())
this->m_filterTask.interrupt();
if (m_filterTask.isRunning())
m_filterTask.interrupt();
if (!this->m_currFilter->empty()) {
this->m_filterTask = TaskManager::createTask("Filtering", currOccurrences.size(), [this, provider, &currOccurrences](Task &task) {
if (!m_currFilter->empty()) {
m_filterTask = TaskManager::createTask("Filtering", currOccurrences.size(), [this, provider, &currOccurrences](Task &task) {
u64 progress = 0;
std::erase_if(currOccurrences, [this, provider, &task, &progress](const auto &region) {
task.update(progress);
progress += 1;
return !hex::containsIgnoreCase(this->decodeValue(provider, region), this->m_currFilter.get(provider));
return !hex::containsIgnoreCase(this->decodeValue(provider, region), m_currFilter.get(provider));
});
});
}
@@ -925,7 +925,7 @@ namespace hex::plugin::builtin {
if (ImGui::GetIO().KeyCtrl) {
foundItem.selected = !foundItem.selected;
} else {
for (auto &occurrence : *this->m_sortedOccurrences)
for (auto &occurrence : *m_sortedOccurrences)
occurrence.selected = false;
foundItem.selected = true;
ImHexApi::HexEditor::setSelection(foundItem.region.getStartAddress(), foundItem.region.getSize());

View File

@@ -22,19 +22,19 @@ namespace hex::plugin::builtin {
ImGuiExt::Header(this->getUnlocalizedName(), true);
ImGui::PushItemWidth(-1);
if (ImGui::InputTextMultiline("##input", this->m_input)) {
if (ImGui::InputTextMultiline("##input", m_input)) {
auto provider = std::make_unique<MemoryFileProvider>();
provider->resize(this->m_input.size());
provider->writeRaw(0x00, this->m_input.data(), this->m_input.size());
provider->resize(m_input.size());
provider->writeRaw(0x00, m_input.data(), m_input.size());
this->m_hash.reset();
auto bytes = this->m_hash.get(Region { 0x00, provider->getActualSize() }, provider.get());
m_hash.reset();
auto bytes = m_hash.get(Region { 0x00, provider->getActualSize() }, provider.get());
this->m_result = crypt::encode16(bytes);
m_result = crypt::encode16(bytes);
}
ImGui::NewLine();
ImGui::InputText("##result", this->m_result, ImGuiInputTextFlags_ReadOnly);
ImGui::InputText("##result", m_result, ImGuiInputTextFlags_ReadOnly);
ImGui::PopItemWidth();
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Escape)))
@@ -59,7 +59,7 @@ namespace hex::plugin::builtin {
ViewHashes::ViewHashes() : View::Window("hex.builtin.view.hashes.name") {
EventRegionSelected::subscribe(this, [this](const auto &providerRegion) {
for (auto &function : this->m_hashFunctions.get(providerRegion.getProvider()))
for (auto &function : m_hashFunctions.get(providerRegion.getProvider()))
function.reset();
});
@@ -69,7 +69,7 @@ namespace hex::plugin::builtin {
auto selection = ImHexApi::HexEditor::getSelection();
if (selection.has_value() && ImGui::GetIO().KeyShift) {
auto &hashFunctions = this->m_hashFunctions.get(selection->getProvider());
auto &hashFunctions = m_hashFunctions.get(selection->getProvider());
if (!hashFunctions.empty() && selection.has_value() && selection->overlaps(Region { address, size })) {
ImGui::BeginTooltip();
@@ -117,7 +117,7 @@ namespace hex::plugin::builtin {
return true;
auto data = nlohmann::json::parse(fileContent.begin(), fileContent.end());
this->m_hashFunctions->clear();
m_hashFunctions->clear();
return this->importHashes(provider, data);
},
@@ -140,29 +140,29 @@ namespace hex::plugin::builtin {
void ViewHashes::drawContent() {
const auto &hashes = ContentRegistry::Hashes::impl::getHashes();
if (this->m_selectedHash == nullptr && !hashes.empty()) {
this->m_selectedHash = hashes.front().get();
if (m_selectedHash == nullptr && !hashes.empty()) {
m_selectedHash = hashes.front().get();
}
if (ImGui::BeginCombo("hex.builtin.view.hashes.function"_lang, this->m_selectedHash != nullptr ? Lang(this->m_selectedHash->getUnlocalizedName()) : "")) {
if (ImGui::BeginCombo("hex.builtin.view.hashes.function"_lang, m_selectedHash != nullptr ? Lang(m_selectedHash->getUnlocalizedName()) : "")) {
for (const auto &hash : hashes) {
if (ImGui::Selectable(Lang(hash->getUnlocalizedName()), this->m_selectedHash == hash.get())) {
this->m_selectedHash = hash.get();
this->m_newHashName.clear();
if (ImGui::Selectable(Lang(hash->getUnlocalizedName()), m_selectedHash == hash.get())) {
m_selectedHash = hash.get();
m_newHashName.clear();
}
}
ImGui::EndCombo();
}
if (this->m_newHashName.empty() && this->m_selectedHash != nullptr)
this->m_newHashName = hex::format("{} {}", Lang(this->m_selectedHash->getUnlocalizedName()), static_cast<const char *>("hex.builtin.view.hashes.hash"_lang));
if (m_newHashName.empty() && m_selectedHash != nullptr)
m_newHashName = hex::format("{} {}", Lang(m_selectedHash->getUnlocalizedName()), static_cast<const char *>("hex.builtin.view.hashes.hash"_lang));
if (ImGui::BeginChild("##settings", ImVec2(ImGui::GetContentRegionAvail().x, 200_scaled), true)) {
if (this->m_selectedHash != nullptr) {
if (m_selectedHash != nullptr) {
auto startPos = ImGui::GetCursorPosY();
this->m_selectedHash->draw();
m_selectedHash->draw();
// Check if no elements have been added
if (startPos == ImGui::GetCursorPosY()) {
@@ -173,13 +173,13 @@ namespace hex::plugin::builtin {
ImGui::EndChild();
ImGuiExt::InputTextIcon("##hash_name", ICON_VS_SYMBOL_KEY, this->m_newHashName);
ImGuiExt::InputTextIcon("##hash_name", ICON_VS_SYMBOL_KEY, m_newHashName);
ImGui::SameLine();
ImGui::BeginDisabled(this->m_newHashName.empty() || this->m_selectedHash == nullptr);
ImGui::BeginDisabled(m_newHashName.empty() || m_selectedHash == nullptr);
if (ImGuiExt::IconButton(ICON_VS_ADD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
if (this->m_selectedHash != nullptr) {
this->m_hashFunctions->push_back(this->m_selectedHash->create(this->m_newHashName));
if (m_selectedHash != nullptr) {
m_hashFunctions->push_back(m_selectedHash->create(m_newHashName));
AchievementManager::unlockAchievement("hex.builtin.achievement.misc", "hex.builtin.achievement.misc.create_hash.name");
}
}
@@ -200,8 +200,8 @@ namespace hex::plugin::builtin {
auto selection = ImHexApi::HexEditor::getSelection();
std::optional<u32> indexToRemove;
for (u32 i = 0; i < this->m_hashFunctions->size(); i++) {
auto &function = (*this->m_hashFunctions)[i];
for (u32 i = 0; i < m_hashFunctions->size(); i++) {
auto &function = (*m_hashFunctions)[i];
ImGui::PushID(i);
@@ -242,7 +242,7 @@ namespace hex::plugin::builtin {
}
if (indexToRemove.has_value()) {
this->m_hashFunctions->erase(this->m_hashFunctions->begin() + indexToRemove.value());
m_hashFunctions->erase(m_hashFunctions->begin() + indexToRemove.value());
}
ImGui::EndTable();
@@ -265,7 +265,7 @@ namespace hex::plugin::builtin {
auto newFunction = newHash->create(hash["name"]);
newFunction.getType()->load(hash["settings"]);
this->m_hashFunctions.get(provider).push_back(std::move(newFunction));
m_hashFunctions.get(provider).push_back(std::move(newFunction));
break;
}
}
@@ -277,7 +277,7 @@ namespace hex::plugin::builtin {
bool ViewHashes::exportHashes(prv::Provider *provider, nlohmann::json &json) {
json["hashes"] = nlohmann::json::array();
size_t index = 0;
for (const auto &hashFunction : this->m_hashFunctions.get(provider)) {
for (const auto &hashFunction : m_hashFunctions.get(provider)) {
json["hashes"][index] = {
{ "name", hashFunction.getName() },
{ "type", hashFunction.getType()->getUnlocalizedName() },

View File

@@ -30,39 +30,39 @@ namespace hex::plugin::builtin {
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.file.goto"_lang);
if (ImGui::BeginTabBar("goto_tabs")) {
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.goto.offset.absolute"_lang)) {
this->m_mode = Mode::Absolute;
m_mode = Mode::Absolute;
ImGui::EndTabItem();
}
ImGui::BeginDisabled(!editor->isSelectionValid());
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.goto.offset.relative"_lang)) {
this->m_mode = Mode::Relative;
m_mode = Mode::Relative;
ImGui::EndTabItem();
}
ImGui::EndDisabled();
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.goto.offset.begin"_lang)) {
this->m_mode = Mode::Begin;
m_mode = Mode::Begin;
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.goto.offset.end"_lang)) {
this->m_mode = Mode::End;
m_mode = Mode::End;
ImGui::EndTabItem();
}
if (this->m_requestFocus){
if (m_requestFocus){
ImGui::SetKeyboardFocusHere();
this->m_requestFocus = false;
m_requestFocus = false;
}
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_OPERATOR, this->m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
if (auto result = this->m_evaluator.evaluate(this->m_input); result.has_value()) {
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_OPERATOR, m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
if (auto result = m_evaluator.evaluate(m_input); result.has_value()) {
const auto inputResult = result.value();
u64 newAddress = 0x00;
auto provider = ImHexApi::Provider::get();
switch (this->m_mode) {
switch (m_mode) {
case Mode::Absolute: {
newAddress = inputResult;
}
@@ -115,34 +115,34 @@ namespace hex::plugin::builtin {
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.file.select"_lang);
if (ImGui::BeginTabBar("select_tabs")) {
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.select.offset.region"_lang)) {
u64 inputA = this->m_region.getStartAddress();
u64 inputB = this->m_region.getEndAddress();
u64 inputA = m_region.getStartAddress();
u64 inputB = m_region.getEndAddress();
ImGuiExt::InputHexadecimal("hex.builtin.view.hex_editor.select.offset.begin"_lang, &inputA, ImGuiInputTextFlags_AutoSelectAll);
ImGuiExt::InputHexadecimal("hex.builtin.view.hex_editor.select.offset.end"_lang, &inputB, ImGuiInputTextFlags_AutoSelectAll);
if (inputB < inputA)
inputB = inputA;
this->m_region = { inputA, (inputB - inputA) + 1 };
m_region = { inputA, (inputB - inputA) + 1 };
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.select.offset.size"_lang)) {
u64 inputA = this->m_region.getStartAddress();
u64 inputB = this->m_region.getSize();
u64 inputA = m_region.getStartAddress();
u64 inputB = m_region.getSize();
ImGuiExt::InputHexadecimal("hex.builtin.view.hex_editor.select.offset.begin"_lang, &inputA, ImGuiInputTextFlags_AutoSelectAll);
ImGuiExt::InputHexadecimal("hex.builtin.view.hex_editor.select.offset.size"_lang, &inputB, ImGuiInputTextFlags_AutoSelectAll);
if (inputB <= 0)
inputB = 1;
this->m_region = { inputA, inputB };
m_region = { inputA, inputB };
ImGui::EndTabItem();
}
if (ImGui::Button("hex.builtin.view.hex_editor.select.select"_lang) || (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_Enter)))) {
editor->setSelection(this->m_region.getStartAddress(), this->m_region.getEndAddress());
editor->setSelection(m_region.getStartAddress(), m_region.getEndAddress());
editor->jumpToSelection();
}
@@ -158,8 +158,8 @@ namespace hex::plugin::builtin {
public:
PopupFind() {
EventRegionSelected::subscribe(this, [this](Region region) {
this->m_searchPosition = this->m_nextSearchPosition.value_or(region.getStartAddress());
this->m_nextSearchPosition.reset();
m_searchPosition = m_nextSearchPosition.value_or(region.getStartAddress());
m_nextSearchPosition.reset();
});
}
@@ -173,35 +173,35 @@ namespace hex::plugin::builtin {
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.file.search"_lang);
if (ImGui::BeginTabBar("##find_tabs")) {
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.search.hex"_lang)) {
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_NUMERIC, this->m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_CharsHexadecimal)) {
if (!this->m_input.empty()) {
this->m_shouldSearch = true;
this->m_backwards = false;
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_NUMERIC, m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_CharsHexadecimal)) {
if (!m_input.empty()) {
m_shouldSearch = true;
m_backwards = false;
}
}
this->drawButtons();
if (this->m_shouldSearch) {
searchSequence = crypt::decode16(this->m_input);
if (m_shouldSearch) {
searchSequence = crypt::decode16(m_input);
}
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.view.hex_editor.search.string"_lang)) {
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_KEY, this->m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
if (!this->m_input.empty()) {
this->m_shouldSearch = true;
this->m_backwards = false;
if (ImGuiExt::InputTextIcon("##input", ICON_VS_SYMBOL_KEY, m_input, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) {
if (!m_input.empty()) {
m_shouldSearch = true;
m_backwards = false;
}
}
this->drawButtons();
if (this->m_shouldSearch) {
if (m_shouldSearch) {
searchSequence.clear();
std::copy(this->m_input.begin(), this->m_input.end(), std::back_inserter(searchSequence));
std::copy(m_input.begin(), m_input.end(), std::back_inserter(searchSequence));
if (!searchSequence.empty() && searchSequence.back() == 0x00)
searchSequence.pop_back();
@@ -213,16 +213,16 @@ namespace hex::plugin::builtin {
ImGui::EndTabBar();
}
if (!this->m_searchTask.isRunning() && !searchSequence.empty() && this->m_shouldSearch) {
this->m_searchTask = TaskManager::createTask("hex.builtin.common.processing", ImHexApi::Provider::get()->getActualSize(), [this, editor, searchSequence](auto &) {
if (!m_searchTask.isRunning() && !searchSequence.empty() && m_shouldSearch) {
m_searchTask = TaskManager::createTask("hex.builtin.common.processing", ImHexApi::Provider::get()->getActualSize(), [this, editor, searchSequence](auto &) {
for (u8 retry = 0; retry < 2; retry++) {
auto region = this->findSequence(searchSequence, this->m_backwards);
auto region = this->findSequence(searchSequence, m_backwards);
if (region.has_value()) {
if (editor->getSelection() == region) {
if (this->m_nextSearchPosition.has_value())
this->m_searchPosition = this->m_nextSearchPosition.value();
this->m_nextSearchPosition.reset();
if (m_nextSearchPosition.has_value())
m_searchPosition = m_nextSearchPosition.value();
m_nextSearchPosition.reset();
} else {
TaskManager::doLater([editor, region]{
editor->setSelection(region->getStartAddress(), region->getEndAddress());
@@ -232,12 +232,12 @@ namespace hex::plugin::builtin {
break;
}
} else {
this->m_reachedEnd = true;
m_reachedEnd = true;
}
}
this->m_shouldSearch = false;
this->m_requestFocus = true;
m_shouldSearch = false;
m_requestFocus = true;
});
}
}
@@ -247,42 +247,42 @@ namespace hex::plugin::builtin {
const auto ButtonSize = ImVec2(ImGui::CalcTextSize(ICON_VS_SEARCH).x, ImGui::GetTextLineHeight()) + ImGui::GetStyle().CellPadding * 2;
const auto ButtonColor = ImGui::GetStyleColorVec4(ImGuiCol_Text);
if (this->m_requestFocus) {
if (m_requestFocus) {
ImGui::SetKeyboardFocusHere(-1);
this->m_requestFocus = false;
m_requestFocus = false;
}
ImGui::BeginDisabled(this->m_searchTask.isRunning());
ImGui::BeginDisabled(m_searchTask.isRunning());
{
ImGui::SameLine();
if (ImGuiExt::IconButton(ICON_VS_SEARCH "##search", ButtonColor, ButtonSize)) {
this->m_shouldSearch = true;
this->m_backwards = false;
this->m_reachedEnd = false;
this->m_searchPosition.reset();
this->m_nextSearchPosition.reset();
m_shouldSearch = true;
m_backwards = false;
m_reachedEnd = false;
m_searchPosition.reset();
m_nextSearchPosition.reset();
}
ImGui::BeginDisabled(!this->m_searchPosition.has_value());
ImGui::BeginDisabled(!m_searchPosition.has_value());
{
ImGui::BeginDisabled(this->m_reachedEnd && this->m_backwards);
ImGui::BeginDisabled(m_reachedEnd && m_backwards);
{
if (ImGuiExt::IconButton(ICON_VS_ARROW_UP "##up", ButtonColor, ButtonSize)) {
this->m_shouldSearch = true;
this->m_backwards = true;
this->m_reachedEnd = false;
m_shouldSearch = true;
m_backwards = true;
m_reachedEnd = false;
}
}
ImGui::EndDisabled();
ImGui::SameLine();
ImGui::BeginDisabled(this->m_reachedEnd && !this->m_backwards);
ImGui::BeginDisabled(m_reachedEnd && !m_backwards);
{
if (ImGuiExt::IconButton(ICON_VS_ARROW_DOWN "##down", ButtonColor, ButtonSize)) {
this->m_shouldSearch = true;
this->m_backwards = false;
this->m_reachedEnd = false;
m_shouldSearch = true;
m_backwards = false;
m_reachedEnd = false;
}
}
ImGui::EndDisabled();
@@ -298,7 +298,7 @@ namespace hex::plugin::builtin {
prv::ProviderReader reader(provider);
reader.seek(this->m_searchPosition.value_or(provider->getBaseAddress()));
reader.seek(m_searchPosition.value_or(provider->getBaseAddress()));
constexpr static auto searchFunction = [](const auto &haystackBegin, const auto &haystackEnd, const auto &needleBegin, const auto &needleEnd) {
return std::search(haystackBegin, haystackEnd, std::boyer_moore_horspool_searcher(needleBegin, needleEnd));
@@ -307,16 +307,16 @@ namespace hex::plugin::builtin {
if (!backwards) {
auto occurrence = searchFunction(reader.begin(), reader.end(), sequence.begin(), sequence.end());
if (occurrence != reader.end()) {
this->m_nextSearchPosition = occurrence.getAddress() + sequence.size();
m_nextSearchPosition = occurrence.getAddress() + sequence.size();
return Region { occurrence.getAddress(), sequence.size() };
}
} else {
auto occurrence = searchFunction(reader.rbegin(), reader.rend(), sequence.rbegin(), sequence.rend());
if (occurrence != reader.rend()) {
if (occurrence.getAddress() < sequence.size())
this->m_nextSearchPosition = 0x00;
m_nextSearchPosition = 0x00;
else
this->m_nextSearchPosition = occurrence.getAddress() - sequence.size();
m_nextSearchPosition = occurrence.getAddress() - sequence.size();
return Region { occurrence.getAddress() - (sequence.size() - 1), sequence.size() };
}
@@ -343,15 +343,15 @@ namespace hex::plugin::builtin {
void draw(ViewHexEditor *editor) override {
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.set_base"_lang);
ImGuiExt::InputHexadecimal("##base_address", &this->m_baseAddress);
ImGuiExt::InputHexadecimal("##base_address", &m_baseAddress);
if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter))) {
setBaseAddress(this->m_baseAddress);
setBaseAddress(m_baseAddress);
editor->closePopup();
}
ImGuiExt::ConfirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
[&, this]{
setBaseAddress(this->m_baseAddress);
setBaseAddress(m_baseAddress);
editor->closePopup();
},
[&]{
@@ -377,15 +377,15 @@ namespace hex::plugin::builtin {
void draw(ViewHexEditor *editor) override {
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.set_page_size"_lang);
ImGuiExt::InputHexadecimal("##page_size", &this->m_pageSize);
ImGuiExt::InputHexadecimal("##page_size", &m_pageSize);
if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter))) {
setPageSize(this->m_pageSize);
setPageSize(m_pageSize);
editor->closePopup();
}
ImGuiExt::ConfirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
[&, this]{
setPageSize(this->m_pageSize);
setPageSize(m_pageSize);
editor->closePopup();
},
[&]{
@@ -415,15 +415,15 @@ namespace hex::plugin::builtin {
void draw(ViewHexEditor *editor) override {
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.resize"_lang);
ImGuiExt::InputHexadecimal("##resize", &this->m_size);
ImGuiExt::InputHexadecimal("##resize", &m_size);
if (ImGui::IsItemFocused() && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter))) {
this->resize(this->m_size);
this->resize(m_size);
editor->closePopup();
}
ImGuiExt::ConfirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
[&, this]{
this->resize(this->m_size);
this->resize(m_size);
editor->closePopup();
},
[&]{
@@ -448,12 +448,12 @@ namespace hex::plugin::builtin {
void draw(ViewHexEditor *editor) override {
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.insert"_lang);
ImGuiExt::InputHexadecimal("hex.builtin.common.address"_lang, &this->m_address);
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &this->m_size);
ImGuiExt::InputHexadecimal("hex.builtin.common.address"_lang, &m_address);
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &m_size);
ImGuiExt::ConfirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
[&, this]{
insert(this->m_address, this->m_size);
insert(m_address, m_size);
editor->closePopup();
},
[&]{
@@ -479,12 +479,12 @@ namespace hex::plugin::builtin {
void draw(ViewHexEditor *editor) override {
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.remove"_lang);
ImGuiExt::InputHexadecimal("hex.builtin.common.address"_lang, &this->m_address);
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &this->m_size);
ImGuiExt::InputHexadecimal("hex.builtin.common.address"_lang, &m_address);
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &m_size);
ImGuiExt::ConfirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
[&, this]{
remove(this->m_address, this->m_size);
remove(m_address, m_size);
editor->closePopup();
},
[&]{
@@ -510,16 +510,16 @@ namespace hex::plugin::builtin {
void draw(ViewHexEditor *editor) override {
ImGui::TextUnformatted("hex.builtin.view.hex_editor.menu.edit.fill"_lang);
ImGuiExt::InputHexadecimal("hex.builtin.common.address"_lang, &this->m_address);
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &this->m_size);
ImGuiExt::InputHexadecimal("hex.builtin.common.address"_lang, &m_address);
ImGuiExt::InputHexadecimal("hex.builtin.common.size"_lang, &m_size);
ImGui::Separator();
ImGuiExt::InputTextIcon("hex.builtin.common.bytes"_lang, ICON_VS_SYMBOL_NAMESPACE, this->m_input);
ImGuiExt::InputTextIcon("hex.builtin.common.bytes"_lang, ICON_VS_SYMBOL_NAMESPACE, m_input);
ImGuiExt::ConfirmButtons("hex.builtin.common.set"_lang, "hex.builtin.common.cancel"_lang,
[&, this] {
fill(this->m_address, this->m_size, this->m_input);
fill(m_address, m_size, m_input);
editor->closePopup();
},
[&] {
@@ -558,8 +558,8 @@ namespace hex::plugin::builtin {
/* Hex Editor */
ViewHexEditor::ViewHexEditor() : View::Window("hex.builtin.view.hex_editor.name") {
this->m_hexEditor.setForegroundHighlightCallback([this](u64 address, const u8 *data, size_t size) -> std::optional<color_t> {
if (auto highlight = this->m_foregroundHighlights->find(address); highlight != this->m_foregroundHighlights->end())
m_hexEditor.setForegroundHighlightCallback([this](u64 address, const u8 *data, size_t size) -> std::optional<color_t> {
if (auto highlight = m_foregroundHighlights->find(address); highlight != m_foregroundHighlights->end())
return highlight->second;
std::optional<color_t> result;
@@ -576,13 +576,13 @@ namespace hex::plugin::builtin {
}
if (result.has_value())
this->m_foregroundHighlights->insert({ address, result.value() });
m_foregroundHighlights->insert({ address, result.value() });
return result;
});
this->m_hexEditor.setBackgroundHighlightCallback([this](u64 address, const u8 *data, size_t size) -> std::optional<color_t> {
if (auto highlight = this->m_backgroundHighlights->find(address); highlight != this->m_backgroundHighlights->end())
m_hexEditor.setBackgroundHighlightCallback([this](u64 address, const u8 *data, size_t size) -> std::optional<color_t> {
if (auto highlight = m_backgroundHighlights->find(address); highlight != m_backgroundHighlights->end())
return highlight->second;
std::optional<color_t> result;
@@ -599,12 +599,12 @@ namespace hex::plugin::builtin {
}
if (result.has_value())
this->m_backgroundHighlights->insert({ address, result.value() });
m_backgroundHighlights->insert({ address, result.value() });
return result;
});
this->m_hexEditor.setTooltipCallback([](u64 address, const u8 *data, size_t size) {
m_hexEditor.setTooltipCallback([](u64 address, const u8 *data, size_t size) {
for (const auto &[id, callback] : ImHexApi::HexEditor::impl::getTooltipFunctions()) {
callback(address, data, size);
}
@@ -644,8 +644,8 @@ namespace hex::plugin::builtin {
void ViewHexEditor::drawPopup() {
// Popup windows
if (this->m_shouldOpenPopup) {
this->m_shouldOpenPopup = false;
if (m_shouldOpenPopup) {
m_shouldOpenPopup = false;
ImGui::OpenPopup("##hex_editor_popup");
}
@@ -663,8 +663,8 @@ namespace hex::plugin::builtin {
justOpened = false;
}
if (this->m_currPopup != nullptr)
this->m_currPopup->draw(this);
if (m_currPopup != nullptr)
m_currPopup->draw(this);
else
ImGui::CloseCurrentPopup();
@@ -680,9 +680,9 @@ namespace hex::plugin::builtin {
}
void ViewHexEditor::drawContent() {
this->m_hexEditor.setProvider(ImHexApi::Provider::get());
m_hexEditor.setProvider(ImHexApi::Provider::get());
this->m_hexEditor.draw();
m_hexEditor.draw();
this->drawPopup();
}
@@ -771,185 +771,185 @@ namespace hex::plugin::builtin {
// Remove selection
ShortcutManager::addShortcut(this, Keys::Escape, "hex.builtin.view.hex_editor.shortcut.remove_selection", [this] {
auto provider = ImHexApi::Provider::get();
this->m_selectionStart->reset();
this->m_selectionEnd->reset();
m_selectionStart->reset();
m_selectionEnd->reset();
this->m_hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
m_hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion{ Region::Invalid(), provider });
});
ShortcutManager::addShortcut(this, Keys::Enter, "hex.builtin.view.hex_editor.shortcut.enter_editing", [this] {
if (auto cursor = this->m_hexEditor.getCursorPosition(); cursor.has_value())
this->m_hexEditor.setEditingAddress(cursor.value());
if (auto cursor = m_hexEditor.getCursorPosition(); cursor.has_value())
m_hexEditor.setEditingAddress(cursor.value());
});
// Move cursor around
ShortcutManager::addShortcut(this, Keys::Up, "hex.builtin.view.hex_editor.shortcut.cursor_up", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
if (cursor >= this->m_hexEditor.getBytesPerRow()) {
auto pos = cursor - this->m_hexEditor.getBytesPerRow();
if (cursor >= m_hexEditor.getBytesPerRow()) {
auto pos = cursor - m_hexEditor.getBytesPerRow();
this->setSelection(pos, pos);
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
m_hexEditor.scrollToSelection();
m_hexEditor.jumpIfOffScreen();
}
});
ShortcutManager::addShortcut(this, Keys::Down, "hex.builtin.view.hex_editor.shortcut.cursor_down", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto pos = cursor + this->m_hexEditor.getBytesPerRow();
auto pos = cursor + m_hexEditor.getBytesPerRow();
this->setSelection(pos, pos);
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
m_hexEditor.scrollToSelection();
m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, Keys::Left, "hex.builtin.view.hex_editor.shortcut.cursor_left", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
if (cursor > 0) {
auto pos = cursor - this->m_hexEditor.getBytesPerCell();
auto pos = cursor - m_hexEditor.getBytesPerCell();
this->setSelection(pos, pos);
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
m_hexEditor.scrollToSelection();
m_hexEditor.jumpIfOffScreen();
}
});
ShortcutManager::addShortcut(this, Keys::Right, "hex.builtin.view.hex_editor.shortcut.cursor_right", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto pos = cursor + this->m_hexEditor.getBytesPerCell();
auto pos = cursor + m_hexEditor.getBytesPerCell();
this->setSelection(pos, pos);
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
m_hexEditor.scrollToSelection();
m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, Keys::PageUp, "hex.builtin.view.hex_editor.shortcut.cursor_page_up", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
u64 visibleByteCount = this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount();
u64 visibleByteCount = m_hexEditor.getBytesPerRow() * m_hexEditor.getVisibleRowCount();
if (cursor >= visibleByteCount) {
auto pos = cursor - visibleByteCount;
this->setSelection(pos, (pos + this->m_hexEditor.getBytesPerCell()) - 1);
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
this->setSelection(pos, (pos + m_hexEditor.getBytesPerCell()) - 1);
m_hexEditor.scrollToSelection();
m_hexEditor.jumpIfOffScreen();
}
});
ShortcutManager::addShortcut(this, Keys::PageDown, "hex.builtin.view.hex_editor.shortcut.cursor_page_down", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto pos = cursor + (this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount());
this->setSelection(pos, (pos + this->m_hexEditor.getBytesPerCell()) - 1);
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
auto pos = cursor + (m_hexEditor.getBytesPerRow() * m_hexEditor.getVisibleRowCount());
this->setSelection(pos, (pos + m_hexEditor.getBytesPerCell()) - 1);
m_hexEditor.scrollToSelection();
m_hexEditor.jumpIfOffScreen();
});
// Move selection around
ShortcutManager::addShortcut(this, SHIFT + Keys::Up, "hex.builtin.view.hex_editor.shortcut.selection_up", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition();
auto cursor = m_hexEditor.getCursorPosition();
if (cursor != selection.getStartAddress()) {
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow();
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), m_hexEditor.getBytesPerRow()) - m_hexEditor.getBytesPerRow();
setSelection(selection.getStartAddress(), newCursor);
this->m_hexEditor.setCursorPosition(newCursor);
m_hexEditor.setCursorPosition(newCursor);
} else {
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow();
auto newCursor = std::max<u64>(cursor.value_or(selection.getEndAddress()), m_hexEditor.getBytesPerRow()) - m_hexEditor.getBytesPerRow();
setSelection(newCursor, selection.getEndAddress());
this->m_hexEditor.setCursorPosition(newCursor);
m_hexEditor.setCursorPosition(newCursor);
}
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
m_hexEditor.scrollToSelection();
m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, SHIFT + Keys::Down, "hex.builtin.view.hex_editor.shortcut.selection_down", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition();
auto cursor = m_hexEditor.getCursorPosition();
if (cursor != selection.getStartAddress()) {
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerRow();
auto newCursor = cursor.value_or(selection.getEndAddress()) + m_hexEditor.getBytesPerRow();
setSelection(selection.getStartAddress(), newCursor);
this->m_hexEditor.setCursorPosition(newCursor);
m_hexEditor.setCursorPosition(newCursor);
} else {
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerRow();
auto newCursor = cursor.value_or(selection.getEndAddress()) + m_hexEditor.getBytesPerRow();
setSelection(newCursor, selection.getEndAddress());
this->m_hexEditor.setCursorPosition(newCursor);
m_hexEditor.setCursorPosition(newCursor);
}
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
m_hexEditor.scrollToSelection();
m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, SHIFT + Keys::Left, "hex.builtin.view.hex_editor.shortcut.selection_left", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition();
auto cursor = m_hexEditor.getCursorPosition();
if (cursor != selection.getStartAddress()) {
auto newCursor = cursor.value_or(selection.getEndAddress()) - this->m_hexEditor.getBytesPerCell();
auto newCursor = cursor.value_or(selection.getEndAddress()) - m_hexEditor.getBytesPerCell();
setSelection(selection.getStartAddress(), newCursor);
this->m_hexEditor.setCursorPosition(newCursor);
m_hexEditor.setCursorPosition(newCursor);
} else {
auto newCursor = cursor.value_or(selection.getEndAddress()) - this->m_hexEditor.getBytesPerCell();
auto newCursor = cursor.value_or(selection.getEndAddress()) - m_hexEditor.getBytesPerCell();
setSelection(newCursor, selection.getEndAddress());
this->m_hexEditor.setCursorPosition(newCursor);
m_hexEditor.setCursorPosition(newCursor);
}
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
m_hexEditor.scrollToSelection();
m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, SHIFT + Keys::Right, "hex.builtin.view.hex_editor.shortcut.selection_right", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition();
auto cursor = m_hexEditor.getCursorPosition();
if (cursor != selection.getStartAddress()) {
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerCell();
auto newCursor = cursor.value_or(selection.getEndAddress()) + m_hexEditor.getBytesPerCell();
setSelection(selection.getStartAddress(), newCursor);
this->m_hexEditor.setCursorPosition(newCursor);
m_hexEditor.setCursorPosition(newCursor);
} else {
auto newCursor = cursor.value_or(selection.getEndAddress()) + this->m_hexEditor.getBytesPerCell();
auto newCursor = cursor.value_or(selection.getEndAddress()) + m_hexEditor.getBytesPerCell();
setSelection(newCursor, selection.getEndAddress());
this->m_hexEditor.setCursorPosition(newCursor);
m_hexEditor.setCursorPosition(newCursor);
}
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
m_hexEditor.scrollToSelection();
m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, SHIFT + Keys::PageUp, "hex.builtin.view.hex_editor.shortcut.selection_page_up", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
if (cursor != selection.getStartAddress()) {
auto newCursor = std::max<u64>(cursor, this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount();
auto newCursor = std::max<u64>(cursor, m_hexEditor.getBytesPerRow()) - m_hexEditor.getBytesPerRow() * m_hexEditor.getVisibleRowCount();
setSelection(selection.getStartAddress(), newCursor);
this->m_hexEditor.setCursorPosition(newCursor);
m_hexEditor.setCursorPosition(newCursor);
} else {
auto newCursor = std::max<u64>(cursor, this->m_hexEditor.getBytesPerRow()) - this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount();
auto newCursor = std::max<u64>(cursor, m_hexEditor.getBytesPerRow()) - m_hexEditor.getBytesPerRow() * m_hexEditor.getVisibleRowCount();
setSelection(newCursor, selection.getEndAddress());
this->m_hexEditor.setCursorPosition(newCursor);
m_hexEditor.setCursorPosition(newCursor);
}
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
m_hexEditor.scrollToSelection();
m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, SHIFT + Keys::PageDown, "hex.builtin.view.hex_editor.shortcut.selection_page_down", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
auto cursor = m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
if (cursor != selection.getStartAddress()) {
auto newCursor = cursor + (this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount());
auto newCursor = cursor + (m_hexEditor.getBytesPerRow() * m_hexEditor.getVisibleRowCount());
setSelection(selection.getStartAddress(), newCursor);
this->m_hexEditor.setCursorPosition(newCursor);
m_hexEditor.setCursorPosition(newCursor);
} else {
auto newCursor = cursor + (this->m_hexEditor.getBytesPerRow() * this->m_hexEditor.getVisibleRowCount());
auto newCursor = cursor + (m_hexEditor.getBytesPerRow() * m_hexEditor.getVisibleRowCount());
setSelection(newCursor, selection.getEndAddress());
this->m_hexEditor.setCursorPosition(newCursor);
m_hexEditor.setCursorPosition(newCursor);
}
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
m_hexEditor.scrollToSelection();
m_hexEditor.jumpIfOffScreen();
});
}
@@ -959,8 +959,8 @@ namespace hex::plugin::builtin {
auto provider = ImHexApi::Provider::get();
if (region == Region::Invalid()) {
this->m_selectionStart->reset();
this->m_selectionEnd->reset();
m_selectionStart->reset();
m_selectionEnd->reset();
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion({ Region::Invalid(), nullptr }));
return;
@@ -979,26 +979,26 @@ namespace hex::plugin::builtin {
EventProviderChanged::subscribe(this, [this](auto *oldProvider, auto *newProvider) {
if (oldProvider != nullptr) {
auto selection = this->m_hexEditor.getSelection();
auto selection = m_hexEditor.getSelection();
if (selection != Region::Invalid()) {
this->m_selectionStart.get(oldProvider) = selection.getStartAddress();
this->m_selectionEnd.get(oldProvider) = selection.getEndAddress();
this->m_scrollPosition.get(oldProvider) = this->m_hexEditor.getScrollPosition();
m_selectionStart.get(oldProvider) = selection.getStartAddress();
m_selectionEnd.get(oldProvider) = selection.getEndAddress();
m_scrollPosition.get(oldProvider) = m_hexEditor.getScrollPosition();
}
}
this->m_hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
this->m_hexEditor.setScrollPosition(0);
m_hexEditor.setSelectionUnchecked(std::nullopt, std::nullopt);
m_hexEditor.setScrollPosition(0);
if (newProvider != nullptr) {
this->m_hexEditor.setSelectionUnchecked(this->m_selectionStart.get(newProvider), this->m_selectionEnd.get(newProvider));
this->m_hexEditor.setScrollPosition(this->m_scrollPosition.get(newProvider));
m_hexEditor.setSelectionUnchecked(m_selectionStart.get(newProvider), m_selectionEnd.get(newProvider));
m_hexEditor.setScrollPosition(m_scrollPosition.get(newProvider));
} else {
ImHexApi::HexEditor::clearSelection();
}
this->m_hexEditor.forceUpdateScrollPosition();
m_hexEditor.forceUpdateScrollPosition();
if (isSelectionValid()) {
EventRegionSelected::post(ImHexApi::HexEditor::ProviderRegion{ this->getSelection(), newProvider });
}
@@ -1009,8 +1009,8 @@ namespace hex::plugin::builtin {
});
EventHighlightingChanged::subscribe(this, [this]{
this->m_foregroundHighlights->clear();
this->m_backgroundHighlights->clear();
m_foregroundHighlights->clear();
m_backgroundHighlights->clear();
});
ProjectFile::registerPerProviderHandler({
@@ -1022,12 +1022,12 @@ namespace hex::plugin::builtin {
auto content = tar.readString(basePath);
if (!content.empty())
this->m_hexEditor.setCustomEncoding(EncodingFile(hex::EncodingFile::Type::Thingy, content));
m_hexEditor.setCustomEncoding(EncodingFile(hex::EncodingFile::Type::Thingy, content));
return true;
},
.store = [this](prv::Provider *, const std::fs::path &basePath, Tar &tar) {
if (const auto &encoding = this->m_hexEditor.getCustomEncoding(); encoding.has_value()) {
if (const auto &encoding = m_hexEditor.getCustomEncoding(); encoding.has_value()) {
auto content = encoding->getTableContent();
if (!content.empty())
@@ -1086,7 +1086,7 @@ namespace hex::plugin::builtin {
ImHexApi::Provider::markDirty();
TaskManager::doLater([this, encoding = std::move(encoding)] mutable {
this->m_hexEditor.setCustomEncoding(std::move(encoding));
m_hexEditor.setCustomEncoding(std::move(encoding));
});
});
});
@@ -1161,12 +1161,12 @@ namespace hex::plugin::builtin {
Shortcut::None,
[this] {
auto selection = ImHexApi::HexEditor::getSelection();
auto customEncoding = this->m_hexEditor.getCustomEncoding();
auto customEncoding = m_hexEditor.getCustomEncoding();
if (customEncoding.has_value() && selection.has_value() && selection != Region::Invalid())
copyCustomEncoding(*customEncoding, *selection);
},
[this] {
return ImHexApi::HexEditor::isSelectionValid() && this->m_hexEditor.getCustomEncoding().has_value();
return ImHexApi::HexEditor::isSelectionValid() && m_hexEditor.getCustomEncoding().has_value();
});
ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.edit", "hex.builtin.view.hex_editor.menu.edit.copy_as" }, 1350);

View File

@@ -118,7 +118,7 @@ namespace hex::plugin::builtin {
.load = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) -> bool {
const auto json = nlohmann::json::parse(tar.readString(basePath));
auto &rules = this->m_rules.get(provider);
auto &rules = m_rules.get(provider);
rules.clear();
for (const auto &entry : json) {
@@ -140,7 +140,7 @@ namespace hex::plugin::builtin {
},
.store = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) -> bool {
nlohmann::json result = nlohmann::json::array();
for (const auto &rule : this->m_rules.get(provider)) {
for (const auto &rule : m_rules.get(provider)) {
nlohmann::json content;
content["name"] = rule.name;
@@ -163,9 +163,9 @@ namespace hex::plugin::builtin {
});
// Initialize the selected rule iterators to point to the end of the rules lists
this->m_selectedRule = this->m_rules->end();
m_selectedRule = m_rules->end();
EventProviderCreated::subscribe([this](prv::Provider *provider) {
this->m_selectedRule.get(provider) = this->m_rules.get(provider).end();
m_selectedRule.get(provider) = m_rules.get(provider).end();
});
}
@@ -175,7 +175,7 @@ namespace hex::plugin::builtin {
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 1);
ImGui::TableSetupColumn("Enabled", ImGuiTableColumnFlags_WidthFixed, 10_scaled);
for (auto it = this->m_rules->begin(); it != this->m_rules->end(); ++it) {
for (auto it = m_rules->begin(); it != m_rules->end(); ++it) {
auto &rule = *it;
ImGui::TableNextRow();
@@ -184,8 +184,8 @@ namespace hex::plugin::builtin {
// Add a selectable for each rule to be able to switch between them
ImGui::PushID(&rule);
ImGui::BeginDisabled(!rule.enabled);
if (ImGui::Selectable(rule.name.c_str(), this->m_selectedRule == it, ImGuiSelectableFlags_SpanAvailWidth)) {
this->m_selectedRule = it;
if (ImGui::Selectable(rule.name.c_str(), m_selectedRule == it, ImGuiSelectableFlags_SpanAvailWidth)) {
m_selectedRule = it;
}
ImGui::EndDisabled();
@@ -205,21 +205,21 @@ namespace hex::plugin::builtin {
// Draw button to add a new rule
if (ImGuiExt::DimmedIconButton(ICON_VS_ADD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
this->m_rules->emplace_back("hex.builtin.view.highlight_rules.new_rule"_lang);
m_rules->emplace_back("hex.builtin.view.highlight_rules.new_rule"_lang);
if (this->m_selectedRule == this->m_rules->end())
this->m_selectedRule = this->m_rules->begin();
if (m_selectedRule == m_rules->end())
m_selectedRule = m_rules->begin();
}
ImGui::SameLine();
// Draw button to remove the selected rule
ImGui::BeginDisabled(this->m_selectedRule == this->m_rules->end());
ImGui::BeginDisabled(m_selectedRule == m_rules->end());
if (ImGuiExt::DimmedIconButton(ICON_VS_REMOVE, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
auto next = std::next(*this->m_selectedRule);
this->m_rules->erase(*this->m_selectedRule);
this->m_selectedRule = next;
auto next = std::next(*m_selectedRule);
m_rules->erase(*m_selectedRule);
m_selectedRule = next;
}
ImGui::EndDisabled();
}
@@ -228,14 +228,14 @@ namespace hex::plugin::builtin {
void ViewHighlightRules::drawRulesConfig() {
ImGuiExt::BeginSubWindow("hex.builtin.view.highlight_rules.config"_lang, ImGui::GetContentRegionAvail());
{
if (this->m_selectedRule != this->m_rules->end()) {
if (m_selectedRule != m_rules->end()) {
// Draw text input field for the rule name
ImGui::PushItemWidth(-1);
ImGui::InputTextWithHint("##name", "Name", this->m_selectedRule.get()->name);
ImGui::InputTextWithHint("##name", "Name", m_selectedRule.get()->name);
ImGui::PopItemWidth();
auto &rule = *this->m_selectedRule;
auto &rule = *m_selectedRule;
// Draw a table containing all the expressions for the selected rule
ImGui::PushID(&rule);
@@ -282,7 +282,7 @@ namespace hex::plugin::builtin {
// Draw button to add a new expression
if (ImGuiExt::DimmedIconButton(ICON_VS_ADD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
this->m_selectedRule.get()->addExpression(Rule::Expression("", {}));
m_selectedRule.get()->addExpression(Rule::Expression("", {}));
ImHexApi::Provider::markDirty();
}

View File

@@ -22,27 +22,27 @@ namespace hex::plugin::builtin {
ViewInformation::ViewInformation() : View::Window("hex.builtin.view.information.name") {
EventDataChanged::subscribe(this, [this] {
this->m_dataValid = false;
this->m_plainTextCharacterPercentage = -1.0;
this->m_averageEntropy = -1.0;
this->m_highestBlockEntropy = -1.0;
this->m_blockSize = 0;
this->m_dataMimeType.clear();
this->m_dataDescription.clear();
this->m_analyzedRegion = { 0, 0 };
m_dataValid = false;
m_plainTextCharacterPercentage = -1.0;
m_averageEntropy = -1.0;
m_highestBlockEntropy = -1.0;
m_blockSize = 0;
m_dataMimeType.clear();
m_dataDescription.clear();
m_analyzedRegion = { 0, 0 };
});
EventRegionSelected::subscribe(this, [this](Region region) {
// Set the position of the diagram relative to the place where
// the user clicked inside the hex editor view
if (this->m_blockSize != 0) {
this->m_byteTypesDistribution.setHandlePosition(region.getStartAddress());
this->m_chunkBasedEntropy.setHandlePosition(region.getStartAddress());
if (m_blockSize != 0) {
m_byteTypesDistribution.setHandlePosition(region.getStartAddress());
m_chunkBasedEntropy.setHandlePosition(region.getStartAddress());
}
});
EventProviderDeleted::subscribe(this, [this](const auto*) {
this->m_dataValid = false;
m_dataValid = false;
});
ContentRegistry::FileHandler::add({ ".mgc" }, [](const auto &path) {
@@ -66,72 +66,72 @@ namespace hex::plugin::builtin {
void ViewInformation::analyze() {
AchievementManager::unlockAchievement("hex.builtin.achievement.misc", "hex.builtin.achievement.misc.analyze_file.name");
this->m_analyzerTask = TaskManager::createTask("hex.builtin.view.information.analyzing", 0, [this](auto &task) {
m_analyzerTask = TaskManager::createTask("hex.builtin.view.information.analyzing", 0, [this](auto &task) {
auto provider = ImHexApi::Provider::get();
if ((this->m_analyzedRegion.getStartAddress() >= this->m_analyzedRegion.getEndAddress()) || (this->m_analyzedRegion.getEndAddress() > provider->getActualSize())) {
this->m_analyzedRegion = { provider->getBaseAddress(), provider->getActualSize() };
if ((m_analyzedRegion.getStartAddress() >= m_analyzedRegion.getEndAddress()) || (m_analyzedRegion.getEndAddress() > provider->getActualSize())) {
m_analyzedRegion = { provider->getBaseAddress(), provider->getActualSize() };
}
if (this->m_inputChunkSize == 0) {
this->m_inputChunkSize = 256;
if (m_inputChunkSize == 0) {
m_inputChunkSize = 256;
}
task.setMaxValue(this->m_analyzedRegion.getSize());
task.setMaxValue(m_analyzedRegion.getSize());
{
magic::compile();
this->m_dataDescription = magic::getDescription(provider);
this->m_dataMimeType = magic::getMIMEType(provider);
m_dataDescription = magic::getDescription(provider);
m_dataMimeType = magic::getMIMEType(provider);
}
{
this->m_blockSize = std::max<u32>(std::ceil(provider->getActualSize() / 2048.0F), 256);
m_blockSize = std::max<u32>(std::ceil(provider->getActualSize() / 2048.0F), 256);
this->m_averageEntropy = -1.0;
this->m_highestBlockEntropy = -1.0;
this->m_plainTextCharacterPercentage = -1.0;
m_averageEntropy = -1.0;
m_highestBlockEntropy = -1.0;
m_plainTextCharacterPercentage = -1.0;
// Setup / start each analysis
this->m_byteDistribution.reset();
this->m_digram.reset(this->m_analysisRegion.getSize());
this->m_layeredDistribution.reset(this->m_analysisRegion.getSize());
this->m_byteTypesDistribution.reset(this->m_analysisRegion.getStartAddress(), this->m_analysisRegion.getEndAddress(), provider->getBaseAddress(), provider->getActualSize());
this->m_chunkBasedEntropy.reset(this->m_inputChunkSize, this->m_analysisRegion.getStartAddress(), this->m_analysisRegion.getEndAddress(),
m_byteDistribution.reset();
m_digram.reset(m_analysisRegion.getSize());
m_layeredDistribution.reset(m_analysisRegion.getSize());
m_byteTypesDistribution.reset(m_analysisRegion.getStartAddress(), m_analysisRegion.getEndAddress(), provider->getBaseAddress(), provider->getActualSize());
m_chunkBasedEntropy.reset(m_inputChunkSize, m_analysisRegion.getStartAddress(), m_analysisRegion.getEndAddress(),
provider->getBaseAddress(), provider->getActualSize());
// Create a handle to the file
auto reader = prv::ProviderReader(provider);
reader.seek(this->m_analysisRegion.getStartAddress());
reader.setEndAddress(this->m_analysisRegion.getEndAddress());
reader.seek(m_analysisRegion.getStartAddress());
reader.setEndAddress(m_analysisRegion.getEndAddress());
this->m_analyzedRegion = this->m_analysisRegion;
m_analyzedRegion = m_analysisRegion;
u64 count = 0;
// Loop over each byte of the selection and update each analysis
// one byte at a time to process the file only once
for (u8 byte : reader) {
this->m_byteDistribution.update(byte);
this->m_byteTypesDistribution.update(byte);
this->m_chunkBasedEntropy.update(byte);
this->m_layeredDistribution.update(byte);
this->m_digram.update(byte);
m_byteDistribution.update(byte);
m_byteTypesDistribution.update(byte);
m_chunkBasedEntropy.update(byte);
m_layeredDistribution.update(byte);
m_digram.update(byte);
++count;
task.update(count);
}
this->m_averageEntropy = this->m_chunkBasedEntropy.calculateEntropy(this->m_byteDistribution.get(), this->m_analyzedRegion.getSize());
this->m_highestBlockEntropy = this->m_chunkBasedEntropy.getHighestEntropyBlockValue();
this->m_highestBlockEntropyAddress = this->m_chunkBasedEntropy.getHighestEntropyBlockAddress();
this->m_lowestBlockEntropy = this->m_chunkBasedEntropy.getLowestEntropyBlockValue();
this->m_lowestBlockEntropyAddress = this->m_chunkBasedEntropy.getLowestEntropyBlockAddress();
this->m_plainTextCharacterPercentage = this->m_byteTypesDistribution.getPlainTextCharacterPercentage();
m_averageEntropy = m_chunkBasedEntropy.calculateEntropy(m_byteDistribution.get(), m_analyzedRegion.getSize());
m_highestBlockEntropy = m_chunkBasedEntropy.getHighestEntropyBlockValue();
m_highestBlockEntropyAddress = m_chunkBasedEntropy.getHighestEntropyBlockAddress();
m_lowestBlockEntropy = m_chunkBasedEntropy.getLowestEntropyBlockValue();
m_lowestBlockEntropyAddress = m_chunkBasedEntropy.getLowestEntropyBlockAddress();
m_plainTextCharacterPercentage = m_byteTypesDistribution.getPlainTextCharacterPercentage();
}
this->m_dataValid = true;
m_dataValid = true;
});
}
@@ -140,7 +140,7 @@ namespace hex::plugin::builtin {
auto provider = ImHexApi::Provider::get();
if (ImHexApi::Provider::isValid() && provider->isReadable()) {
ImGui::BeginDisabled(this->m_analyzerTask.isRunning());
ImGui::BeginDisabled(m_analyzerTask.isRunning());
ImGuiExt::BeginSubWindow("hex.builtin.common.settings"_lang);
{
if (ImGui::BeginTable("SettingsTable", 2, ImGuiTableFlags_BordersInner | ImGuiTableFlags_SizingFixedSame, ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
@@ -148,10 +148,10 @@ namespace hex::plugin::builtin {
ImGui::TableSetupColumn("Right", ImGuiTableColumnFlags_WidthStretch, 0.5F);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ui::regionSelectionPicker(&this->m_analysisRegion, provider, &this->m_selectionType, false);
ui::regionSelectionPicker(&m_analysisRegion, provider, &m_selectionType, false);
ImGui::TableNextColumn();
ImGuiExt::InputHexadecimal("hex.builtin.view.information.block_size"_lang, &this->m_inputChunkSize);
ImGuiExt::InputHexadecimal("hex.builtin.view.information.block_size"_lang, &m_inputChunkSize);
ImGui::EndTable();
}
@@ -164,13 +164,13 @@ namespace hex::plugin::builtin {
ImGuiExt::EndSubWindow();
ImGui::EndDisabled();
if (this->m_analyzerTask.isRunning()) {
if (m_analyzerTask.isRunning()) {
ImGuiExt::TextSpinner("hex.builtin.view.information.analyzing"_lang);
} else {
ImGui::NewLine();
}
if (!this->m_analyzerTask.isRunning() && this->m_dataValid) {
if (!m_analyzerTask.isRunning() && m_dataValid) {
// Provider information
ImGuiExt::Header("hex.builtin.view.information.provider_information"_lang, true);
@@ -191,13 +191,13 @@ namespace hex::plugin::builtin {
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.region"_lang);
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("0x{:X} - 0x{:X}", this->m_analyzedRegion.getStartAddress(), this->m_analyzedRegion.getEndAddress());
ImGuiExt::TextFormatted("0x{:X} - 0x{:X}", m_analyzedRegion.getStartAddress(), m_analyzedRegion.getEndAddress());
ImGui::EndTable();
}
// Magic information
if (!(this->m_dataDescription.empty() && this->m_dataMimeType.empty())) {
if (!(m_dataDescription.empty() && m_dataMimeType.empty())) {
ImGuiExt::Header("hex.builtin.view.information.magic"_lang);
if (ImGui::BeginTable("magic", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg)) {
@@ -206,31 +206,31 @@ namespace hex::plugin::builtin {
ImGui::TableNextRow();
if (!this->m_dataDescription.empty()) {
if (!m_dataDescription.empty()) {
ImGui::TableNextColumn();
ImGui::TextUnformatted("hex.builtin.view.information.description"_lang);
ImGui::TableNextColumn();
if (this->m_dataDescription == "data") {
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{} ({})", "hex.builtin.view.information.octet_stream_text"_lang, this->m_dataDescription);
if (m_dataDescription == "data") {
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{} ({})", "hex.builtin.view.information.octet_stream_text"_lang, m_dataDescription);
} else {
ImGuiExt::TextFormattedWrapped("{}", this->m_dataDescription);
ImGuiExt::TextFormattedWrapped("{}", m_dataDescription);
}
}
if (!this->m_dataMimeType.empty()) {
if (!m_dataMimeType.empty()) {
ImGui::TableNextColumn();
ImGui::TextUnformatted("hex.builtin.view.information.mime"_lang);
ImGui::TableNextColumn();
if (this->m_dataMimeType == "application/octet-stream") {
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{} ({})", "hex.builtin.view.information.octet_stream_text"_lang, this->m_dataMimeType);
if (m_dataMimeType == "application/octet-stream") {
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{} ({})", "hex.builtin.view.information.octet_stream_text"_lang, m_dataMimeType);
ImGui::SameLine();
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGuiExt::HelpHover("hex.builtin.view.information.octet_stream_warning"_lang);
ImGui::PopStyleVar();
} else {
ImGuiExt::TextFormatted("{}", this->m_dataMimeType);
ImGuiExt::TextFormatted("{}", m_dataMimeType);
}
}
@@ -241,7 +241,7 @@ namespace hex::plugin::builtin {
}
// Information analysis
if (this->m_analyzedRegion.getSize() > 0) {
if (m_analyzedRegion.getSize() > 0) {
ImGuiExt::Header("hex.builtin.view.information.info_analysis"_lang);
@@ -250,14 +250,14 @@ namespace hex::plugin::builtin {
// Display byte distribution analysis
ImGui::TextUnformatted("hex.builtin.view.information.distribution"_lang);
this->m_byteDistribution.draw(
m_byteDistribution.draw(
ImVec2(-1, 0),
ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect
);
// Display byte types distribution analysis
ImGui::TextUnformatted("hex.builtin.view.information.byte_types"_lang);
this->m_byteTypesDistribution.draw(
m_byteTypesDistribution.draw(
ImVec2(-1, 0),
ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect,
true
@@ -265,7 +265,7 @@ namespace hex::plugin::builtin {
// Display chunk-based entropy analysis
ImGui::TextUnformatted("hex.builtin.view.information.entropy"_lang);
this->m_chunkBasedEntropy.draw(
m_chunkBasedEntropy.draw(
ImVec2(-1, 0),
ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect,
true
@@ -287,15 +287,15 @@ namespace hex::plugin::builtin {
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.block_size"_lang);
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("hex.builtin.view.information.block_size.desc"_lang, this->m_chunkBasedEntropy.getSize(), this->m_chunkBasedEntropy.getChunkSize());
ImGuiExt::TextFormatted("hex.builtin.view.information.block_size.desc"_lang, m_chunkBasedEntropy.getSize(), m_chunkBasedEntropy.getChunkSize());
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.file_entropy"_lang);
ImGui::TableNextColumn();
if (this->m_averageEntropy < 0)
if (m_averageEntropy < 0)
ImGui::TextUnformatted("???");
else {
auto entropy = std::abs(this->m_averageEntropy);
auto entropy = std::abs(m_averageEntropy);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.1F);
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGui::GetColorU32(ImGuiCol_TableRowBgAlt));
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImColor::HSV(0.3F - (0.3F * entropy), 0.6F, 0.8F, 1.0F).Value);
@@ -307,12 +307,12 @@ namespace hex::plugin::builtin {
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.highest_entropy"_lang);
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{:.5f} @", this->m_highestBlockEntropy);
ImGuiExt::TextFormatted("{:.5f} @", m_highestBlockEntropy);
ImGui::SameLine();
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
if (ImGui::Button(hex::format("0x{:06X}", this->m_highestBlockEntropyAddress).c_str())) {
ImHexApi::HexEditor::setSelection(this->m_highestBlockEntropyAddress, this->m_inputChunkSize);
if (ImGui::Button(hex::format("0x{:06X}", m_highestBlockEntropyAddress).c_str())) {
ImHexApi::HexEditor::setSelection(m_highestBlockEntropyAddress, m_inputChunkSize);
}
ImGui::PopStyleColor();
ImGui::PopStyleVar();
@@ -320,12 +320,12 @@ namespace hex::plugin::builtin {
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.lowest_entropy"_lang);
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{:.5f} @", this->m_lowestBlockEntropy);
ImGuiExt::TextFormatted("{:.5f} @", m_lowestBlockEntropy);
ImGui::SameLine();
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
if (ImGui::Button(hex::format("0x{:06X}", this->m_lowestBlockEntropyAddress).c_str())) {
ImHexApi::HexEditor::setSelection(this->m_lowestBlockEntropyAddress, this->m_inputChunkSize);
if (ImGui::Button(hex::format("0x{:06X}", m_lowestBlockEntropyAddress).c_str())) {
ImHexApi::HexEditor::setSelection(m_lowestBlockEntropyAddress, m_inputChunkSize);
}
ImGui::PopStyleColor();
ImGui::PopStyleVar();
@@ -333,13 +333,13 @@ namespace hex::plugin::builtin {
ImGui::TableNextColumn();
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.plain_text_percentage"_lang);
ImGui::TableNextColumn();
if (this->m_plainTextCharacterPercentage < 0)
if (m_plainTextCharacterPercentage < 0)
ImGui::TextUnformatted("???");
else {
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.1F);
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGui::GetColorU32(ImGuiCol_TableRowBgAlt));
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImColor::HSV(0.3F * (this->m_plainTextCharacterPercentage / 100.0F), 0.8F, 0.6F, 1.0F).Value);
ImGui::ProgressBar(this->m_plainTextCharacterPercentage / 100.0F, ImVec2(200_scaled, ImGui::GetTextLineHeight()));
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImColor::HSV(0.3F * (m_plainTextCharacterPercentage / 100.0F), 0.8F, 0.6F, 1.0F).Value);
ImGui::ProgressBar(m_plainTextCharacterPercentage / 100.0F, ImVec2(200_scaled, ImGui::GetTextLineHeight()));
ImGui::PopStyleColor(2);
ImGui::PopStyleVar();
}
@@ -354,12 +354,12 @@ namespace hex::plugin::builtin {
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
if (this->m_averageEntropy > 0.83 && this->m_highestBlockEntropy > 0.9) {
if (m_averageEntropy > 0.83 && m_highestBlockEntropy > 0.9) {
ImGui::TableNextColumn();
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{}", "hex.builtin.view.information.encrypted"_lang);
}
if (this->m_plainTextCharacterPercentage > 95) {
if (m_plainTextCharacterPercentage > 95) {
ImGui::TableNextColumn();
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{}", "hex.builtin.view.information.plain_text"_lang);
}
@@ -370,7 +370,7 @@ namespace hex::plugin::builtin {
ImGui::BeginGroup();
{
ImGui::TextUnformatted("hex.builtin.view.information.digram"_lang);
this->m_digram.draw(scaled(ImVec2(300, 300)));
m_digram.draw(scaled(ImVec2(300, 300)));
}
ImGui::EndGroup();
@@ -379,7 +379,7 @@ namespace hex::plugin::builtin {
ImGui::BeginGroup();
{
ImGui::TextUnformatted("hex.builtin.view.information.layered_distribution"_lang);
this->m_layeredDistribution.draw(scaled(ImVec2(300, 300)));
m_layeredDistribution.draw(scaled(ImVec2(300, 300)));
}
ImGui::EndGroup();
}

View File

@@ -40,7 +40,7 @@ namespace hex::plugin::builtin {
}
void ViewLogs::drawContent() {
ImGui::Combo("hex.builtin.view.logs.log_level"_lang, &this->m_logLevel, "DEBUG\0INFO\0WARNING\0ERROR\0FATAL\0");
ImGui::Combo("hex.builtin.view.logs.log_level"_lang, &m_logLevel, "DEBUG\0INFO\0WARNING\0ERROR\0FATAL\0");
if (ImGui::BeginTable("##logs", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY)) {
ImGui::TableSetupColumn("hex.builtin.view.logs.component"_lang, ImGuiTableColumnFlags_WidthFixed, 100_scaled);
@@ -58,7 +58,7 @@ namespace hex::plugin::builtin {
for (size_t i = clipper.DisplayStart; i < std::min<size_t>(clipper.DisplayEnd + end, logs.size()); i++) {
const auto &log = logs[logs.size() - 1 - i];
if (!shouldDisplay(log.level, this->m_logLevel)) {
if (!shouldDisplay(log.level, m_logLevel)) {
end++;
clipper.ItemsCount--;
continue;

View File

@@ -151,7 +151,7 @@ namespace hex::plugin::builtin {
}
if (ImGui::IsMouseReleased(1) && ImGui::IsItemHovered()) {
ImGui::OpenPopup("PatchContextMenu");
this->m_selectedPatch = address;
m_selectedPatch = address;
}
ImGui::TableNextColumn();
@@ -175,8 +175,8 @@ namespace hex::plugin::builtin {
void ViewPatches::drawAlwaysVisibleContent() {
if (auto provider = ImHexApi::Provider::get(); provider != nullptr) {
const auto &operations = provider->getUndoStack().getAppliedOperations();
if (this->m_numOperations.get(provider) != operations.size()) {
this->m_numOperations.get(provider) = operations.size();
if (m_numOperations.get(provider) != operations.size()) {
m_numOperations.get(provider) = operations.size();
EventHighlightingChanged::post();
}
}

View File

@@ -9,32 +9,32 @@
namespace hex::plugin::builtin {
ViewPatternData::ViewPatternData() : View::Window("hex.builtin.view.pattern_data.name") {
this->m_patternDrawer = std::make_unique<ui::PatternDrawer>();
m_patternDrawer = std::make_unique<ui::PatternDrawer>();
// Handle tree style setting changes
EventSettingsChanged::subscribe(this, [this] {
auto patternStyle = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.pattern_tree_style", 0);
this->m_patternDrawer->setTreeStyle(patternStyle);
m_patternDrawer->setTreeStyle(patternStyle);
auto rowColoring = ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.pattern_data_row_bg", false);
this->m_patternDrawer->enableRowColoring(rowColoring);
m_patternDrawer->enableRowColoring(rowColoring);
});
// Reset the pattern drawer when the provider changes
EventProviderChanged::subscribe(this, [this](auto, auto) {
this->m_patternDrawer->reset();
m_patternDrawer->reset();
});
EventPatternEvaluating::subscribe(this, [this]{
this->m_patternDrawer->reset();
m_patternDrawer->reset();
});
EventPatternExecuted::subscribe(this, [this](auto){
this->m_patternDrawer->reset();
m_patternDrawer->reset();
});
// Handle jumping to a pattern's location when it is clicked
this->m_patternDrawer->setSelectionCallback([](Region region){ ImHexApi::HexEditor::setSelection(region); });
m_patternDrawer->setSelectionCallback([](Region region){ ImHexApi::HexEditor::setSelection(region); });
}
ViewPatternData::~ViewPatternData() {
@@ -52,11 +52,11 @@ namespace hex::plugin::builtin {
const auto height = std::max(ImGui::GetContentRegionAvail().y - ImGui::GetTextLineHeightWithSpacing() - ImGui::GetStyle().FramePadding.y * 2, ImGui::GetTextLineHeightWithSpacing() * 5);
if (!runtime.arePatternsValid()) {
this->m_patternDrawer->draw({ }, nullptr, height);
m_patternDrawer->draw({ }, nullptr, height);
} else {
// If the runtime has finished evaluating, draw the patterns
if (TRY_LOCK(ContentRegistry::PatternLanguage::getRuntimeLock())) {
this->m_patternDrawer->draw(runtime.getPatterns(), &runtime, height);
m_patternDrawer->draw(runtime.getPatterns(), &runtime, height);
}
}
}

View File

@@ -126,17 +126,17 @@ namespace hex::plugin::builtin {
}
ViewPatternEditor::ViewPatternEditor() : View::Window("hex.builtin.view.pattern_editor.name") {
this->m_parserRuntime = std::make_unique<pl::PatternLanguage>();
ContentRegistry::PatternLanguage::configureRuntime(*this->m_parserRuntime, nullptr);
m_parserRuntime = std::make_unique<pl::PatternLanguage>();
ContentRegistry::PatternLanguage::configureRuntime(*m_parserRuntime, nullptr);
this->m_textEditor.SetLanguageDefinition(PatternLanguage());
this->m_textEditor.SetShowWhitespaces(false);
m_textEditor.SetLanguageDefinition(PatternLanguage());
m_textEditor.SetShowWhitespaces(false);
this->m_consoleEditor.SetLanguageDefinition(ConsoleLog());
this->m_consoleEditor.SetShowWhitespaces(false);
this->m_consoleEditor.SetReadOnly(true);
this->m_consoleEditor.SetShowCursor(false);
this->m_consoleEditor.SetShowLineNumbers(false);
m_consoleEditor.SetLanguageDefinition(ConsoleLog());
m_consoleEditor.SetShowWhitespaces(false);
m_consoleEditor.SetReadOnly(true);
m_consoleEditor.SetShowCursor(false);
m_consoleEditor.SetShowLineNumbers(false);
this->registerEvents();
this->registerMenuItems();
@@ -167,31 +167,31 @@ namespace hex::plugin::builtin {
if (availableSize.y > 1)
textEditorSize.y = std::clamp(textEditorSize.y, 1.0F, std::max(1.0F, availableSize.y - ImGui::GetTextLineHeightWithSpacing() * 3));
this->m_textEditor.Render("hex.builtin.view.pattern_editor.name"_lang, textEditorSize, true);
m_textEditor.Render("hex.builtin.view.pattern_editor.name"_lang, textEditorSize, true);
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
ImGui::OpenPopup("##pattern_editor_context_menu");
}
if (ImGui::BeginPopup("##pattern_editor_context_menu")) {
bool hasSelection = this->m_textEditor.HasSelection();
bool hasSelection = m_textEditor.HasSelection();
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.cut"_lang, Shortcut(CTRLCMD + Keys::X).toString().c_str(), false, hasSelection)) {
this->m_textEditor.Cut();
m_textEditor.Cut();
}
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.copy"_lang, Shortcut(CTRLCMD + Keys::C).toString().c_str(), false, hasSelection)) {
this->m_textEditor.Copy();
m_textEditor.Copy();
}
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.paste"_lang, Shortcut(CTRLCMD + Keys::V).toString().c_str())) {
this->m_textEditor.Paste();
m_textEditor.Paste();
}
ImGui::Separator();
if (ImGui::MenuItem("hex.builtin.menu.edit.undo"_lang, Shortcut(CTRLCMD + Keys::Z).toString().c_str(), false, this->m_textEditor.CanUndo())) {
this->m_textEditor.Undo();
if (ImGui::MenuItem("hex.builtin.menu.edit.undo"_lang, Shortcut(CTRLCMD + Keys::Z).toString().c_str(), false, m_textEditor.CanUndo())) {
m_textEditor.Undo();
}
if (ImGui::MenuItem("hex.builtin.menu.edit.redo"_lang, Shortcut(CTRLCMD + Keys::Y).toString().c_str(), false, this->m_textEditor.CanRedo())) {
this->m_textEditor.Redo();
if (ImGui::MenuItem("hex.builtin.menu.edit.redo"_lang, Shortcut(CTRLCMD + Keys::Y).toString().c_str(), false, m_textEditor.CanRedo())) {
m_textEditor.Redo();
}
ImGui::EndPopup();
@@ -222,15 +222,15 @@ namespace hex::plugin::builtin {
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.env_vars"_lang)) {
this->drawEnvVars(settingsSize, *this->m_envVarEntries);
this->drawEnvVars(settingsSize, *m_envVarEntries);
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.settings"_lang)) {
this->drawVariableSettings(settingsSize, *this->m_patternVariables);
this->drawVariableSettings(settingsSize, *m_patternVariables);
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.sections"_lang)) {
this->drawSectionSelector(settingsSize, *this->m_sections);
this->drawSectionSelector(settingsSize, *m_sections);
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.debugger"_lang)) {
@@ -246,22 +246,22 @@ namespace hex::plugin::builtin {
{
auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
if (runtime.isRunning()) {
if (this->m_breakpointHit) {
if (m_breakpointHit) {
if (ImGuiExt::IconButton(ICON_VS_DEBUG_CONTINUE, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarYellow)))
this->m_breakpointHit = false;
m_breakpointHit = false;
ImGui::SameLine();
if (ImGuiExt::IconButton(ICON_VS_DEBUG_STEP_INTO, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarYellow))) {
runtime.getInternals().evaluator->pauseNextLine();
this->m_breakpointHit = false;
m_breakpointHit = false;
}
} else {
if (ImGuiExt::IconButton(ICON_VS_DEBUG_STOP, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed)))
runtime.abort();
}
} else {
if (ImGuiExt::IconButton(ICON_VS_DEBUG_START, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen)) || this->m_triggerEvaluation) {
this->m_triggerEvaluation = false;
this->evaluatePattern(this->m_textEditor.GetText(), provider);
if (ImGuiExt::IconButton(ICON_VS_DEBUG_START, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarGreen)) || m_triggerEvaluation) {
m_triggerEvaluation = false;
this->evaluatePattern(m_textEditor.GetText(), provider);
}
}
@@ -269,8 +269,8 @@ namespace hex::plugin::builtin {
ImGui::PopStyleVar();
ImGui::SameLine();
if (this->m_runningEvaluators > 0) {
if (this->m_breakpointHit) {
if (m_runningEvaluators > 0) {
if (m_breakpointHit) {
ImGuiExt::TextFormatted("hex.builtin.view.pattern_editor.breakpoint_hit"_lang, runtime.getInternals().evaluator->getPauseLine().value_or(0));
} else {
ImGuiExt::TextSpinner("hex.builtin.view.pattern_editor.evaluating"_lang);
@@ -294,8 +294,8 @@ namespace hex::plugin::builtin {
const auto insertPos = [&, this](u64 address, u32 color) {
const auto progress = (address - dataBaseAddress) / float(dataSize);
this->m_accessHistory[this->m_accessHistoryIndex] = { progress, color };
this->m_accessHistoryIndex = (this->m_accessHistoryIndex + 1) % this->m_accessHistory.size();
m_accessHistory[m_accessHistoryIndex] = { progress, color };
m_accessHistoryIndex = (m_accessHistoryIndex + 1) % m_accessHistory.size();
};
insertPos(runtime.getLastReadAddress(), ImGuiExt::GetCustomColorU32(ImGuiCustomCol_ToolbarBlue));
@@ -303,7 +303,7 @@ namespace hex::plugin::builtin {
insertPos(runtime.getLastPatternPlaceAddress(), ImGuiExt::GetCustomColorU32(ImGuiCustomCol_ToolbarGreen));
auto drawList = ImGui::GetWindowDrawList();
for (const auto &[progress, color] : this->m_accessHistory) {
for (const auto &[progress, color] : m_accessHistory) {
if (progress <= 0) continue;
const auto linePos = startPos + ImVec2(size.x * progress, 0);
@@ -315,9 +315,9 @@ namespace hex::plugin::builtin {
ImGui::PopStyleVar(2);
} else {
if (ImGui::Checkbox("hex.builtin.view.pattern_editor.auto"_lang, &this->m_runAutomatically)) {
if (this->m_runAutomatically)
this->m_hasUnevaluatedChanges = true;
if (ImGui::Checkbox("hex.builtin.view.pattern_editor.auto"_lang, &m_runAutomatically)) {
if (m_runAutomatically)
m_hasUnevaluatedChanges = true;
}
ImGui::SameLine();
@@ -334,68 +334,68 @@ namespace hex::plugin::builtin {
}
}
if (this->m_textEditor.IsTextChanged()) {
this->m_hasUnevaluatedChanges = true;
if (m_textEditor.IsTextChanged()) {
m_hasUnevaluatedChanges = true;
ImHexApi::Provider::markDirty();
this->m_sourceCode = this->m_textEditor.GetText();
m_sourceCode = m_textEditor.GetText();
}
if (this->m_hasUnevaluatedChanges && this->m_runningEvaluators == 0 && this->m_runningParsers == 0) {
this->m_hasUnevaluatedChanges = false;
if (m_hasUnevaluatedChanges && m_runningEvaluators == 0 && m_runningParsers == 0) {
m_hasUnevaluatedChanges = false;
auto code = this->m_textEditor.GetText();
auto code = m_textEditor.GetText();
EventPatternEditorChanged::post(code);
TaskManager::createBackgroundTask("Pattern Parsing", [this, code, provider](auto &){
this->parsePattern(code, provider);
if (this->m_runAutomatically)
this->m_triggerAutoEvaluate = true;
if (m_runAutomatically)
m_triggerAutoEvaluate = true;
});
}
if (this->m_triggerAutoEvaluate.exchange(false)) {
this->evaluatePattern(this->m_textEditor.GetText(), provider);
if (m_triggerAutoEvaluate.exchange(false)) {
this->evaluatePattern(m_textEditor.GetText(), provider);
}
}
if (this->m_dangerousFunctionCalled && !ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopup)) {
if (m_dangerousFunctionCalled && !ImGui::IsPopupOpen(ImGuiID(0), ImGuiPopupFlags_AnyPopup)) {
PopupQuestion::open("hex.builtin.view.pattern_editor.dangerous_function.desc"_lang,
[this] {
this->m_dangerousFunctionsAllowed = DangerousFunctionPerms::Allow;
m_dangerousFunctionsAllowed = DangerousFunctionPerms::Allow;
}, [this] {
this->m_dangerousFunctionsAllowed = DangerousFunctionPerms::Deny;
m_dangerousFunctionsAllowed = DangerousFunctionPerms::Deny;
}
);
this->m_dangerousFunctionCalled = false;
m_dangerousFunctionCalled = false;
}
View::discardNavigationRequests();
}
void ViewPatternEditor::drawConsole(ImVec2 size) {
if (this->m_consoleNeedsUpdate) {
std::scoped_lock lock(this->m_logMutex);
if (m_consoleNeedsUpdate) {
std::scoped_lock lock(m_logMutex);
auto lineCount = this->m_consoleEditor.GetTextLines().size() - 1;
if (this->m_console->size() < lineCount) {
this->m_consoleEditor.SetText("");
auto lineCount = m_consoleEditor.GetTextLines().size() - 1;
if (m_console->size() < lineCount) {
m_consoleEditor.SetText("");
lineCount = 0;
}
this->m_consoleEditor.SetCursorPosition({ int(lineCount + 1), 0 });
m_consoleEditor.SetCursorPosition({ int(lineCount + 1), 0 });
auto linesToAdd = this->m_console->size() - lineCount;
auto linesToAdd = m_console->size() - lineCount;
for (size_t i = 0; i < linesToAdd; i += 1) {
this->m_consoleEditor.InsertText(this->m_console->at(lineCount + i));
this->m_consoleEditor.InsertText("\n");
m_consoleEditor.InsertText(m_console->at(lineCount + i));
m_consoleEditor.InsertText("\n");
}
this->m_consoleNeedsUpdate = false;
m_consoleNeedsUpdate = false;
}
this->m_consoleEditor.Render("##console", size, true);
m_consoleEditor.Render("##console", size, true);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetStyle().FramePadding.y + 1_scaled);
}
@@ -593,10 +593,10 @@ namespace hex::plugin::builtin {
dataProvider->writeRaw(0x00, section.data.data(), section.data.size());
dataProvider->setReadOnly(true);
auto hexEditor = auto(this->m_sectionHexEditor);
auto hexEditor = auto(m_sectionHexEditor);
hexEditor.setBackgroundHighlightCallback([this, id, &runtime](u64 address, const u8 *, size_t) -> std::optional<color_t> {
if (this->m_runningEvaluators != 0)
if (m_runningEvaluators != 0)
return std::nullopt;
if (!ImHexApi::Provider::isValid())
return std::nullopt;
@@ -618,7 +618,7 @@ namespace hex::plugin::builtin {
auto patternProvider = ImHexApi::Provider::get();
this->m_sectionWindowDrawer[patternProvider] = [this, id, patternProvider, dataProvider, hexEditor, patternDrawer = std::make_shared<ui::PatternDrawer>(), &runtime] mutable {
m_sectionWindowDrawer[patternProvider] = [this, id, patternProvider, dataProvider, hexEditor, patternDrawer = std::make_shared<ui::PatternDrawer>(), &runtime] mutable {
hexEditor.setProvider(dataProvider.get());
hexEditor.draw(480_scaled);
patternDrawer->setSelectionCallback([&](const auto &region) {
@@ -626,7 +626,7 @@ namespace hex::plugin::builtin {
});
const auto &patterns = [&, this] -> const auto& {
if (patternProvider->isReadable() && *this->m_executionDone)
if (patternProvider->isReadable() && *m_executionDone)
return runtime.getPatterns(id);
else {
static const std::vector<std::shared_ptr<pl::ptrn::Pattern>> empty;
@@ -634,7 +634,7 @@ namespace hex::plugin::builtin {
}
}();
if (*this->m_executionDone)
if (*m_executionDone)
patternDrawer->draw(patterns, &runtime, 150_scaled);
};
}
@@ -653,25 +653,25 @@ namespace hex::plugin::builtin {
if (ImGui::BeginChild("##debugger", size, true)) {
const auto &breakpoints = evaluator->getBreakpoints();
auto line = this->m_textEditor.GetCursorPosition().mLine + 1;
auto line = m_textEditor.GetCursorPosition().mLine + 1;
if (!breakpoints.contains(line)) {
if (ImGuiExt::IconButton(ICON_VS_DEBUG_BREAKPOINT, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
evaluator->addBreakpoint(line);
this->m_textEditor.SetBreakpoints(breakpoints);
m_textEditor.SetBreakpoints(breakpoints);
}
ImGuiExt::InfoTooltip("hex.builtin.view.pattern_editor.debugger.add_tooltip"_lang);
} else {
if (ImGuiExt::IconButton(ICON_VS_DEBUG_BREAKPOINT_UNVERIFIED, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
evaluator->removeBreakpoint(line);
this->m_textEditor.SetBreakpoints(breakpoints);
m_textEditor.SetBreakpoints(breakpoints);
}
ImGuiExt::InfoTooltip("hex.builtin.view.pattern_editor.debugger.remove_tooltip"_lang);
}
ImGui::SameLine();
if (*this->m_breakpointHit) {
if (*m_breakpointHit) {
auto displayValue = [&](const auto &parent, size_t index) {
return hex::format("{0} {1} [{2}]",
"hex.builtin.view.pattern_editor.debugger.scope"_lang,
@@ -684,14 +684,14 @@ namespace hex::plugin::builtin {
if (evaluator->getScopeCount() > 0) {
ImGui::SetNextItemWidth(-1);
auto &currScope = evaluator->getScope(-this->m_debuggerScopeIndex);
if (ImGui::BeginCombo("##scope", displayValue(currScope.parent, this->m_debuggerScopeIndex).c_str())) {
auto &currScope = evaluator->getScope(-m_debuggerScopeIndex);
if (ImGui::BeginCombo("##scope", displayValue(currScope.parent, m_debuggerScopeIndex).c_str())) {
for (size_t i = 0; i < evaluator->getScopeCount(); i++) {
auto &scope = evaluator->getScope(-i);
if (ImGui::Selectable(displayValue(scope.parent, i).c_str(), i == size_t(this->m_debuggerScopeIndex))) {
this->m_debuggerScopeIndex = i;
this->m_resetDebuggerVariables = true;
if (ImGui::Selectable(displayValue(scope.parent, i).c_str(), i == size_t(m_debuggerScopeIndex))) {
m_debuggerScopeIndex = i;
m_resetDebuggerVariables = true;
}
}
@@ -699,19 +699,19 @@ namespace hex::plugin::builtin {
}
}
if (this->m_resetDebuggerVariables) {
if (m_resetDebuggerVariables) {
auto pauseLine = evaluator->getPauseLine();
(*this->m_debuggerDrawer)->reset();
this->m_resetDebuggerVariables = false;
this->m_textEditor.SetCursorPosition(TextEditor::Coordinates(pauseLine.value_or(0) - 1, 0));
(*m_debuggerDrawer)->reset();
m_resetDebuggerVariables = false;
m_textEditor.SetCursorPosition(TextEditor::Coordinates(pauseLine.value_or(0) - 1, 0));
if (pauseLine.has_value())
this->m_textEditor.SetCursorPosition({ int(pauseLine.value() - 1), 0 });
m_textEditor.SetCursorPosition({ int(pauseLine.value() - 1), 0 });
}
auto &currScope = evaluator->getScope(-this->m_debuggerScopeIndex);
(*this->m_debuggerDrawer)->draw(*currScope.scope, &runtime, size.y - ImGui::GetTextLineHeightWithSpacing() * 4);
auto &currScope = evaluator->getScope(-m_debuggerScopeIndex);
(*m_debuggerDrawer)->draw(*currScope.scope, &runtime, size.y - ImGui::GetTextLineHeightWithSpacing() * 4);
}
}
ImGui::EndChild();
@@ -720,51 +720,51 @@ namespace hex::plugin::builtin {
void ViewPatternEditor::drawAlwaysVisibleContent() {
auto provider = ImHexApi::Provider::get();
auto open = this->m_sectionWindowDrawer.contains(provider);
auto open = m_sectionWindowDrawer.contains(provider);
if (open) {
ImGui::SetNextWindowSize(scaled(ImVec2(600, 700)), ImGuiCond_Appearing);
if (ImGui::Begin("hex.builtin.view.pattern_editor.section_popup"_lang, &open, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
this->m_sectionWindowDrawer[provider]();
m_sectionWindowDrawer[provider]();
}
ImGui::End();
}
if (!open && this->m_sectionWindowDrawer.contains(provider)) {
if (!open && m_sectionWindowDrawer.contains(provider)) {
ImHexApi::HexEditor::setSelection(Region::Invalid());
this->m_sectionWindowDrawer.erase(provider);
m_sectionWindowDrawer.erase(provider);
}
if (!this->m_lastEvaluationProcessed) {
if (!this->m_lastEvaluationResult) {
if (this->m_lastEvaluationError->has_value()) {
if (!m_lastEvaluationProcessed) {
if (!m_lastEvaluationResult) {
if (m_lastEvaluationError->has_value()) {
TextEditor::ErrorMarkers errorMarkers = {
{ (*this->m_lastEvaluationError)->line, (*this->m_lastEvaluationError)->message }
{ (*m_lastEvaluationError)->line, (*m_lastEvaluationError)->message }
};
this->m_textEditor.SetErrorMarkers(errorMarkers);
m_textEditor.SetErrorMarkers(errorMarkers);
}
} else {
for (auto &[name, variable] : *this->m_patternVariables) {
if (variable.outVariable && this->m_lastEvaluationOutVars->contains(name))
variable.value = this->m_lastEvaluationOutVars->at(name);
for (auto &[name, variable] : *m_patternVariables) {
if (variable.outVariable && m_lastEvaluationOutVars->contains(name))
variable.value = m_lastEvaluationOutVars->at(name);
}
EventHighlightingChanged::post();
}
this->m_lastEvaluationProcessed = true;
*this->m_executionDone = true;
m_lastEvaluationProcessed = true;
*m_executionDone = true;
}
if (this->m_shouldAnalyze) {
this->m_shouldAnalyze = false;
if (m_shouldAnalyze) {
m_shouldAnalyze = false;
TaskManager::createBackgroundTask("Analyzing file content", [this, provider](auto &) {
if (!this->m_autoLoadPatterns)
if (!m_autoLoadPatterns)
return;
// Copy over current pattern source code to the new provider
if (!this->m_syncPatternSourceCode) {
*this->m_sourceCode = this->m_textEditor.GetText();
if (!m_syncPatternSourceCode) {
*m_sourceCode = m_textEditor.GetText();
}
pl::PatternLanguage runtime;
@@ -844,7 +844,7 @@ namespace hex::plugin::builtin {
return true;
});
this->m_possiblePatternFiles.get(provider).clear();
m_possiblePatternFiles.get(provider).clear();
std::error_code errorCode;
for (const auto &dir : fs::getDefaultPaths(fs::ImHexPath::Patterns)) {
@@ -868,13 +868,13 @@ namespace hex::plugin::builtin {
}
if (foundCorrectType)
this->m_possiblePatternFiles.get(provider).push_back(entry.path());
m_possiblePatternFiles.get(provider).push_back(entry.path());
runtime.reset();
}
}
if (!this->m_possiblePatternFiles.get(provider).empty()) {
if (!m_possiblePatternFiles.get(provider).empty()) {
PopupAcceptPattern::open(this);
}
});
@@ -949,20 +949,20 @@ namespace hex::plugin::builtin {
auto code = file.readString();
this->evaluatePattern(code, provider);
this->m_textEditor.SetText(code);
this->m_sourceCode = code;
m_textEditor.SetText(code);
m_sourceCode = code;
TaskManager::createBackgroundTask("Parse pattern", [this, code, provider](auto&) { this->parsePattern(code, provider); });
}
}
void ViewPatternEditor::parsePattern(const std::string &code, prv::Provider *provider) {
this->m_runningParsers += 1;
m_runningParsers += 1;
ContentRegistry::PatternLanguage::configureRuntime(*this->m_parserRuntime, nullptr);
auto ast = this->m_parserRuntime->parseString(code);
ContentRegistry::PatternLanguage::configureRuntime(*m_parserRuntime, nullptr);
auto ast = m_parserRuntime->parseString(code);
auto &patternVariables = this->m_patternVariables.get(provider);
auto &patternVariables = m_patternVariables.get(provider);
patternVariables.clear();
@@ -991,7 +991,7 @@ namespace hex::plugin::builtin {
}
}
this->m_runningParsers -= 1;
m_runningParsers -= 1;
}
void ViewPatternEditor::evaluatePattern(const std::string &code, prv::Provider *provider) {
@@ -999,19 +999,19 @@ namespace hex::plugin::builtin {
auto lock = std::scoped_lock(ContentRegistry::PatternLanguage::getRuntimeLock());
this->m_runningEvaluators += 1;
*this->m_executionDone = false;
m_runningEvaluators += 1;
*m_executionDone = false;
this->m_textEditor.SetErrorMarkers({});
this->m_console->clear();
this->m_consoleNeedsUpdate = true;
m_textEditor.SetErrorMarkers({});
m_console->clear();
m_consoleNeedsUpdate = true;
this->m_sectionWindowDrawer.clear();
this->m_consoleEditor.SetText("");
m_sectionWindowDrawer.clear();
m_consoleEditor.SetText("");
this->m_accessHistory = {};
this->m_accessHistoryIndex = 0;
m_accessHistory = {};
m_accessHistoryIndex = 0;
EventHighlightingChanged::post();
@@ -1021,41 +1021,41 @@ namespace hex::plugin::builtin {
auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
ContentRegistry::PatternLanguage::configureRuntime(runtime, provider);
runtime.getInternals().evaluator->setBreakpointHitCallback([this]{
this->m_debuggerScopeIndex = 0;
*this->m_breakpointHit = true;
this->m_resetDebuggerVariables = true;
while (*this->m_breakpointHit) {
m_debuggerScopeIndex = 0;
*m_breakpointHit = true;
m_resetDebuggerVariables = true;
while (*m_breakpointHit) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
});
task.setInterruptCallback([this, &runtime] {
this->m_breakpointHit = false;
m_breakpointHit = false;
runtime.abort();
});
std::map<std::string, pl::core::Token::Literal> envVars;
for (const auto &[id, name, value, type] : *this->m_envVarEntries)
for (const auto &[id, name, value, type] : *m_envVarEntries)
envVars.insert({ name, value });
std::map<std::string, pl::core::Token::Literal> inVariables;
for (auto &[name, variable] : *this->m_patternVariables) {
for (auto &[name, variable] : *m_patternVariables) {
if (variable.inVariable)
inVariables[name] = variable.value;
}
runtime.setDangerousFunctionCallHandler([this]{
this->m_dangerousFunctionCalled = true;
m_dangerousFunctionCalled = true;
while (this->m_dangerousFunctionsAllowed == DangerousFunctionPerms::Ask) {
while (m_dangerousFunctionsAllowed == DangerousFunctionPerms::Ask) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
return this->m_dangerousFunctionsAllowed == DangerousFunctionPerms::Allow;
return m_dangerousFunctionsAllowed == DangerousFunctionPerms::Allow;
});
runtime.setLogCallback([this](auto level, auto message) {
std::scoped_lock lock(this->m_logMutex);
std::scoped_lock lock(m_logMutex);
for (auto line : wolv::util::splitString(message, "\n")) {
switch (level) {
@@ -1067,30 +1067,30 @@ namespace hex::plugin::builtin {
case Error: line = hex::format("E: {}", line); break;
}
this->m_console->emplace_back(line);
this->m_consoleNeedsUpdate = true;
m_console->emplace_back(line);
m_consoleNeedsUpdate = true;
}
});
ON_SCOPE_EXIT {
*this->m_lastEvaluationOutVars = runtime.getOutVariables();
*this->m_sections = runtime.getSections();
*m_lastEvaluationOutVars = runtime.getOutVariables();
*m_sections = runtime.getSections();
this->m_runningEvaluators -= 1;
m_runningEvaluators -= 1;
this->m_lastEvaluationProcessed = false;
m_lastEvaluationProcessed = false;
std::scoped_lock lock(this->m_logMutex);
this->m_console->emplace_back(
std::scoped_lock lock(m_logMutex);
m_console->emplace_back(
hex::format("I: Evaluation took {}", std::chrono::duration<double>(runtime.getLastRunningTime()))
);
this->m_consoleNeedsUpdate = true;
m_consoleNeedsUpdate = true;
};
this->m_lastEvaluationResult = runtime.executeString(code, envVars, inVariables);
if (!this->m_lastEvaluationResult) {
*this->m_lastEvaluationError = runtime.getError();
m_lastEvaluationResult = runtime.executeString(code, envVars, inVariables);
if (!m_lastEvaluationResult) {
*m_lastEvaluationError = runtime.getError();
}
TaskManager::doLater([code] {
@@ -1105,52 +1105,52 @@ namespace hex::plugin::builtin {
});
RequestRunPatternCode::subscribe(this, [this] {
this->m_triggerAutoEvaluate = true;
m_triggerAutoEvaluate = true;
});
RequestSavePatternLanguageFile::subscribe(this, [this](const std::fs::path &path) {
wolv::io::File file(path, wolv::io::File::Mode::Create);
file.writeString(wolv::util::trim(this->m_textEditor.GetText()));
file.writeString(wolv::util::trim(m_textEditor.GetText()));
});
RequestSetPatternLanguageCode::subscribe(this, [this](const std::string &code) {
this->m_textEditor.SetText(code);
this->m_sourceCode = code;
this->m_hasUnevaluatedChanges = true;
m_textEditor.SetText(code);
m_sourceCode = code;
m_hasUnevaluatedChanges = true;
});
EventSettingsChanged::subscribe(this, [this] {
this->m_syncPatternSourceCode = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.sync_pattern_source", false);
this->m_autoLoadPatterns = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.auto_load_patterns", true);
m_syncPatternSourceCode = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.sync_pattern_source", false);
m_autoLoadPatterns = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.auto_load_patterns", true);
});
EventProviderOpened::subscribe(this, [this](prv::Provider *provider) {
this->m_shouldAnalyze.get(provider) = true;
this->m_envVarEntries->push_back({ 0, "", 0, EnvVarType::Integer });
m_shouldAnalyze.get(provider) = true;
m_envVarEntries->push_back({ 0, "", 0, EnvVarType::Integer });
this->m_debuggerDrawer.get(provider) = std::make_unique<ui::PatternDrawer>();
m_debuggerDrawer.get(provider) = std::make_unique<ui::PatternDrawer>();
});
EventProviderChanged::subscribe(this, [this](prv::Provider *oldProvider, prv::Provider *newProvider) {
if (!this->m_syncPatternSourceCode) {
if (!m_syncPatternSourceCode) {
if (oldProvider != nullptr)
this->m_sourceCode.get(oldProvider) = this->m_textEditor.GetText();
m_sourceCode.get(oldProvider) = m_textEditor.GetText();
if (newProvider != nullptr) {
this->m_consoleEditor.SetTextLines(this->m_console.get(newProvider));
this->m_textEditor.SetText(wolv::util::trim(this->m_sourceCode.get(newProvider)));
m_consoleEditor.SetTextLines(m_console.get(newProvider));
m_textEditor.SetText(wolv::util::trim(m_sourceCode.get(newProvider)));
}
else
this->m_textEditor.SetText("");
m_textEditor.SetText("");
} else {
this->m_hasUnevaluatedChanges = true;
m_hasUnevaluatedChanges = true;
}
});
EventProviderClosed::subscribe(this, [this](prv::Provider *) {
if (this->m_syncPatternSourceCode && ImHexApi::Provider::getProviders().empty()) {
this->m_textEditor.SetText("");
this->m_sourceCode = "";
if (m_syncPatternSourceCode && ImHexApi::Provider::getProviders().empty()) {
m_textEditor.SetText("");
m_sourceCode = "";
}
});
}
@@ -1171,9 +1171,9 @@ namespace hex::plugin::builtin {
}
void ViewPatternEditor::appendEditorText(const std::string &text) {
this->m_textEditor.SetCursorPosition(TextEditor::Coordinates { this->m_textEditor.GetTotalLines(), 0 });
this->m_textEditor.InsertText(hex::format("\n{0}", text));
this->m_triggerEvaluation = true;
m_textEditor.SetCursorPosition(TextEditor::Coordinates { m_textEditor.GetTotalLines(), 0 });
m_textEditor.InsertText(hex::format("\n{0}", text));
m_triggerEvaluation = true;
}
void ViewPatternEditor::appendVariable(const std::string &type) {
@@ -1222,10 +1222,10 @@ namespace hex::plugin::builtin {
[this](const auto &path) {
wolv::io::File file(path, wolv::io::File::Mode::Create);
file.writeString(wolv::util::trim(this->m_textEditor.GetText()));
file.writeString(wolv::util::trim(m_textEditor.GetText()));
});
}, [this] {
return !wolv::util::trim(this->m_textEditor.GetText()).empty() && ImHexApi::Provider::isValid();
return !wolv::util::trim(m_textEditor.GetText()).empty() && ImHexApi::Provider::isValid();
}
);
@@ -1257,7 +1257,7 @@ namespace hex::plugin::builtin {
ImGui::EndMenu();
}
const auto &types = this->m_parserRuntime->getInternals().parser->getTypes();
const auto &types = m_parserRuntime->getInternals().parser->getTypes();
bool hasPlaceableTypes = std::any_of(types.begin(), types.end(), [](const auto &type) { return !type.second->isTemplateType(); });
if (ImGui::BeginMenu("hex.builtin.view.pattern_editor.menu.edit.place_pattern.custom"_lang, hasPlaceableTypes)) {
@@ -1280,7 +1280,7 @@ namespace hex::plugin::builtin {
ImGui::EndMenu();
}
}, [this] {
return ImHexApi::Provider::isValid() && ImHexApi::HexEditor::isSelectionValid() && this->m_runningParsers == 0;
return ImHexApi::Provider::isValid() && ImHexApi::HexEditor::isSelectionValid() && m_runningParsers == 0;
});
}
@@ -1299,7 +1299,7 @@ namespace hex::plugin::builtin {
ImHexApi::HexEditor::addBackgroundHighlightingProvider([this](u64 address, const u8 *data, size_t size, bool) -> std::optional<color_t> {
hex::unused(data, size);
if (this->m_runningEvaluators != 0)
if (m_runningEvaluators != 0)
return std::nullopt;
auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
@@ -1358,11 +1358,11 @@ namespace hex::plugin::builtin {
.load = [this](prv::Provider *provider, const std::fs::path &basePath, Tar &tar) {
std::string sourceCode = tar.readString(basePath);
if (!this->m_syncPatternSourceCode)
this->m_sourceCode.get(provider) = sourceCode;
if (!m_syncPatternSourceCode)
m_sourceCode.get(provider) = sourceCode;
if (provider == ImHexApi::Provider::get())
this->m_textEditor.SetText(sourceCode);
m_textEditor.SetText(sourceCode);
return true;
},
@@ -1370,12 +1370,12 @@ namespace hex::plugin::builtin {
std::string sourceCode;
if (provider == ImHexApi::Provider::get())
this->m_sourceCode.get(provider) = this->m_textEditor.GetText();
m_sourceCode.get(provider) = m_textEditor.GetText();
if (this->m_syncPatternSourceCode)
sourceCode = this->m_textEditor.GetText();
if (m_syncPatternSourceCode)
sourceCode = m_textEditor.GetText();
else
sourceCode = this->m_sourceCode.get(provider);
sourceCode = m_sourceCode.get(provider);
tar.writeString(basePath, wolv::util::trim(sourceCode));
return true;
@@ -1383,7 +1383,7 @@ namespace hex::plugin::builtin {
});
ShortcutManager::addShortcut(this, Keys::F8 + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.add_breakpoint", [this] {
auto line = this->m_textEditor.GetCursorPosition().mLine + 1;
auto line = m_textEditor.GetCursorPosition().mLine + 1;
auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
auto &evaluator = runtime.getInternals().evaluator;
@@ -1395,19 +1395,19 @@ namespace hex::plugin::builtin {
evaluator->addBreakpoint(line);
}
this->m_textEditor.SetBreakpoints(breakpoints);
m_textEditor.SetBreakpoints(breakpoints);
});
/* Trigger evaluation */
ShortcutManager::addGlobalShortcut(Keys::F5 + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.run_pattern", [this] {
this->m_triggerAutoEvaluate = true;
m_triggerAutoEvaluate = true;
});
/* Continue debugger */
ShortcutManager::addGlobalShortcut(SHIFT + Keys::F9 + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.continue_debugger", [this] {
auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
if (runtime.isRunning())
this->m_breakpointHit = false;
m_breakpointHit = false;
});
/* Step debugger */
@@ -1415,13 +1415,13 @@ namespace hex::plugin::builtin {
auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
if (runtime.isRunning()) {
runtime.getInternals().evaluator->pauseNextLine();
this->m_breakpointHit = false;
m_breakpointHit = false;
}
});
// Generate pattern code report
ContentRegistry::Reports::addReportProvider([this](prv::Provider *provider) -> std::string {
auto patternCode = this->m_sourceCode.get(provider);
auto patternCode = m_sourceCode.get(provider);
if (wolv::util::trim(patternCode).empty())
return "";

View File

@@ -88,8 +88,8 @@ namespace hex::plugin::builtin {
// Request a restart if the setting requires it
if (widget->doesRequireRestart()) {
this->m_restartRequested = true;
this->m_triggerPopup = true;
m_restartRequested = true;
m_triggerPopup = true;
}
}
}
@@ -109,12 +109,12 @@ namespace hex::plugin::builtin {
void ViewSettings::drawAlwaysVisibleContent() {
// If a restart is required, ask the user if they want to restart
if (!this->getWindowOpenState() && this->m_triggerPopup) {
this->m_triggerPopup = false;
if (!this->getWindowOpenState() && m_triggerPopup) {
m_triggerPopup = false;
PopupQuestion::open("hex.builtin.view.settings.restart_question"_lang,
ImHexApi::System::restartImHex,
[this]{
this->m_restartRequested = false;
m_restartRequested = false;
}
);
}

View File

@@ -29,13 +29,13 @@ namespace hex::plugin::builtin {
ViewStore::ViewStore() : View::Floating("hex.builtin.view.store.name") {
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.extras", "hex.builtin.view.store.name" }, 1000, Shortcut::None, [&, this] {
if (this->m_requestStatus == RequestStatus::NotAttempted)
if (m_requestStatus == RequestStatus::NotAttempted)
this->refresh();
this->getWindowOpenState() = true;
});
this->m_httpRequest.setTimeout(30'0000);
m_httpRequest.setTimeout(30'0000);
addCategory("hex.builtin.view.store.tab.patterns", "patterns", fs::ImHexPath::Patterns);
addCategory("hex.builtin.view.store.tab.includes", "includes", fs::ImHexPath::PatternsInclude);
@@ -46,7 +46,7 @@ namespace hex::plugin::builtin {
addCategory("hex.builtin.view.store.tab.encodings", "encodings", fs::ImHexPath::Encodings);
addCategory("hex.builtin.view.store.tab.constants", "constants", fs::ImHexPath::Constants);
addCategory("hex.builtin.view.store.tab.themes", "themes", fs::ImHexPath::Themes, [this]{
auto themeFile = wolv::io::File(this->m_downloadPath, wolv::io::File::Mode::Read);
auto themeFile = wolv::io::File(m_downloadPath, wolv::io::File::Mode::Read);
ThemeManager::addTheme(themeFile.readString());
});
@@ -114,12 +114,12 @@ namespace hex::plugin::builtin {
const auto buttonSize = ImVec2(100_scaled, ImGui::GetTextLineHeightWithSpacing());
ImGui::PushID(id);
ImGui::BeginDisabled(this->m_updateAllTask.isRunning() || (this->m_download.valid() && this->m_download.wait_for(0s) != std::future_status::ready));
ImGui::BeginDisabled(m_updateAllTask.isRunning() || (m_download.valid() && m_download.wait_for(0s) != std::future_status::ready));
{
if (entry.downloading) {
ImGui::ProgressBar(this->m_httpRequest.getProgress(), buttonSize, "");
ImGui::ProgressBar(m_httpRequest.getProgress(), buttonSize, "");
if (this->m_download.valid() && this->m_download.wait_for(0s) == std::future_status::ready) {
if (m_download.valid() && m_download.wait_for(0s) == std::future_status::ready) {
this->handleDownloadFinished(category, entry);
}
@@ -169,8 +169,8 @@ namespace hex::plugin::builtin {
ImGuiExt::Header("hex.builtin.view.store.desc"_lang, true);
bool reloading = false;
if (this->m_apiRequest.valid()) {
if (this->m_apiRequest.wait_for(0s) != std::future_status::ready)
if (m_apiRequest.valid()) {
if (m_apiRequest.wait_for(0s) != std::future_status::ready)
reloading = true;
else
this->parseResponse();
@@ -189,15 +189,15 @@ namespace hex::plugin::builtin {
// Align the button to the right
ImGui::SameLine(ImGui::GetWindowWidth() - ImGui::GetCursorPosX() - 25_scaled);
ImGui::BeginDisabled(this->m_updateAllTask.isRunning() || this->m_updateCount == 0);
ImGui::BeginDisabled(m_updateAllTask.isRunning() || m_updateCount == 0);
if (ImGuiExt::IconButton(ICON_VS_CLOUD_DOWNLOAD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
this->m_updateAllTask = TaskManager::createTask("Update All...", this->m_updateCount, [this](auto &task) {
m_updateAllTask = TaskManager::createTask("Update All...", m_updateCount, [this](auto &task) {
u32 progress = 0;
for (auto &category : this->m_categories) {
for (auto &category : m_categories) {
for (auto &entry : category.entries) {
if (entry.hasUpdate) {
entry.downloading = this->download(category.path, entry.fileName, entry.link, true);
this->m_download.wait();
m_download.wait();
this->handleDownloadFinished(category, entry);
task.update(progress);
}
@@ -205,12 +205,12 @@ namespace hex::plugin::builtin {
}
});
}
ImGuiExt::InfoTooltip(hex::format("hex.builtin.view.store.update_count"_lang, this->m_updateCount.load()).c_str());
ImGuiExt::InfoTooltip(hex::format("hex.builtin.view.store.update_count"_lang, m_updateCount.load()).c_str());
ImGui::EndDisabled();
if (ImGui::BeginTabBar("storeTabs")) {
for (auto &category : this->m_categories) {
for (auto &category : m_categories) {
this->drawTab(category);
}
@@ -221,22 +221,22 @@ namespace hex::plugin::builtin {
void ViewStore::refresh() {
// Do not refresh if a refresh is already in progress
if (this->m_requestStatus == RequestStatus::InProgress)
if (m_requestStatus == RequestStatus::InProgress)
return;
this->m_requestStatus = RequestStatus::InProgress;
m_requestStatus = RequestStatus::InProgress;
for (auto &category : this->m_categories) {
for (auto &category : m_categories) {
category.entries.clear();
}
this->m_httpRequest.setUrl(ImHexApiURL + "/store"s);
this->m_apiRequest = this->m_httpRequest.execute();
m_httpRequest.setUrl(ImHexApiURL + "/store"s);
m_apiRequest = m_httpRequest.execute();
}
void ViewStore::parseResponse() {
auto response = this->m_apiRequest.get();
this->m_requestStatus = response.isSuccess() ? RequestStatus::Succeeded : RequestStatus::Failed;
if (this->m_requestStatus == RequestStatus::Succeeded) {
auto response = m_apiRequest.get();
m_requestStatus = response.isSuccess() ? RequestStatus::Succeeded : RequestStatus::Failed;
if (m_requestStatus == RequestStatus::Succeeded) {
auto json = nlohmann::json::parse(response.getData());
auto parseStoreEntries = [](auto storeJson, StoreCategory &category) {
@@ -262,23 +262,23 @@ namespace hex::plugin::builtin {
});
};
for (auto &category : this->m_categories) {
for (auto &category : m_categories) {
parseStoreEntries(json, category);
}
this->m_updateCount = 0;
for (auto &category : this->m_categories) {
m_updateCount = 0;
for (auto &category : m_categories) {
for (auto &entry : category.entries) {
if (entry.hasUpdate)
this->m_updateCount += 1;
m_updateCount += 1;
}
}
}
this->m_apiRequest = {};
m_apiRequest = {};
}
void ViewStore::drawContent() {
if (this->m_requestStatus == RequestStatus::Failed)
if (m_requestStatus == RequestStatus::Failed)
ImGuiExt::TextFormattedColored(ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed), "hex.builtin.view.store.netfailed"_lang);
this->drawStore();
@@ -301,10 +301,10 @@ namespace hex::plugin::builtin {
if (!update || wolv::io::fs::exists(fullPath)) {
downloading = true;
this->m_downloadPath = fullPath;
m_downloadPath = fullPath;
this->m_httpRequest.setUrl(url);
this->m_download = this->m_httpRequest.downloadFile(fullPath);
m_httpRequest.setUrl(url);
m_download = m_httpRequest.downloadFile(fullPath);
break;
}
}
@@ -334,27 +334,27 @@ namespace hex::plugin::builtin {
}
void ViewStore::addCategory(const UnlocalizedString &unlocalizedName, const std::string &requestName, fs::ImHexPath path, std::function<void()> downloadCallback) {
this->m_categories.push_back({ unlocalizedName, requestName, path, { }, std::move(downloadCallback) });
m_categories.push_back({ unlocalizedName, requestName, path, { }, std::move(downloadCallback) });
}
void ViewStore::handleDownloadFinished(const StoreCategory &category, StoreEntry &entry) {
entry.downloading = false;
auto response = this->m_download.get();
auto response = m_download.get();
if (response.isSuccess()) {
if (entry.hasUpdate)
this->m_updateCount -= 1;
m_updateCount -= 1;
entry.installed = true;
entry.hasUpdate = false;
entry.system = false;
if (entry.isFolder) {
Tar tar(this->m_downloadPath, Tar::Mode::Read);
tar.extractAll(this->m_downloadPath.parent_path() / this->m_downloadPath.stem());
EventStoreContentDownloaded::post(this->m_downloadPath.parent_path() / this->m_downloadPath.stem());
Tar tar(m_downloadPath, Tar::Mode::Read);
tar.extractAll(m_downloadPath.parent_path() / m_downloadPath.stem());
EventStoreContentDownloaded::post(m_downloadPath.parent_path() / m_downloadPath.stem());
} else {
EventStoreContentDownloaded::post(this->m_downloadPath);
EventStoreContentDownloaded::post(m_downloadPath);
}
category.downloadCallback();
@@ -362,7 +362,7 @@ namespace hex::plugin::builtin {
log::error("Download failed! HTTP Code {}", response.getStatusCode());
this->m_download = {};
m_download = {};
}
}

View File

@@ -28,9 +28,9 @@ namespace hex::plugin::builtin {
// Loop over all the individual theme settings
for (auto &[colorName, colorId] : handler.colorMap) {
if (this->m_startingColor.has_value()) {
if (this->m_hoveredColorId == colorId && this->m_hoveredHandlerName == name) {
handler.setFunction(colorId, this->m_startingColor.value());
if (m_startingColor.has_value()) {
if (m_hoveredColorId == colorId && m_hoveredHandlerName == name) {
handler.setFunction(colorId, m_startingColor.value());
}
}
@@ -47,17 +47,17 @@ namespace hex::plugin::builtin {
if (ImGui::IsItemHovered()) {
anyColorHovered = true;
if (!this->m_hoveredColorId.has_value()) {
this->m_hoveredColorId = colorId;
this->m_startingColor = color;
this->m_hoveredHandlerName = name;
if (!m_hoveredColorId.has_value()) {
m_hoveredColorId = colorId;
m_startingColor = color;
m_hoveredHandlerName = name;
}
}
}
}
if (this->m_hoveredHandlerName == name && this->m_startingColor.has_value() && this->m_hoveredColorId.has_value()) {
auto flashingColor = this->m_startingColor.value();
if (m_hoveredHandlerName == name && m_startingColor.has_value() && m_hoveredColorId.has_value()) {
auto flashingColor = m_startingColor.value();
const float flashProgress = std::min(1.0F, (1.0F + sinf(ImGui::GetTime() * 6)) / 2.0F);
flashingColor.Value.x = std::lerp(flashingColor.Value.x / 2, 1.0F, flashProgress);
@@ -65,12 +65,12 @@ namespace hex::plugin::builtin {
flashingColor.Value.z = flashingColor.Value.z / 2;
flashingColor.Value.w = 1.0F;
handler.setFunction(*this->m_hoveredColorId, flashingColor);
handler.setFunction(*m_hoveredColorId, flashingColor);
if (!anyColorHovered) {
handler.setFunction(this->m_hoveredColorId.value(), this->m_startingColor.value());
this->m_startingColor.reset();
this->m_hoveredColorId.reset();
handler.setFunction(m_hoveredColorId.value(), m_startingColor.value());
m_startingColor.reset();
m_hoveredColorId.reset();
}
}
}
@@ -110,13 +110,13 @@ namespace hex::plugin::builtin {
// Draw export settings
ImGuiExt::Header("hex.builtin.view.theme_manager.export"_lang);
ImGuiExt::InputTextIcon("hex.builtin.view.theme_manager.export.name"_lang, ICON_VS_SYMBOL_KEY, this->m_themeName);
ImGuiExt::InputTextIcon("hex.builtin.view.theme_manager.export.name"_lang, ICON_VS_SYMBOL_KEY, m_themeName);
// Draw the export buttons
if (ImGui::Button("hex.builtin.view.theme_manager.save_theme"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
fs::openFileBrowser(fs::DialogMode::Save, { { "ImHex Theme", "json" } }, [this](const std::fs::path &path){
// Export the current theme as json
auto json = ThemeManager::exportCurrentTheme(this->m_themeName);
auto json = ThemeManager::exportCurrentTheme(m_themeName);
// Write the json to the file
wolv::io::File outputFile(path, wolv::io::File::Mode::Create);

View File

@@ -6,7 +6,7 @@
namespace hex::plugin::builtin {
ViewTools::ViewTools() : View::Window("hex.builtin.view.tools.name") {
this->m_dragStartIterator = ContentRegistry::Tools::impl::getEntries().end();
m_dragStartIterator = ContentRegistry::Tools::impl::getEntries().end();
}
void ViewTools::drawContent() {
@@ -27,15 +27,15 @@ namespace hex::plugin::builtin {
// Handle dragging the tool out of the main window
// If the user clicks on the header, start dragging the tool remember the iterator
if (ImGui::IsMouseClicked(0) && ImGui::IsItemActivated() && this->m_dragStartIterator == tools.end())
this->m_dragStartIterator = iter;
if (ImGui::IsMouseClicked(0) && ImGui::IsItemActivated() && m_dragStartIterator == tools.end())
m_dragStartIterator = iter;
// If the user released the mouse button, stop dragging the tool
if (!ImGui::IsMouseDown(0))
this->m_dragStartIterator = tools.end();
m_dragStartIterator = tools.end();
// Detach the tool if the user dragged it out of the main window
if (!ImGui::IsItemHovered() && this->m_dragStartIterator == iter) {
if (!ImGui::IsItemHovered() && m_dragStartIterator == iter) {
detached = true;
}
@@ -62,8 +62,8 @@ namespace hex::plugin::builtin {
function();
// Handle the first frame after the tool has been detached
if (ImGui::IsWindowAppearing() && this->m_dragStartIterator == iter) {
this->m_dragStartIterator = tools.end();
if (ImGui::IsWindowAppearing() && m_dragStartIterator == iter) {
m_dragStartIterator = tools.end();
// Attach the newly created window to the cursor, so it gets dragged around
GImGui->MovingWindow = ImGui::GetCurrentWindowRead();

View File

@@ -27,14 +27,14 @@ namespace hex::plugin::builtin {
if (ImGui::BeginTable("Tutorials", 1, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImGui::GetContentRegionAvail())) {
for (const auto &tutorial : tutorials | std::views::values) {
if (this->m_selectedTutorial == nullptr)
this->m_selectedTutorial = &tutorial;
if (m_selectedTutorial == nullptr)
m_selectedTutorial = &tutorial;
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::Selectable(Lang(tutorial.getUnlocalizedName()), this->m_selectedTutorial == &tutorial, ImGuiSelectableFlags_SpanAllColumns)) {
this->m_selectedTutorial = &tutorial;
if (ImGui::Selectable(Lang(tutorial.getUnlocalizedName()), m_selectedTutorial == &tutorial, ImGuiSelectableFlags_SpanAllColumns)) {
m_selectedTutorial = &tutorial;
}
}
@@ -43,16 +43,16 @@ namespace hex::plugin::builtin {
ImGui::TableNextColumn();
if (this->m_selectedTutorial != nullptr) {
if (m_selectedTutorial != nullptr) {
ImGuiExt::BeginSubWindow("hex.builtin.view.tutorials.description"_lang, ImGui::GetContentRegionAvail() - ImVec2(0, ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().ItemSpacing.y * 2));
{
ImGuiExt::TextFormattedWrapped(Lang(this->m_selectedTutorial->getUnlocalizedDescription()));
ImGuiExt::TextFormattedWrapped(Lang(m_selectedTutorial->getUnlocalizedDescription()));
}
ImGuiExt::EndSubWindow();
ImGui::BeginDisabled(currTutorial != tutorials.end());
if (ImGuiExt::DimmedButton("hex.builtin.view.tutorials.start"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
TutorialManager::startTutorial(this->m_selectedTutorial->getUnlocalizedName());
TutorialManager::startTutorial(m_selectedTutorial->getUnlocalizedName());
}
ImGui::EndDisabled();
}

View File

@@ -58,7 +58,7 @@ namespace hex::plugin::builtin {
if (!rules.is_array())
return false;
this->m_matches.get(provider).clear();
m_matches.get(provider).clear();
for (auto &rule : rules) {
if (!rule.contains("name") || !rule.contains("path"))
@@ -70,7 +70,7 @@ namespace hex::plugin::builtin {
if (!name.is_string() || !path.is_string())
return false;
this->m_rules.get(provider).emplace_back(std::fs::path(name.get<std::string>()), std::fs::path(path.get<std::string>()));
m_rules.get(provider).emplace_back(std::fs::path(name.get<std::string>()), std::fs::path(path.get<std::string>()));
}
return true;
@@ -80,7 +80,7 @@ namespace hex::plugin::builtin {
data["rules"] = nlohmann::json::array();
for (auto &[name, path] : this->m_rules.get(provider)) {
for (auto &[name, path] : m_rules.get(provider)) {
data["rules"].push_back({
{ "name", wolv::util::toUTF8String(name) },
{ "path", wolv::util::toUTF8String(path) }
@@ -102,10 +102,10 @@ namespace hex::plugin::builtin {
ImGuiExt::Header("hex.builtin.view.yara.header.rules"_lang, true);
if (ImGui::BeginListBox("##rules", ImVec2(-FLT_MIN, ImGui::GetTextLineHeightWithSpacing() * 5))) {
for (u32 i = 0; i < this->m_rules->size(); i++) {
const bool selected = (this->m_selectedRule == i);
if (ImGui::Selectable(wolv::util::toUTF8String((*this->m_rules)[i].first).c_str(), selected)) {
this->m_selectedRule = i;
for (u32 i = 0; i < m_rules->size(); i++) {
const bool selected = (m_selectedRule == i);
if (ImGui::Selectable(wolv::util::toUTF8String((*m_rules)[i].first).c_str(), selected)) {
m_selectedRule = i;
}
}
ImGui::EndListBox();
@@ -126,15 +126,15 @@ namespace hex::plugin::builtin {
PopupFileChooser::open(basePaths, paths, std::vector<hex::fs::ItemFilter>{ { "Yara File", "yara" }, { "Yara File", "yar" } }, true,
[&](const auto &path) {
this->m_rules->push_back({ path.filename(), path });
m_rules->push_back({ path.filename(), path });
});
}
ImGui::SameLine();
if (ImGuiExt::IconButton(ICON_VS_REMOVE, ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
if (this->m_selectedRule < this->m_rules->size()) {
this->m_rules->erase(this->m_rules->begin() + this->m_selectedRule);
this->m_selectedRule = std::min(this->m_selectedRule, u32(this->m_rules->size() - 1));
if (m_selectedRule < m_rules->size()) {
m_rules->erase(m_rules->begin() + m_selectedRule);
m_selectedRule = std::min(m_selectedRule, u32(m_rules->size() - 1));
}
}
@@ -142,7 +142,7 @@ namespace hex::plugin::builtin {
if (ImGui::Button("hex.builtin.view.yara.match"_lang)) this->applyRules();
ImGui::SameLine();
if (this->m_matcherTask.isRunning()) {
if (m_matcherTask.isRunning()) {
ImGui::SameLine();
ImGuiExt::TextSpinner("hex.builtin.view.yara.matching"_lang);
}
@@ -163,13 +163,13 @@ namespace hex::plugin::builtin {
ImGui::TableHeadersRow();
auto sortSpecs = ImGui::TableGetSortSpecs();
if (!this->m_matches->empty() && (sortSpecs->SpecsDirty || this->m_sortedMatches->empty())) {
this->m_sortedMatches->clear();
std::transform(this->m_matches->begin(), this->m_matches->end(), std::back_inserter(*this->m_sortedMatches), [](auto &match) {
if (!m_matches->empty() && (sortSpecs->SpecsDirty || m_sortedMatches->empty())) {
m_sortedMatches->clear();
std::transform(m_matches->begin(), m_matches->end(), std::back_inserter(*m_sortedMatches), [](auto &match) {
return &match;
});
std::sort(this->m_sortedMatches->begin(), this->m_sortedMatches->end(), [&sortSpecs](const YaraMatch *left, const YaraMatch *right) -> bool {
std::sort(m_sortedMatches->begin(), m_sortedMatches->end(), [&sortSpecs](const YaraMatch *left, const YaraMatch *right) -> bool {
if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("identifier"))
return left->identifier < right->identifier;
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("variable"))
@@ -183,18 +183,18 @@ namespace hex::plugin::builtin {
});
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Descending)
std::reverse(this->m_sortedMatches->begin(), this->m_sortedMatches->end());
std::reverse(m_sortedMatches->begin(), m_sortedMatches->end());
sortSpecs->SpecsDirty = false;
}
if (!this->m_matcherTask.isRunning()) {
if (!m_matcherTask.isRunning()) {
ImGuiListClipper clipper;
clipper.Begin(this->m_sortedMatches->size());
clipper.Begin(m_sortedMatches->size());
while (clipper.Step()) {
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
auto &[identifier, variableName, address, size, wholeDataMatch, highlightId, tooltipId] = *(*this->m_sortedMatches)[i];
auto &[identifier, variableName, address, size, wholeDataMatch, highlightId, tooltipId] = *(*m_sortedMatches)[i];
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::PushID(i);
@@ -232,10 +232,10 @@ namespace hex::plugin::builtin {
if (ImGui::BeginChild("##console", consoleSize, true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_HorizontalScrollbar)) {
ImGuiListClipper clipper;
clipper.Begin(this->m_consoleMessages.size());
clipper.Begin(m_consoleMessages.size());
while (clipper.Step())
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
const auto &message = this->m_consoleMessages[i];
const auto &message = m_consoleMessages[i];
if (ImGui::Selectable(message.c_str()))
ImGui::SetClipboardText(message.c_str());
@@ -245,19 +245,19 @@ namespace hex::plugin::builtin {
}
void ViewYara::clearResult() {
for (const auto &match : *this->m_matches) {
for (const auto &match : *m_matches) {
ImHexApi::HexEditor::removeBackgroundHighlight(match.highlightId);
ImHexApi::HexEditor::removeTooltip(match.tooltipId);
}
this->m_matches->clear();
this->m_consoleMessages.clear();
m_matches->clear();
m_consoleMessages.clear();
}
void ViewYara::applyRules() {
this->clearResult();
this->m_matcherTask = TaskManager::createTask("hex.builtin.view.yara.matching", 0, [this](auto &task) {
m_matcherTask = TaskManager::createTask("hex.builtin.view.yara.matching", 0, [this](auto &task) {
if (!ImHexApi::Provider::isValid()) return;
struct ResultContext {
@@ -269,7 +269,7 @@ namespace hex::plugin::builtin {
ResultContext resultContext;
resultContext.task = &task;
for (const auto &[fileName, filePath] : *this->m_rules) {
for (const auto &[fileName, filePath] : *m_rules) {
YR_COMPILER *compiler = nullptr;
yr_compiler_create(&compiler);
ON_SCOPE_EXIT {
@@ -300,7 +300,7 @@ namespace hex::plugin::builtin {
currFilePath.data()
);
wolv::io::File file((*this->m_rules)[this->m_selectedRule].second, wolv::io::File::Mode::Read);
wolv::io::File file((*m_rules)[m_selectedRule].second, wolv::io::File::Mode::Read);
if (!file.isValid()) return;
if (yr_compiler_add_file(compiler, file.getHandle(), nullptr, nullptr) != 0) {
@@ -310,7 +310,7 @@ namespace hex::plugin::builtin {
TaskManager::doLater([this, errorMessage = wolv::util::trim(errorMessage)] {
this->clearResult();
this->m_consoleMessages.push_back(hex::format("hex.builtin.view.yara.error"_lang, errorMessage));
m_consoleMessages.push_back(hex::format("hex.builtin.view.yara.error"_lang, errorMessage));
});
return;
@@ -417,22 +417,22 @@ namespace hex::plugin::builtin {
}
TaskManager::doLater([this, resultContext] {
for (const auto &match : *this->m_matches) {
for (const auto &match : *m_matches) {
ImHexApi::HexEditor::removeBackgroundHighlight(match.highlightId);
ImHexApi::HexEditor::removeTooltip(match.tooltipId);
}
this->m_consoleMessages = resultContext.consoleMessages;
m_consoleMessages = resultContext.consoleMessages;
std::move(resultContext.newMatches.begin(), resultContext.newMatches.end(), std::back_inserter(*this->m_matches));
std::move(resultContext.newMatches.begin(), resultContext.newMatches.end(), std::back_inserter(*m_matches));
auto uniques = std::set(this->m_matches->begin(), this->m_matches->end(), [](const auto &l, const auto &r) {
auto uniques = std::set(m_matches->begin(), m_matches->end(), [](const auto &l, const auto &r) {
return std::tie(l.address, l.size, l.wholeDataMatch, l.identifier, l.variable) <
std::tie(r.address, r.size, r.wholeDataMatch, r.identifier, r.variable);
});
this->m_matches->clear();
std::move(uniques.begin(), uniques.end(), std::back_inserter(*this->m_matches));
m_matches->clear();
std::move(uniques.begin(), uniques.end(), std::back_inserter(*m_matches));
constexpr static color_t YaraColor = 0x70B4771F;
for (auto &match : uniques) {

View File

@@ -55,31 +55,31 @@ namespace hex::plugin::builtin {
m_restoreCallback(restoreCallback),
m_deleteCallback(deleteCallback) {
this->m_reportError = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.upload_crash_logs", true);
m_reportError = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.upload_crash_logs", true);
}
void drawContent() override {
ImGui::TextUnformatted("hex.builtin.popup.safety_backup.desc"_lang);
if (!this->m_logFilePath.empty()) {
if (!m_logFilePath.empty()) {
ImGui::NewLine();
ImGui::TextUnformatted("hex.builtin.popup.safety_backup.log_file"_lang);
ImGui::SameLine(0, 2_scaled);
if (ImGuiExt::Hyperlink(this->m_logFilePath.filename().string().c_str())) {
fs::openFolderWithSelectionExternal(this->m_logFilePath);
if (ImGuiExt::Hyperlink(m_logFilePath.filename().string().c_str())) {
fs::openFolderWithSelectionExternal(m_logFilePath);
}
ImGui::Checkbox("hex.builtin.popup.safety_backup.report_error"_lang, &this->m_reportError);
ImGui::Checkbox("hex.builtin.popup.safety_backup.report_error"_lang, &m_reportError);
ImGui::NewLine();
}
auto width = ImGui::GetWindowWidth();
ImGui::SetCursorPosX(width / 9);
if (ImGui::Button("hex.builtin.popup.safety_backup.restore"_lang, ImVec2(width / 3, 0))) {
this->m_restoreCallback();
this->m_deleteCallback();
m_restoreCallback();
m_deleteCallback();
if (this->m_reportError) {
wolv::io::File logFile(this->m_logFilePath, wolv::io::File::Mode::Read);
if (m_reportError) {
wolv::io::File logFile(m_logFilePath, wolv::io::File::Mode::Read);
if (logFile.isValid()) {
// Read current log file data
auto data = logFile.readString();
@@ -94,21 +94,21 @@ namespace hex::plugin::builtin {
}
}
TaskManager::createBackgroundTask("Upload Crash report", [path = this->m_logFilePath, data](auto&){
TaskManager::createBackgroundTask("Upload Crash report", [path = m_logFilePath, data](auto&){
HttpRequest request("POST", ImHexApiURL + std::string("/crash_upload"));
request.uploadFile(std::vector<u8>(data.begin(), data.end()), "file", path.filename()).wait();
});
}
}
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.upload_crash_logs", this->m_reportError);
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.upload_crash_logs", m_reportError);
this->close();
}
ImGui::SameLine();
ImGui::SetCursorPosX(width / 9 * 5);
if (ImGui::Button("hex.builtin.popup.safety_backup.delete"_lang, ImVec2(width / 3, 0)) || ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Escape))) {
this->m_deleteCallback();
m_deleteCallback();
this->close();
}

View File

@@ -70,14 +70,14 @@ namespace hex::plugin::builtin::ui {
/* Hex Editor */
HexEditor::HexEditor(prv::Provider *provider) : m_provider(provider) {
this->m_currDataVisualizer = ContentRegistry::HexEditor::getVisualizerByName("hex.builtin.visualizer.hexadecimal.8bit");
this->m_bytesPerRow = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.bytes_per_row", this->m_bytesPerRow);
m_currDataVisualizer = ContentRegistry::HexEditor::getVisualizerByName("hex.builtin.visualizer.hexadecimal.8bit");
m_bytesPerRow = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.bytes_per_row", m_bytesPerRow);
EventSettingsChanged::subscribe(this, [this] {
this->m_selectionColor = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.highlight_color", 0x60C08080);
this->m_syncScrolling = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.sync_scrolling", false);
this->m_byteCellPadding = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.byte_padding", false);
this->m_characterCellPadding = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.char_padding", false);
m_selectionColor = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.highlight_color", 0x60C08080);
m_syncScrolling = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.sync_scrolling", false);
m_byteCellPadding = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.byte_padding", false);
m_characterCellPadding = ContentRegistry::Settings::read("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.char_padding", false);
});
}
@@ -99,14 +99,14 @@ namespace hex::plugin::builtin::ui {
if (byteAddress >= selection.getStartAddress() && byteAddress <= selection.getEndAddress()) {
if (color.has_value())
color = (ImAlphaBlendColors(color.value(), this->m_selectionColor)) & 0x00FFFFFF;
color = (ImAlphaBlendColors(color.value(), m_selectionColor)) & 0x00FFFFFF;
else
color = this->m_selectionColor;
color = m_selectionColor;
}
}
if (color.has_value())
color = (*color & 0x00FFFFFF) | (this->m_selectionColor & 0xFF000000);
color = (*color & 0x00FFFFFF) | (m_selectionColor & 0xFF000000);
return color;
}
@@ -152,7 +152,7 @@ namespace hex::plugin::builtin::ui {
void HexEditor::drawTooltip(u64 address, const u8 *data, size_t size) const {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, scaled(ImVec2(5, 5)));
this->m_tooltipCallback(address, data, size);
m_tooltipCallback(address, data, size);
ImGui::PopStyleVar();
}
@@ -160,39 +160,39 @@ namespace hex::plugin::builtin::ui {
void HexEditor::drawCell(u64 address, const u8 *data, size_t size, bool hovered, CellType cellType) {
static DataVisualizerAscii asciiVisualizer;
if (this->m_shouldUpdateEditingValue && address == this->m_editingAddress) {
this->m_shouldUpdateEditingValue = false;
if (m_shouldUpdateEditingValue && address == m_editingAddress) {
m_shouldUpdateEditingValue = false;
if (this->m_editingBytes.size() < size) {
this->m_editingBytes.resize(size);
if (m_editingBytes.size() < size) {
m_editingBytes.resize(size);
}
std::memcpy(this->m_editingBytes.data(), data, size);
std::memcpy(m_editingBytes.data(), data, size);
}
if (this->m_editingAddress != address || this->m_editingCellType != cellType) {
if (m_editingAddress != address || m_editingCellType != cellType) {
if (cellType == CellType::Hex) {
std::vector<u8> buffer(size);
std::memcpy(buffer.data(), data, size);
if (this->m_dataVisualizerEndianness != std::endian::native)
if (m_dataVisualizerEndianness != std::endian::native)
std::reverse(buffer.begin(), buffer.end());
this->m_currDataVisualizer->draw(address, buffer.data(), buffer.size(), this->m_upperCaseHex);
m_currDataVisualizer->draw(address, buffer.data(), buffer.size(), m_upperCaseHex);
} else {
asciiVisualizer.draw(address, data, size, this->m_upperCaseHex);
asciiVisualizer.draw(address, data, size, m_upperCaseHex);
}
if (hovered && this->m_provider->isWritable()) {
if (hovered && m_provider->isWritable()) {
// Enter editing mode when double-clicking a cell
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
this->m_editingAddress = address;
this->m_shouldModifyValue = false;
this->m_enteredEditingMode = true;
m_editingAddress = address;
m_shouldModifyValue = false;
m_enteredEditingMode = true;
this->m_editingBytes.resize(size);
std::memcpy(this->m_editingBytes.data(), data, size);
this->m_editingCellType = cellType;
m_editingBytes.resize(size);
std::memcpy(m_editingBytes.data(), data, size);
m_editingCellType = cellType;
}
}
}
@@ -201,64 +201,64 @@ namespace hex::plugin::builtin::ui {
ImGui::SetNextFrameWantCaptureKeyboard(true);
bool shouldExitEditingMode = true;
if (cellType == this->m_editingCellType && cellType == CellType::Hex) {
std::vector<u8> buffer = this->m_editingBytes;
if (cellType == m_editingCellType && cellType == CellType::Hex) {
std::vector<u8> buffer = m_editingBytes;
if (this->m_dataVisualizerEndianness != std::endian::native)
if (m_dataVisualizerEndianness != std::endian::native)
std::reverse(buffer.begin(), buffer.end());
shouldExitEditingMode = this->m_currDataVisualizer->drawEditing(*this->m_editingAddress, buffer.data(), buffer.size(), this->m_upperCaseHex, this->m_enteredEditingMode);
shouldExitEditingMode = m_currDataVisualizer->drawEditing(*m_editingAddress, buffer.data(), buffer.size(), m_upperCaseHex, m_enteredEditingMode);
if (this->m_dataVisualizerEndianness != std::endian::native)
if (m_dataVisualizerEndianness != std::endian::native)
std::reverse(buffer.begin(), buffer.end());
this->m_editingBytes = buffer;
} else if (cellType == this->m_editingCellType && cellType == CellType::ASCII) {
shouldExitEditingMode = asciiVisualizer.drawEditing(*this->m_editingAddress, this->m_editingBytes.data(), this->m_editingBytes.size(), this->m_upperCaseHex, this->m_enteredEditingMode);
m_editingBytes = buffer;
} else if (cellType == m_editingCellType && cellType == CellType::ASCII) {
shouldExitEditingMode = asciiVisualizer.drawEditing(*m_editingAddress, m_editingBytes.data(), m_editingBytes.size(), m_upperCaseHex, m_enteredEditingMode);
}
if (shouldExitEditingMode || this->m_shouldModifyValue) {
if (shouldExitEditingMode || m_shouldModifyValue) {
{
std::vector<u8> oldData(this->m_editingBytes.size());
this->m_provider->read(*this->m_editingAddress, oldData.data(), oldData.size());
std::vector<u8> oldData(m_editingBytes.size());
m_provider->read(*m_editingAddress, oldData.data(), oldData.size());
size_t writtenBytes = 0;
for (size_t i = 0; i < this->m_editingBytes.size(); i += 1) {
if (this->m_editingBytes[i] != oldData[i]) {
this->m_provider->write(*this->m_editingAddress, &this->m_editingBytes[i], 1);
for (size_t i = 0; i < m_editingBytes.size(); i += 1) {
if (m_editingBytes[i] != oldData[i]) {
m_provider->write(*m_editingAddress, &m_editingBytes[i], 1);
writtenBytes += 1;
}
}
this->m_provider->getUndoStack().groupOperations(writtenBytes, "hex.builtin.undo_operation.modification");
m_provider->getUndoStack().groupOperations(writtenBytes, "hex.builtin.undo_operation.modification");
}
if (!this->m_selectionChanged && !ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsKeyDown(ImGuiKey_Escape)) {
auto nextEditingAddress = *this->m_editingAddress + this->m_currDataVisualizer->getBytesPerCell();
if (!m_selectionChanged && !ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsKeyDown(ImGuiKey_Escape)) {
auto nextEditingAddress = *m_editingAddress + m_currDataVisualizer->getBytesPerCell();
this->setSelection(nextEditingAddress, nextEditingAddress);
if (nextEditingAddress >= this->m_provider->getBaseAddress() + this->m_provider->getCurrentPageAddress() + this->m_provider->getSize())
this->m_editingAddress = std::nullopt;
if (nextEditingAddress >= m_provider->getBaseAddress() + m_provider->getCurrentPageAddress() + m_provider->getSize())
m_editingAddress = std::nullopt;
else
this->m_editingAddress = nextEditingAddress;
m_editingAddress = nextEditingAddress;
} else {
this->m_editingAddress = std::nullopt;
m_editingAddress = std::nullopt;
}
this->m_shouldModifyValue = false;
this->m_shouldUpdateEditingValue = true;
m_shouldModifyValue = false;
m_shouldUpdateEditingValue = true;
}
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !hovered && !this->m_enteredEditingMode) {
this->m_editingAddress = std::nullopt;
this->m_shouldModifyValue = false;
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !hovered && !m_enteredEditingMode) {
m_editingAddress = std::nullopt;
m_shouldModifyValue = false;
}
if (!this->m_editingAddress.has_value())
this->m_editingCellType = CellType::None;
if (!m_editingAddress.has_value())
m_editingCellType = CellType::None;
this->m_enteredEditingMode = false;
m_enteredEditingMode = false;
}
}
@@ -280,15 +280,15 @@ namespace hex::plugin::builtin::ui {
drawList->AddLine(cellPos, cellPos + ImVec2(0, cellSize.y), ImColor(SelectionFrameColor), 1_scaled);
// Draw vertical line at the right of the last byte and the end of the line
if (x == u16((this->m_bytesPerRow / bytesPerCell) - 1) || (byteAddress + bytesPerCell) > selection.getEndAddress())
if (x == u16((m_bytesPerRow / bytesPerCell) - 1) || (byteAddress + bytesPerCell) > selection.getEndAddress())
drawList->AddLine(cellPos + ImVec2(cellSize.x, -1), cellPos + cellSize, ImColor(SelectionFrameColor), 1_scaled);
// Draw horizontal line at the top of the bytes
if (y == 0 || (byteAddress - this->m_bytesPerRow) < selection.getStartAddress())
if (y == 0 || (byteAddress - m_bytesPerRow) < selection.getStartAddress())
drawList->AddLine(cellPos, cellPos + ImVec2(cellSize.x + 1, 0), ImColor(SelectionFrameColor), 1_scaled);
// Draw horizontal line at the bottom of the bytes
if ((byteAddress + this->m_bytesPerRow) > selection.getEndAddress())
if ((byteAddress + m_bytesPerRow) > selection.getEndAddress())
drawList->AddLine(cellPos + ImVec2(0, cellSize.y), cellPos + cellSize + ImVec2(1, 0), ImColor(SelectionFrameColor), 1_scaled);
}
@@ -296,19 +296,19 @@ namespace hex::plugin::builtin::ui {
const float SeparatorColumWidth = 6_scaled;
const auto CharacterSize = ImGui::CalcTextSize("0");
const auto bytesPerCell = this->m_currDataVisualizer->getBytesPerCell();
const u16 columnCount = this->m_bytesPerRow / bytesPerCell;
const auto bytesPerCell = m_currDataVisualizer->getBytesPerCell();
const u16 columnCount = m_bytesPerRow / bytesPerCell;
auto byteColumnCount = 2 + columnCount + getByteColumnSeparatorCount(columnCount) + 2 + 2;
if (byteColumnCount >= IMGUI_TABLE_MAX_COLUMNS) {
this->m_bytesPerRow = 64;
ContentRegistry::Settings::write("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.bytes_per_row", this->m_bytesPerRow);
m_bytesPerRow = 64;
ContentRegistry::Settings::write("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.bytes_per_row", m_bytesPerRow);
return;
}
const auto selection = getSelection();
if (this->m_provider == nullptr || this->m_provider->getActualSize() == 0) {
if (m_provider == nullptr || m_provider->getActualSize() == 0) {
ImGuiExt::TextFormattedCentered("{}", "hex.builtin.hex_editor.no_bytes"_lang);
}
@@ -326,14 +326,14 @@ namespace hex::plugin::builtin::ui {
if (isColumnSeparatorColumn(i, columnCount))
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, SeparatorColumWidth);
ImGui::TableSetupColumn(hex::format(this->m_upperCaseHex ? "{:0{}X}" : "{:0{}x}", i * bytesPerCell, this->m_currDataVisualizer->getMaxCharsPerCell()).c_str(), ImGuiTableColumnFlags_WidthFixed, CharacterSize.x * this->m_currDataVisualizer->getMaxCharsPerCell() + (6 + this->m_byteCellPadding) * 1_scaled);
ImGui::TableSetupColumn(hex::format(m_upperCaseHex ? "{:0{}X}" : "{:0{}x}", i * bytesPerCell, m_currDataVisualizer->getMaxCharsPerCell()).c_str(), ImGuiTableColumnFlags_WidthFixed, CharacterSize.x * m_currDataVisualizer->getMaxCharsPerCell() + (6 + m_byteCellPadding) * 1_scaled);
}
// ASCII column
ImGui::TableSetupColumn("");
if (this->m_showAscii) {
ImGui::TableSetupColumn("hex.builtin.common.encoding.ascii"_lang, ImGuiTableColumnFlags_WidthFixed, (CharacterSize.x + this->m_characterCellPadding * 1_scaled) * this->m_bytesPerRow);
if (m_showAscii) {
ImGui::TableSetupColumn("hex.builtin.common.encoding.ascii"_lang, ImGuiTableColumnFlags_WidthFixed, (CharacterSize.x + m_characterCellPadding * 1_scaled) * m_bytesPerRow);
}
else
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 0);
@@ -341,8 +341,8 @@ namespace hex::plugin::builtin::ui {
ImGui::TableSetupColumn("");
// Custom encoding column
{
if (this->m_currCustomEncoding.has_value() && this->m_showCustomEncoding) {
ImGui::TableSetupColumn(this->m_currCustomEncoding->getName().c_str(), ImGuiTableColumnFlags_WidthStretch);
if (m_currCustomEncoding.has_value() && m_showCustomEncoding) {
ImGui::TableSetupColumn(m_currCustomEncoding->getName().c_str(), ImGuiTableColumnFlags_WidthStretch);
} else {
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 0);
}
@@ -358,11 +358,11 @@ namespace hex::plugin::builtin::ui {
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (this->m_provider != nullptr && this->m_provider->isReadable()) {
if (m_provider != nullptr && m_provider->isReadable()) {
const auto isCurrRegionValid = [this](u64 address) {
auto &[currRegion, currRegionValid] = this->m_currValidRegion;
auto &[currRegion, currRegionValid] = m_currValidRegion;
if (!Region{ address, 1 }.isWithin(currRegion)) {
this->m_currValidRegion = this->m_provider->getRegionValidity(address);
m_currValidRegion = m_provider->getRegionValidity(address);
}
return currRegionValid;
@@ -370,7 +370,7 @@ namespace hex::plugin::builtin::ui {
ImGuiListClipper clipper;
u64 numRows = std::ceil(this->m_provider->getSize() / static_cast<long double>(this->m_bytesPerRow));
u64 numRows = std::ceil(m_provider->getSize() / static_cast<long double>(m_bytesPerRow));
if (numRows == 0) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
@@ -379,34 +379,34 @@ namespace hex::plugin::builtin::ui {
clipper.Begin(numRows + size.y / CharacterSize.y - 3, CharacterSize.y);
while (clipper.Step()) {
this->m_visibleRowCount = clipper.DisplayEnd - clipper.DisplayStart;
m_visibleRowCount = clipper.DisplayEnd - clipper.DisplayStart;
// Loop over rows
for (u64 y = u64(clipper.DisplayStart); y < std::min(numRows, u64(clipper.DisplayEnd)); y++) {
// Draw address column
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGuiExt::TextFormatted(this->m_upperCaseHex ? "{:08X}: " : "{:08x}: ", y * this->m_bytesPerRow + this->m_provider->getBaseAddress() + this->m_provider->getCurrentPageAddress());
ImGuiExt::TextFormatted(m_upperCaseHex ? "{:08X}: " : "{:08x}: ", y * m_bytesPerRow + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress());
ImGui::TableNextColumn();
const u8 validBytes = std::min<u64>(this->m_bytesPerRow, this->m_provider->getSize() - y * this->m_bytesPerRow);
const u8 validBytes = std::min<u64>(m_bytesPerRow, m_provider->getSize() - y * m_bytesPerRow);
std::vector<u8> bytes(this->m_bytesPerRow, 0x00);
this->m_provider->read(y * this->m_bytesPerRow + this->m_provider->getBaseAddress() + this->m_provider->getCurrentPageAddress(), bytes.data(), validBytes);
std::vector<u8> bytes(m_bytesPerRow, 0x00);
m_provider->read(y * m_bytesPerRow + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress(), bytes.data(), validBytes);
std::vector<std::tuple<std::optional<color_t>, std::optional<color_t>>> cellColors;
{
for (u64 x = 0; x < std::ceil(float(validBytes) / bytesPerCell); x++) {
const u64 byteAddress = y * this->m_bytesPerRow + x * bytesPerCell + this->m_provider->getBaseAddress() + this->m_provider->getCurrentPageAddress();
const u64 byteAddress = y * m_bytesPerRow + x * bytesPerCell + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress();
const auto cellBytes = std::min<u64>(validBytes, bytesPerCell);
// Query cell colors
if (x < std::ceil(float(validBytes) / bytesPerCell)) {
auto foregroundColor = this->m_foregroundColorCallback(byteAddress, &bytes[x * cellBytes], cellBytes);
auto backgroundColor = this->m_backgroundColorCallback(byteAddress, &bytes[x * cellBytes], cellBytes);
auto foregroundColor = m_foregroundColorCallback(byteAddress, &bytes[x * cellBytes], cellBytes);
auto backgroundColor = m_backgroundColorCallback(byteAddress, &bytes[x * cellBytes], cellBytes);
if (this->m_grayOutZero && !foregroundColor.has_value()) {
if (m_grayOutZero && !foregroundColor.has_value()) {
bool allZero = true;
for (u64 i = 0; i < cellBytes && (x * cellBytes + i) < bytes.size(); i++) {
if (bytes[x * cellBytes + i] != 0x00) {
@@ -436,7 +436,7 @@ namespace hex::plugin::builtin::ui {
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, scaled(ImVec2(2.75F, 0.0F)));
for (u64 x = 0; x < columnCount; x++) {
const u64 byteAddress = y * this->m_bytesPerRow + x * bytesPerCell + this->m_provider->getBaseAddress() + this->m_provider->getCurrentPageAddress();
const u64 byteAddress = y * m_bytesPerRow + x * bytesPerCell + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress();
ImGui::TableNextColumn();
if (isColumnSeparatorColumn(x, columnCount))
@@ -444,8 +444,8 @@ namespace hex::plugin::builtin::ui {
if (x < std::ceil(float(validBytes) / bytesPerCell)) {
auto cellStartPos = getCellPosition();
auto cellSize = (CharacterSize * ImVec2(this->m_currDataVisualizer->getMaxCharsPerCell(), 1)) + (ImVec2(2, 2) * ImGui::GetStyle().CellPadding) + scaled(ImVec2(1 + this->m_byteCellPadding, 0));
auto maxCharsPerCell = this->m_currDataVisualizer->getMaxCharsPerCell();
auto cellSize = (CharacterSize * ImVec2(m_currDataVisualizer->getMaxCharsPerCell(), 1)) + (ImVec2(2, 2) * ImGui::GetStyle().CellPadding) + scaled(ImVec2(1 + m_byteCellPadding, 0));
auto maxCharsPerCell = m_currDataVisualizer->getMaxCharsPerCell();
auto [foregroundColor, backgroundColor] = cellColors[x];
@@ -495,21 +495,21 @@ namespace hex::plugin::builtin::ui {
ImGui::TableNextColumn();
// Draw ASCII column
if (this->m_showAscii) {
if (m_showAscii) {
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(0, 0));
if (ImGui::BeginTable("##ascii_column", this->m_bytesPerRow)) {
for (u64 x = 0; x < this->m_bytesPerRow; x++)
ImGui::TableSetupColumn(hex::format("##ascii_cell{}", x).c_str(), ImGuiTableColumnFlags_WidthFixed, CharacterSize.x + this->m_characterCellPadding * 1_scaled);
if (ImGui::BeginTable("##ascii_column", m_bytesPerRow)) {
for (u64 x = 0; x < m_bytesPerRow; x++)
ImGui::TableSetupColumn(hex::format("##ascii_cell{}", x).c_str(), ImGuiTableColumnFlags_WidthFixed, CharacterSize.x + m_characterCellPadding * 1_scaled);
ImGui::TableNextRow();
for (u64 x = 0; x < this->m_bytesPerRow; x++) {
for (u64 x = 0; x < m_bytesPerRow; x++) {
ImGui::TableNextColumn();
const u64 byteAddress = y * this->m_bytesPerRow + x + this->m_provider->getBaseAddress() + this->m_provider->getCurrentPageAddress();
const u64 byteAddress = y * m_bytesPerRow + x + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress();
const auto cellStartPos = getCellPosition();
const auto cellSize = CharacterSize + scaled(ImVec2(this->m_characterCellPadding, 0));
const auto cellSize = CharacterSize + scaled(ImVec2(m_characterCellPadding, 0));
const bool cellHovered = ImGui::IsMouseHoveringRect(cellStartPos, cellStartPos + cellSize, true);
@@ -525,11 +525,11 @@ namespace hex::plugin::builtin::ui {
this->drawSelectionFrame(x, y, selection, byteAddress, 1, cellStartPos, cellSize, backgroundColor.value());
}
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (this->m_characterCellPadding * 1_scaled) / 2);
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (m_characterCellPadding * 1_scaled) / 2);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushItemWidth(CharacterSize.x);
if (!isCurrRegionValid(byteAddress))
ImGuiExt::TextFormattedDisabled("{}", this->m_unknownDataCharacter);
ImGuiExt::TextFormattedDisabled("{}", m_unknownDataCharacter);
else
this->drawCell(byteAddress, &bytes[x], 1, cellHovered, CellType::ASCII);
ImGui::PopItemWidth();
@@ -546,29 +546,29 @@ namespace hex::plugin::builtin::ui {
ImGui::TableNextColumn();
// Draw Custom encoding column
if (this->m_showCustomEncoding && this->m_currCustomEncoding.has_value()) {
if (this->m_encodingLineStartAddresses.empty()) {
this->m_encodingLineStartAddresses.push_back(0);
if (m_showCustomEncoding && m_currCustomEncoding.has_value()) {
if (m_encodingLineStartAddresses.empty()) {
m_encodingLineStartAddresses.push_back(0);
}
if (y < this->m_encodingLineStartAddresses.size()) {
if (y < m_encodingLineStartAddresses.size()) {
std::vector<std::pair<u64, CustomEncodingData>> encodingData;
if (this->m_encodingLineStartAddresses[y] >= this->m_bytesPerRow) {
encodingData.emplace_back(y * this->m_bytesPerRow + this->m_provider->getBaseAddress() + this->m_provider->getCurrentPageAddress(), CustomEncodingData(".", 1, ImGuiExt::GetCustomColorU32(ImGuiCustomCol_AdvancedEncodingUnknown)));
this->m_encodingLineStartAddresses.push_back(0);
if (m_encodingLineStartAddresses[y] >= m_bytesPerRow) {
encodingData.emplace_back(y * m_bytesPerRow + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress(), CustomEncodingData(".", 1, ImGuiExt::GetCustomColorU32(ImGuiCustomCol_AdvancedEncodingUnknown)));
m_encodingLineStartAddresses.push_back(0);
} else {
u32 offset = this->m_encodingLineStartAddresses[y];
u32 offset = m_encodingLineStartAddresses[y];
do {
const u64 address = y * this->m_bytesPerRow + offset + this->m_provider->getBaseAddress() + this->m_provider->getCurrentPageAddress();
const u64 address = y * m_bytesPerRow + offset + m_provider->getBaseAddress() + m_provider->getCurrentPageAddress();
auto result = queryCustomEncodingData(this->m_provider, *this->m_currCustomEncoding, address);
auto result = queryCustomEncodingData(m_provider, *m_currCustomEncoding, address);
offset += result.advance;
encodingData.emplace_back(address, result);
} while (offset < this->m_bytesPerRow);
} while (offset < m_bytesPerRow);
this->m_encodingLineStartAddresses.push_back(offset - this->m_bytesPerRow);
m_encodingLineStartAddresses.push_back(offset - m_bytesPerRow);
}
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(0, 0));
@@ -580,10 +580,10 @@ namespace hex::plugin::builtin::ui {
ImGui::TableNextColumn();
const auto cellStartPos = getCellPosition();
const auto cellSize = ImGui::CalcTextSize(data.displayValue.c_str()) * ImVec2(1, 0) + ImVec2(this->m_characterCellPadding * 1_scaled, CharacterSize.y);
const auto cellSize = ImGui::CalcTextSize(data.displayValue.c_str()) * ImVec2(1, 0) + ImVec2(m_characterCellPadding * 1_scaled, CharacterSize.y);
const bool cellHovered = ImGui::IsMouseHoveringRect(cellStartPos, cellStartPos + cellSize, true);
const auto x = address % this->m_bytesPerRow;
const auto x = address % m_bytesPerRow;
if (x < validBytes && isCurrRegionValid(address)) {
auto [foregroundColor, backgroundColor] = cellColors[x / bytesPerCell];
@@ -600,7 +600,7 @@ namespace hex::plugin::builtin::ui {
ImGui::SameLine(0, 0);
ImGui::Dummy({ 0, 0 });
this->handleSelection(address, data.advance, &bytes[address % this->m_bytesPerRow], cellHovered);
this->handleSelection(address, data.advance, &bytes[address % m_bytesPerRow], cellHovered);
}
}
@@ -612,35 +612,35 @@ namespace hex::plugin::builtin::ui {
}
// Scroll to the cursor if it's either at the top or bottom edge of the screen
if (this->m_shouldScrollToSelection && isSelectionValid()) {
if (m_shouldScrollToSelection && isSelectionValid()) {
// Make sure simply clicking on a byte at the edge of the screen won't cause scrolling
if ((ImGui::IsMouseDragging(ImGuiMouseButton_Left) && *this->m_selectionStart != *this->m_selectionEnd)) {
auto fractionPerLine = 1.0 / (this->m_visibleRowCount + 1);
if ((ImGui::IsMouseDragging(ImGuiMouseButton_Left) && *m_selectionStart != *m_selectionEnd)) {
auto fractionPerLine = 1.0 / (m_visibleRowCount + 1);
if (y == (u64(clipper.DisplayStart) + 3)) {
if (i128(this->m_selectionEnd.value() - this->m_provider->getBaseAddress() - this->m_provider->getCurrentPageAddress()) <= (i64(clipper.DisplayStart + 3) * this->m_bytesPerRow)) {
this->m_shouldScrollToSelection = false;
if (i128(m_selectionEnd.value() - m_provider->getBaseAddress() - m_provider->getCurrentPageAddress()) <= (i64(clipper.DisplayStart + 3) * m_bytesPerRow)) {
m_shouldScrollToSelection = false;
ImGui::SetScrollHereY(fractionPerLine * 5);
}
} else if (y == (u64(clipper.DisplayEnd) - 1)) {
if (i128(this->m_selectionEnd.value() - this->m_provider->getBaseAddress() - this->m_provider->getCurrentPageAddress()) >= (i64(clipper.DisplayEnd - 2) * this->m_bytesPerRow)) {
this->m_shouldScrollToSelection = false;
ImGui::SetScrollHereY(fractionPerLine * (this->m_visibleRowCount));
if (i128(m_selectionEnd.value() - m_provider->getBaseAddress() - m_provider->getCurrentPageAddress()) >= (i64(clipper.DisplayEnd - 2) * m_bytesPerRow)) {
m_shouldScrollToSelection = false;
ImGui::SetScrollHereY(fractionPerLine * (m_visibleRowCount));
}
}
}
// If the cursor is off-screen, directly jump to the byte
if (this->m_shouldJumpWhenOffScreen) {
this->m_shouldJumpWhenOffScreen = false;
if (m_shouldJumpWhenOffScreen) {
m_shouldJumpWhenOffScreen = false;
const auto pageAddress = this->m_provider->getCurrentPageAddress() + this->m_provider->getBaseAddress();
const auto pageAddress = m_provider->getCurrentPageAddress() + m_provider->getBaseAddress();
auto newSelection = getSelection();
newSelection.address -= pageAddress;
if ((newSelection.getStartAddress()) < u64(clipper.DisplayStart * this->m_bytesPerRow))
if ((newSelection.getStartAddress()) < u64(clipper.DisplayStart * m_bytesPerRow))
this->jumpToSelection(false);
if ((newSelection.getEndAddress()) > u64(clipper.DisplayEnd * this->m_bytesPerRow))
if ((newSelection.getEndAddress()) > u64(clipper.DisplayEnd * m_bytesPerRow))
this->jumpToSelection(false);
}
}
@@ -648,31 +648,31 @@ namespace hex::plugin::builtin::ui {
}
// Handle jumping to selection
if (this->m_shouldJumpToSelection) {
this->m_shouldJumpToSelection = false;
if (m_shouldJumpToSelection) {
m_shouldJumpToSelection = false;
auto newSelection = getSelection();
this->m_provider->setCurrentPage(this->m_provider->getPageOfAddress(newSelection.address).value_or(0));
m_provider->setCurrentPage(m_provider->getPageOfAddress(newSelection.address).value_or(0));
const auto pageAddress = this->m_provider->getCurrentPageAddress() + this->m_provider->getBaseAddress();
auto scrollPos = (static_cast<long double>(newSelection.getStartAddress() - pageAddress) / this->m_bytesPerRow) * CharacterSize.y;
const auto pageAddress = m_provider->getCurrentPageAddress() + m_provider->getBaseAddress();
auto scrollPos = (static_cast<long double>(newSelection.getStartAddress() - pageAddress) / m_bytesPerRow) * CharacterSize.y;
bool scrollUpwards = scrollPos < ImGui::GetScrollY();
auto scrollFraction = scrollUpwards ? 0.0F : (1.0F - ((1.0F / this->m_visibleRowCount) * 2));
auto scrollFraction = scrollUpwards ? 0.0F : (1.0F - ((1.0F / m_visibleRowCount) * 2));
if (this->m_centerOnJump) {
if (m_centerOnJump) {
scrollFraction = 0.5F;
this->m_centerOnJump = false;
m_centerOnJump = false;
}
ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scrollPos, scrollFraction);
}
if (!this->m_syncScrolling) {
if (this->m_shouldUpdateScrollPosition) {
this->m_shouldUpdateScrollPosition = false;
ImGui::SetScrollY(this->m_scrollPosition);
if (!m_syncScrolling) {
if (m_shouldUpdateScrollPosition) {
m_shouldUpdateScrollPosition = false;
ImGui::SetScrollY(m_scrollPosition);
} else {
this->m_scrollPosition = ImGui::GetScrollY();
m_scrollPosition = ImGui::GetScrollY();
}
}
}
@@ -681,12 +681,12 @@ namespace hex::plugin::builtin::ui {
}
ImGui::PopStyleVar();
this->m_shouldScrollToSelection = false;
m_shouldScrollToSelection = false;
}
void HexEditor::drawFooter(const ImVec2 &size) {
if (this->m_provider != nullptr && this->m_provider->isReadable()) {
const auto pageCount = std::max<u32>(1, this->m_provider->getPageCount());
if (m_provider != nullptr && m_provider->isReadable()) {
const auto pageCount = std::max<u32>(1, m_provider->getPageCount());
constexpr static u32 MinPage = 1;
const auto windowEndPos = ImGui::GetWindowPos() + size - ImGui::GetStyle().WindowPadding;
@@ -702,7 +702,7 @@ namespace hex::plugin::builtin::ui {
// Page slider
ImGui::TableNextColumn();
{
u32 page = this->m_provider->getCurrentPage() + 1;
u32 page = m_provider->getCurrentPage() + 1;
ImGuiExt::TextFormatted("{}: ", "hex.builtin.hex_editor.page"_lang);
ImGui::SameLine();
@@ -711,7 +711,7 @@ namespace hex::plugin::builtin::ui {
{
ImGui::PushItemWidth(-1);
if (ImGui::SliderScalar("##page_selection", ImGuiDataType_U32, &page, &MinPage, &pageCount, hex::format("0x%02llX / 0x{:02X}", pageCount).c_str()))
this->m_provider->setCurrentPage(page - 1);
m_provider->setCurrentPage(page - 1);
ImGui::PopItemWidth();
}
ImGui::EndDisabled();
@@ -720,15 +720,15 @@ namespace hex::plugin::builtin::ui {
// Collapse button
ImGui::TableNextColumn();
{
if (ImGuiExt::DimmedIconButton(this->m_footerCollapsed ? ICON_VS_FOLD_UP : ICON_VS_FOLD_DOWN, ImGui::GetStyleColorVec4(ImGuiCol_Text)))
this->m_footerCollapsed = !this->m_footerCollapsed;
if (ImGuiExt::DimmedIconButton(m_footerCollapsed ? ICON_VS_FOLD_UP : ICON_VS_FOLD_DOWN, ImGui::GetStyleColorVec4(ImGuiCol_Text)))
m_footerCollapsed = !m_footerCollapsed;
}
// Page Address
ImGui::TableNextColumn();
{
const auto pageAddress = this->m_provider->getCurrentPageAddress();
const auto pageSize = this->m_provider->getSize();
const auto pageAddress = m_provider->getCurrentPageAddress();
const auto pageSize = m_provider->getSize();
ImGuiExt::TextFormatted("{}:", "hex.builtin.hex_editor.region"_lang);
ImGui::SameLine();
ImGuiExt::TextFormattedSelectable("0x{0:08X} - 0x{1:08X} ({0} - {1})",
@@ -737,7 +737,7 @@ namespace hex::plugin::builtin::ui {
);
}
if (!this->m_footerCollapsed) {
if (!m_footerCollapsed) {
ImGui::TableNextRow();
// Selection
@@ -750,7 +750,7 @@ namespace hex::plugin::builtin::ui {
selection.getStartAddress(),
selection.getEndAddress(),
selection.getSize(),
this->m_showHumanReadableUnits
m_showHumanReadableUnits
? hex::toByteString(selection.getSize())
: hex::format("{}", selection.getSize())
);
@@ -771,11 +771,11 @@ namespace hex::plugin::builtin::ui {
ImGuiExt::TextFormatted("{}:", "hex.builtin.hex_editor.data_size"_lang);
ImGui::SameLine();
ImGuiExt::TextFormattedSelectable("0x{0:08X} (0x{1:X} | {2})",
this->m_provider->getBaseAddress(),
this->m_provider->getBaseAddress() + this->m_provider->getActualSize(),
this->m_showHumanReadableUnits
? hex::toByteString(this->m_provider->getActualSize())
: hex::format("{}", this->m_provider->getActualSize())
m_provider->getBaseAddress(),
m_provider->getBaseAddress() + m_provider->getActualSize(),
m_showHumanReadableUnits
? hex::toByteString(m_provider->getActualSize())
: hex::format("{}", m_provider->getActualSize())
);
}
@@ -785,26 +785,26 @@ namespace hex::plugin::builtin::ui {
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 2_scaled);
// Upper/lower case hex
ImGuiExt::DimmedIconToggle(ICON_VS_CASE_SENSITIVE, &this->m_upperCaseHex);
ImGuiExt::DimmedIconToggle(ICON_VS_CASE_SENSITIVE, &m_upperCaseHex);
ImGuiExt::InfoTooltip("hex.builtin.hex_editor.uppercase_hex"_lang);
ImGui::SameLine();
// Grayed out zeros
ImGuiExt::DimmedIconToggle(ICON_VS_LIGHTBULB, &this->m_grayOutZero);
ImGuiExt::DimmedIconToggle(ICON_VS_LIGHTBULB, &m_grayOutZero);
ImGuiExt::InfoTooltip("hex.builtin.hex_editor.gray_out_zero"_lang);
ImGui::SameLine();
// ASCII view
ImGuiExt::DimmedIconToggle(ICON_VS_SYMBOL_KEY, &this->m_showAscii);
ImGuiExt::DimmedIconToggle(ICON_VS_SYMBOL_KEY, &m_showAscii);
ImGuiExt::InfoTooltip("hex.builtin.hex_editor.ascii_view"_lang);
ImGui::SameLine(0, 1_scaled);
// Custom encoding view
ImGui::BeginDisabled(!this->m_currCustomEncoding.has_value());
ImGuiExt::DimmedIconToggle(ICON_VS_WHITESPACE, &this->m_showCustomEncoding);
ImGui::BeginDisabled(!m_currCustomEncoding.has_value());
ImGuiExt::DimmedIconToggle(ICON_VS_WHITESPACE, &m_showCustomEncoding);
ImGui::EndDisabled();
ImGuiExt::InfoTooltip("hex.builtin.hex_editor.custom_encoding_view"_lang);
@@ -812,7 +812,7 @@ namespace hex::plugin::builtin::ui {
ImGui::SameLine();
// Human-readable units
ImGuiExt::DimmedIconToggle(ICON_VS_SYMBOL_NUMERIC, &this->m_showHumanReadableUnits);
ImGuiExt::DimmedIconToggle(ICON_VS_SYMBOL_NUMERIC, &m_showHumanReadableUnits);
ImGuiExt::InfoTooltip("hex.builtin.hex_editor.human_readable_units_footer"_lang);
}
@@ -828,33 +828,33 @@ namespace hex::plugin::builtin::ui {
ImGui::SameLine(0, 0);
{
bool hasEndianess = this->m_currDataVisualizer->getBytesPerCell() > 1;
bool hasEndianess = m_currDataVisualizer->getBytesPerCell() > 1;
if (!hasEndianess)
this->m_dataVisualizerEndianness = std::endian::native;
m_dataVisualizerEndianness = std::endian::native;
ImGui::BeginDisabled(!hasEndianess);
{
int sliderPos = this->m_dataVisualizerEndianness == std::endian::little ? 0 : 1;
int sliderPos = m_dataVisualizerEndianness == std::endian::little ? 0 : 1;
ImGui::PushItemWidth(60_scaled);
ImGui::SliderInt("##visualizer_endianness", &sliderPos, 0, 1, sliderPos == 0 ? "hex.builtin.common.little"_lang : "hex.builtin.common.big"_lang);
ImGui::PopItemWidth();
this->m_dataVisualizerEndianness = sliderPos == 0 ? std::endian::little : std::endian::big;
m_dataVisualizerEndianness = sliderPos == 0 ? std::endian::little : std::endian::big;
}
ImGui::EndDisabled();
}
ImGui::SameLine(0, 2_scaled);
ImGui::PushItemWidth((ImGui::GetContentRegionAvail().x / 3) * 2);
if (ImGui::BeginCombo("##visualizer", Lang(this->m_currDataVisualizer->getUnlocalizedName()))) {
if (ImGui::BeginCombo("##visualizer", Lang(m_currDataVisualizer->getUnlocalizedName()))) {
for (const auto &visualizer : visualizers) {
if (ImGui::Selectable(Lang(visualizer->getUnlocalizedName()))) {
this->m_currDataVisualizer = visualizer;
this->m_encodingLineStartAddresses.clear();
m_currDataVisualizer = visualizer;
m_encodingLineStartAddresses.clear();
if (this->m_bytesPerRow < visualizer->getBytesPerCell())
this->m_bytesPerRow = visualizer->getBytesPerCell();
if (m_bytesPerRow < visualizer->getBytesPerCell())
m_bytesPerRow = visualizer->getBytesPerCell();
}
}
@@ -864,12 +864,12 @@ namespace hex::plugin::builtin::ui {
ImGui::SameLine(0, 2_scaled);
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
int bytesPerRow = this->m_bytesPerRow / this->getBytesPerCell();
int bytesPerRow = m_bytesPerRow / this->getBytesPerCell();
if (ImGui::SliderInt("##row_size", &bytesPerRow, 1, 32 / this->getBytesPerCell(), hex::format("{}", bytesPerRow * this->getBytesPerCell()).c_str())) {
this->m_bytesPerRow = bytesPerRow * this->getBytesPerCell();
this->m_encodingLineStartAddresses.clear();
m_bytesPerRow = bytesPerRow * this->getBytesPerCell();
m_encodingLineStartAddresses.clear();
ContentRegistry::Settings::write("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.bytes_per_row", this->m_bytesPerRow);
ContentRegistry::Settings::write("hex.builtin.setting.hex_editor", "hex.builtin.setting.hex_editor.bytes_per_row", m_bytesPerRow);
}
ImGui::PopItemWidth();
}
@@ -887,7 +887,7 @@ namespace hex::plugin::builtin::ui {
drawTooltip(address, data, bytesPerCell);
auto endAddress = address + bytesPerCell - 1;
auto &selectionStart = this->m_selectionStart;
auto &selectionStart = m_selectionStart;
if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) {
this->setSelection(selectionStart.value_or(address), endAddress);
@@ -908,7 +908,7 @@ namespace hex::plugin::builtin::ui {
const auto width = ImGui::GetContentRegionAvail().x;
auto footerSize = ImVec2(width, 0);
if (!this->m_footerCollapsed)
if (!m_footerCollapsed)
footerSize.y = ImGui::GetTextLineHeightWithSpacing() * 3.6F;
else
footerSize.y = ImGui::GetTextLineHeightWithSpacing() * 1.4F;
@@ -922,7 +922,7 @@ namespace hex::plugin::builtin::ui {
if (tableSize.y > 0)
this->drawFooter(footerSize);
this->m_selectionChanged = false;
m_selectionChanged = false;
}
}

View File

@@ -204,12 +204,12 @@ namespace hex::plugin::builtin::ui {
}
bool PatternDrawer::isEditingPattern(const pl::ptrn::Pattern& pattern) const {
return this->m_editingPattern == &pattern && this->m_editingPatternOffset == pattern.getOffset();
return m_editingPattern == &pattern && m_editingPatternOffset == pattern.getOffset();
}
void PatternDrawer::resetEditing() {
this->m_editingPattern = nullptr;
this->m_editingPatternOffset = 0x00;
m_editingPattern = nullptr;
m_editingPatternOffset = 0x00;
}
bool PatternDrawer::matchesFilter(const std::vector<std::string> &filterPath, const std::vector<std::string> &patternPath, bool fullMatch) const {
@@ -232,24 +232,24 @@ namespace hex::plugin::builtin::ui {
}
void PatternDrawer::drawFavoriteColumn(const pl::ptrn::Pattern& pattern) {
if (this->m_rowColoring)
if (m_rowColoring)
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, (pattern.getColor() & 0x00'FF'FF'FF) | 0x30'00'00'00);
if (!this->m_showFavoriteStars) {
if (!m_showFavoriteStars) {
ImGui::TableNextColumn();
return;
}
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
if (this->m_favorites.contains(this->m_currPatternPath)) {
if (m_favorites.contains(m_currPatternPath)) {
if (ImGuiExt::DimmedIconButton(ICON_VS_STAR_DELETE, ImGui::GetStyleColorVec4(ImGuiCol_PlotHistogram))) {
this->m_favorites.erase(this->m_currPatternPath);
m_favorites.erase(m_currPatternPath);
}
}
else {
if (ImGuiExt::DimmedIconButton(ICON_VS_STAR_ADD, ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled))) {
this->m_favorites.insert({ this->m_currPatternPath, pattern.clone() });
m_favorites.insert({ m_currPatternPath, pattern.clone() });
}
}
@@ -271,7 +271,7 @@ namespace hex::plugin::builtin::ui {
try {
visualizer.callback(pattern, iterable, reset, { arguments.begin() + 1, arguments.end() });
} catch (std::exception &e) {
this->m_lastVisualizerError = e.what();
m_lastVisualizerError = e.what();
}
} else {
ImGui::TextUnformatted("hex.builtin.pattern_drawer.visualizer.invalid_parameter_count"_lang);
@@ -280,8 +280,8 @@ namespace hex::plugin::builtin::ui {
ImGui::TextUnformatted("hex.builtin.pattern_drawer.visualizer.unknown"_lang);
}
if (!this->m_lastVisualizerError.empty())
ImGui::TextUnformatted(this->m_lastVisualizerError.c_str());
if (!m_lastVisualizerError.empty())
ImGui::TextUnformatted(m_lastVisualizerError.c_str());
}
void PatternDrawer::drawValueColumn(pl::ptrn::Pattern& pattern) {
@@ -300,12 +300,12 @@ namespace hex::plugin::builtin::ui {
bool shouldReset = false;
if (ImGui::Button(hex::format(" {} {}", ICON_VS_EYE_WATCH, value).c_str(), ImVec2(width, ImGui::GetTextLineHeight()))) {
auto previousPattern = this->m_currVisualizedPattern;
auto previousPattern = m_currVisualizedPattern;
this->m_currVisualizedPattern = &pattern;
this->m_lastVisualizerError.clear();
m_currVisualizedPattern = &pattern;
m_lastVisualizerError.clear();
if (this->m_currVisualizedPattern != previousPattern)
if (m_currVisualizedPattern != previousPattern)
shouldReset = true;
ImGui::OpenPopup("Visualizer");
@@ -315,9 +315,9 @@ namespace hex::plugin::builtin::ui {
ImGui::SameLine();
if (ImGui::BeginPopup("Visualizer")) {
if (this->m_currVisualizedPattern == &pattern) {
drawVisualizer(ContentRegistry::PatternLanguage::impl::getVisualizers(), visualizeArgs, pattern, dynamic_cast<pl::ptrn::IIterable&>(pattern), !this->m_visualizedPatterns.contains(&pattern) || shouldReset);
this->m_visualizedPatterns.insert(&pattern);
if (m_currVisualizedPattern == &pattern) {
drawVisualizer(ContentRegistry::PatternLanguage::impl::getVisualizers(), visualizeArgs, pattern, dynamic_cast<pl::ptrn::IIterable&>(pattern), !m_visualizedPatterns.contains(&pattern) || shouldReset);
m_visualizedPatterns.insert(&pattern);
}
ImGui::EndPopup();
@@ -334,7 +334,7 @@ namespace hex::plugin::builtin::ui {
}
std::string PatternDrawer::getDisplayName(const pl::ptrn::Pattern& pattern) const {
if (this->m_showSpecName && pattern.hasAttribute("hex::spec_name"))
if (m_showSpecName && pattern.hasAttribute("hex::spec_name"))
return pattern.getAttributeArguments("hex::spec_name")[0].toString(true);
else
return pattern.getDisplayName();
@@ -351,7 +351,7 @@ namespace hex::plugin::builtin::ui {
}
return highlightWhenSelected(pattern, [&]{
switch (this->m_treeStyle) {
switch (m_treeStyle) {
using enum TreeStyle;
default:
case Default:
@@ -369,16 +369,16 @@ namespace hex::plugin::builtin::ui {
ImGui::PushID(pattern.getVariableName().c_str());
if (ImGui::Selectable("##PatternLine", false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowOverlap)) {
this->m_selectionCallback(Region { pattern.getOffset(), pattern.getSize() });
m_selectionCallback(Region { pattern.getOffset(), pattern.getSize() });
if (this->m_editingPattern != &pattern) {
if (m_editingPattern != &pattern) {
this->resetEditing();
}
}
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
this->m_editingPattern = &pattern;
this->m_editingPatternOffset = pattern.getOffset();
m_editingPattern = &pattern;
m_editingPatternOffset = pattern.getOffset();
AchievementManager::unlockAchievement("hex.builtin.achievement.patterns", "hex.builtin.achievement.patterns.modify_data.name");
}
@@ -404,7 +404,7 @@ namespace hex::plugin::builtin::ui {
}
void PatternDrawer::closeTreeNode(bool inlined) const {
if (!inlined && this->m_treeStyle != TreeStyle::Flattened)
if (!inlined && m_treeStyle != TreeStyle::Flattened)
ImGui::TreePop();
}
@@ -478,7 +478,7 @@ namespace hex::plugin::builtin::ui {
void PatternDrawer::visit(pl::ptrn::PatternBitfield& pattern) {
bool open = true;
if (!pattern.isInlined() && this->m_treeStyle != TreeStyle::Flattened) {
if (!pattern.isInlined() && m_treeStyle != TreeStyle::Flattened) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
open = createTreeNode(pattern);
@@ -634,7 +634,7 @@ namespace hex::plugin::builtin::ui {
void PatternDrawer::visit(pl::ptrn::PatternPointer& pattern) {
bool open = true;
if (!pattern.isInlined() && this->m_treeStyle != TreeStyle::Flattened) {
if (!pattern.isInlined() && m_treeStyle != TreeStyle::Flattened) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
open = createTreeNode(pattern);
@@ -708,7 +708,7 @@ namespace hex::plugin::builtin::ui {
void PatternDrawer::visit(pl::ptrn::PatternStruct& pattern) {
bool open = true;
if (!pattern.isInlined() && this->m_treeStyle != TreeStyle::Flattened) {
if (!pattern.isInlined() && m_treeStyle != TreeStyle::Flattened) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
open = createTreeNode(pattern);
@@ -758,7 +758,7 @@ namespace hex::plugin::builtin::ui {
void PatternDrawer::visit(pl::ptrn::PatternUnion& pattern) {
bool open = true;
if (!pattern.isInlined() && this->m_treeStyle != TreeStyle::Flattened) {
if (!pattern.isInlined() && m_treeStyle != TreeStyle::Flattened) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
open = createTreeNode(pattern);
@@ -844,18 +844,18 @@ namespace hex::plugin::builtin::ui {
if (pattern.getVisibility() == pl::ptrn::Visibility::Hidden)
return;
this->m_currPatternPath.push_back(pattern.getVariableName());
ON_SCOPE_EXIT { this->m_currPatternPath.pop_back(); };
m_currPatternPath.push_back(pattern.getVariableName());
ON_SCOPE_EXIT { m_currPatternPath.pop_back(); };
if (matchesFilter(this->m_filter.path, this->m_currPatternPath, false)) {
if (this->m_filter.value.has_value()) {
if (matchesFilter(m_filter.path, m_currPatternPath, false)) {
if (m_filter.value.has_value()) {
auto patternValue = pattern.getValue();
if (patternValue == this->m_filter.value)
if (patternValue == m_filter.value)
pattern.accept(*this);
else if (!matchesFilter(this->m_filter.path, this->m_currPatternPath, true))
else if (!matchesFilter(m_filter.path, m_currPatternPath, true))
pattern.accept(*this);
else if (patternValue.isPattern() && this->m_filter.value->isString()) {
if (patternValue.toString(true) == this->m_filter.value->toString(false))
else if (patternValue.isPattern() && m_filter.value->isString()) {
if (patternValue.toString(true) == m_filter.value->toString(false))
pattern.accept(*this);
}
} else {
@@ -869,7 +869,7 @@ namespace hex::plugin::builtin::ui {
return;
bool open = true;
if (!isInlined && this->m_treeStyle != TreeStyle::Flattened) {
if (!isInlined && m_treeStyle != TreeStyle::Flattened) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
open = createTreeNode(pattern);
@@ -933,7 +933,7 @@ namespace hex::plugin::builtin::ui {
ImGui::TableNextColumn();
chunkOpen = highlightWhenSelected(startOffset, ((endOffset + endSize) - startOffset) - 1, [&]{
return ImGui::TreeNodeEx(hex::format("{0}[{1} ... {2}]", this->m_treeStyle == TreeStyle::Flattened ? this->getDisplayName(pattern).c_str() : "", i, endIndex - 1).c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
return ImGui::TreeNodeEx(hex::format("{0}[{1} ... {2}]", m_treeStyle == TreeStyle::Flattened ? this->getDisplayName(pattern).c_str() : "", i, endIndex - 1).c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
});
ImGui::TableNextColumn();
@@ -976,12 +976,12 @@ namespace hex::plugin::builtin::ui {
}
u64& PatternDrawer::getDisplayEnd(const pl::ptrn::Pattern& pattern) {
auto it = this->m_displayEnd.find(&pattern);
if (it != this->m_displayEnd.end()) {
auto it = m_displayEnd.find(&pattern);
if (it != m_displayEnd.end()) {
return it->second;
}
auto [value, success] = this->m_displayEnd.emplace(&pattern, DisplayEndDefault);
auto [value, success] = m_displayEnd.emplace(&pattern, DisplayEndDefault);
return value->second;
}
@@ -1089,13 +1089,13 @@ namespace hex::plugin::builtin::ui {
const auto treeStyleButton = [this](auto icon, TreeStyle style, const char *tooltip) {
bool pushed = false;
if (this->m_treeStyle == style) {
if (m_treeStyle == style) {
ImGui::PushStyleColor(ImGuiCol_Border, ImGui::GetStyleColorVec4(ImGuiCol_ButtonActive));
pushed = true;
}
if (ImGuiExt::DimmedIconButton(icon, ImGui::GetStyleColorVec4(ImGuiCol_Text)))
this->m_treeStyle = style;
m_treeStyle = style;
if (pushed)
ImGui::PopStyleColor();
@@ -1108,14 +1108,14 @@ namespace hex::plugin::builtin::ui {
}
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x - ImGui::GetTextLineHeightWithSpacing() * 9.5);
if (ImGuiExt::InputTextIcon("##Search", ICON_VS_FILTER, this->m_filterText)) {
this->m_filter = parseRValueFilter(this->m_filterText).value_or(Filter{ });
if (ImGuiExt::InputTextIcon("##Search", ICON_VS_FILTER, m_filterText)) {
m_filter = parseRValueFilter(m_filterText).value_or(Filter{ });
}
ImGui::PopItemWidth();
ImGui::SameLine();
ImGuiExt::DimmedIconToggle(ICON_VS_BOOK, &this->m_showSpecName);
ImGuiExt::DimmedIconToggle(ICON_VS_BOOK, &m_showSpecName);
ImGuiExt::InfoTooltip("hex.builtin.pattern_drawer.spec_name"_lang);
ImGui::SameLine();
@@ -1140,7 +1140,7 @@ namespace hex::plugin::builtin::ui {
ImGui::SetNextWindowPos(ImGui::GetWindowPos() + ImVec2(startPos.x, ImGui::GetCursorPosY()));
if (ImGui::BeginPopup("ExportPatterns")) {
for (const auto &formatter : this->m_formatters) {
for (const auto &formatter : m_formatters) {
const auto name = [&]{
auto name = formatter->getName();
std::transform(name.begin(), name.end(), name.begin(), [](char c){ return char(std::toupper(c)); });
@@ -1162,37 +1162,37 @@ namespace hex::plugin::builtin::ui {
ImGui::EndPopup();
}
if (!this->m_favoritesUpdated) {
this->m_favoritesUpdated = true;
if (!m_favoritesUpdated) {
m_favoritesUpdated = true;
if (!patterns.empty() && !this->m_favoritesUpdateTask.isRunning()) {
this->m_favoritesUpdateTask = TaskManager::createTask("hex.builtin.pattern_drawer.updating"_lang, TaskManager::NoProgress, [this, patterns](auto &task) {
if (!patterns.empty() && !m_favoritesUpdateTask.isRunning()) {
m_favoritesUpdateTask = TaskManager::createTask("hex.builtin.pattern_drawer.updating"_lang, TaskManager::NoProgress, [this, patterns](auto &task) {
size_t updatedFavorites = 0;
for (auto &pattern : patterns) {
std::vector<std::string> patternPath;
traversePatternTree(*pattern, patternPath, [&, this](const pl::ptrn::Pattern &pattern) {
if (pattern.hasAttribute("hex::favorite"))
this->m_favorites.insert({ patternPath, pattern.clone() });
m_favorites.insert({ patternPath, pattern.clone() });
if (const auto &args = pattern.getAttributeArguments("hex::group"); !args.empty()) {
auto groupName = args.front().toString();
if (!this->m_groups.contains(groupName))
this->m_groups.insert({groupName, std::vector<std::unique_ptr<pl::ptrn::Pattern>>()});
if (!m_groups.contains(groupName))
m_groups.insert({groupName, std::vector<std::unique_ptr<pl::ptrn::Pattern>>()});
this->m_groups[groupName].push_back(pattern.clone());
m_groups[groupName].push_back(pattern.clone());
}
});
if (updatedFavorites == this->m_favorites.size())
if (updatedFavorites == m_favorites.size())
task.interrupt();
task.update();
patternPath.clear();
traversePatternTree(*pattern, patternPath, [&, this](const pl::ptrn::Pattern &pattern) {
for (auto &[path, favoritePattern] : this->m_favorites) {
if (updatedFavorites == this->m_favorites.size())
for (auto &[path, favoritePattern] : m_favorites) {
if (updatedFavorites == m_favorites.size())
task.interrupt();
task.update();
@@ -1206,7 +1206,7 @@ namespace hex::plugin::builtin::ui {
});
}
std::erase_if(this->m_favorites, [](const auto &entry) {
std::erase_if(m_favorites, [](const auto &entry) {
const auto &[path, favoritePattern] = entry;
return favoritePattern == nullptr;
@@ -1216,20 +1216,20 @@ namespace hex::plugin::builtin::ui {
}
if (beginPatternTable(patterns, this->m_sortedPatterns, height)) {
if (beginPatternTable(patterns, m_sortedPatterns, height)) {
ImGui::TableHeadersRow();
this->m_showFavoriteStars = false;
if (!this->m_favoritesUpdateTask.isRunning()) {
m_showFavoriteStars = false;
if (!m_favoritesUpdateTask.isRunning()) {
int id = 1;
bool doTableNextRow = false;
if (!this->m_favorites.empty() && !patterns.empty()) {
if (!m_favorites.empty() && !patterns.empty()) {
ImGui::TableNextColumn();
ImGui::TableNextColumn();
ImGui::PushID(id);
if (ImGui::TreeNodeEx("hex.builtin.pattern_drawer.favorites"_lang, ImGuiTreeNodeFlags_SpanFullWidth)) {
for (auto &[path, pattern] : this->m_favorites) {
for (auto &[path, pattern] : m_favorites) {
if (pattern == nullptr)
continue;
@@ -1246,8 +1246,8 @@ namespace hex::plugin::builtin::ui {
doTableNextRow = true;
}
if (!this->m_groups.empty() && !patterns.empty()) {
for (auto &[groupName, groupPatterns]: this->m_groups) {
if (!m_groups.empty() && !patterns.empty()) {
for (auto &[groupName, groupPatterns]: m_groups) {
if (doTableNextRow) {
ImGui::TableNextRow();
}
@@ -1276,9 +1276,9 @@ namespace hex::plugin::builtin::ui {
}
}
this->m_showFavoriteStars = true;
m_showFavoriteStars = true;
for (auto &pattern : this->m_sortedPatterns) {
for (auto &pattern : m_sortedPatterns) {
ImGui::PushID(id);
this->draw(*pattern);
ImGui::PopID();
@@ -1290,7 +1290,7 @@ namespace hex::plugin::builtin::ui {
ImGui::EndTable();
}
if (this->m_favoritesUpdateTask.isRunning()) {
if (m_favoritesUpdateTask.isRunning()) {
ImGuiExt::TextOverlay("hex.builtin.pattern_drawer.updating"_lang, ImGui::GetWindowPos() + ImGui::GetWindowSize() / 2);
}
}
@@ -1299,23 +1299,23 @@ namespace hex::plugin::builtin::ui {
std::scoped_lock lock(s_resetDrawMutex);
this->resetEditing();
this->m_displayEnd.clear();
this->m_visualizedPatterns.clear();
this->m_currVisualizedPattern = nullptr;
this->m_sortedPatterns.clear();
this->m_lastVisualizerError.clear();
this->m_currPatternPath.clear();
m_displayEnd.clear();
m_visualizedPatterns.clear();
m_currVisualizedPattern = nullptr;
m_sortedPatterns.clear();
m_lastVisualizerError.clear();
m_currPatternPath.clear();
this->m_favoritesUpdateTask.interrupt();
m_favoritesUpdateTask.interrupt();
for (auto &[path, pattern] : this->m_favorites)
for (auto &[path, pattern] : m_favorites)
pattern = nullptr;
for (auto &[groupName, patterns]: this->m_groups)
for (auto &[groupName, patterns]: m_groups)
for (auto &pattern: patterns)
pattern = nullptr;
this->m_groups.clear();
m_groups.clear();
this->m_favoritesUpdated = false;
m_favoritesUpdated = false;
}
}

View File

@@ -20,16 +20,16 @@ namespace hex::script::loader {
virtual bool loadAll() = 0;
void addScript(std::string name, std::function<void()> entryPoint) {
this->m_scripts.emplace_back(std::move(name), std::move(entryPoint));
m_scripts.emplace_back(std::move(name), std::move(entryPoint));
}
const auto& getScripts() const {
return this->m_scripts;
return m_scripts;
}
protected:
void clearScripts() {
this->m_scripts.clear();
m_scripts.clear();
}
private:

View File

@@ -166,7 +166,7 @@ namespace hex::script::loader {
component_entry_point_fn entryPoint = nullptr;
u32 result = loadAssembly(
this->m_assemblyLoaderPathString.c_str(),
m_assemblyLoaderPathString.c_str(),
dotnetType,
dotnetTypeMethod,
nullptr,
@@ -179,7 +179,7 @@ namespace hex::script::loader {
continue;
}
this->m_loadAssembly = [entryPoint](const std::fs::path &path) -> bool {
m_loadAssembly = [entryPoint](const std::fs::path &path) -> bool {
auto string = wolv::util::toUTF8String(path);
auto result = entryPoint(string.data(), string.size());
@@ -212,7 +212,7 @@ namespace hex::script::loader {
continue;
this->addScript(entry.path().stem().string(), [this, scriptPath] {
hex::unused(this->m_loadAssembly(scriptPath));
hex::unused(m_loadAssembly(scriptPath));
});
}
}

View File

@@ -22,7 +22,7 @@ public:
m_message(std::move(message)) { }
void drawContent() override {
ImGuiExt::TextFormattedWrapped("{}", this->m_message.c_str());
ImGuiExt::TextFormattedWrapped("{}", m_message.c_str());
ImGui::NewLine();
ImGui::Separator();
@@ -65,23 +65,23 @@ public:
m_message(std::move(message)), m_maxSize(maxSize) { }
void drawContent() override {
ImGuiExt::TextFormattedWrapped("{}", this->m_message.c_str());
ImGuiExt::TextFormattedWrapped("{}", m_message.c_str());
ImGui::NewLine();
ImGui::SetItemDefaultFocus();
ImGui::SetNextItemWidth(-1);
bool submitted = ImGui::InputText("##input", this->m_input, ImGuiInputTextFlags_EnterReturnsTrue);
if (this->m_input.size() > this->m_maxSize)
this->m_input.resize(this->m_maxSize);
bool submitted = ImGui::InputText("##input", m_input, ImGuiInputTextFlags_EnterReturnsTrue);
if (m_input.size() > m_maxSize)
m_input.resize(m_maxSize);
ImGui::NewLine();
ImGui::Separator();
auto width = ImGui::GetWindowWidth();
ImGui::SetCursorPosX(width / 9);
ImGui::BeginDisabled(this->m_input.empty());
ImGui::BeginDisabled(m_input.empty());
if (ImGui::Button("hex.builtin.common.okay"_lang, ImVec2(width / 3, 0)) || submitted) {
s_inputTextBoxResult = this->m_input;
s_inputTextBoxResult = m_input;
this->close();
}
ImGui::EndDisabled();

View File

@@ -12,35 +12,35 @@
namespace hex::plugin::windows {
ViewTTYConsole::ViewTTYConsole() : View::Window("hex.windows.view.tty_console.name") {
this->m_comPorts = getAvailablePorts();
this->m_transmitDataBuffer.resize(0xFFF, 0x00);
this->m_receiveDataBuffer.reserve(0xFFF);
this->m_receiveDataBuffer.push_back(0x00);
m_comPorts = getAvailablePorts();
m_transmitDataBuffer.resize(0xFFF, 0x00);
m_receiveDataBuffer.reserve(0xFFF);
m_receiveDataBuffer.push_back(0x00);
}
void ViewTTYConsole::drawContent() {
ImGuiExt::Header("hex.windows.view.tty_console.config"_lang, true);
bool connected = this->m_portHandle != INVALID_HANDLE_VALUE;
bool connected = m_portHandle != INVALID_HANDLE_VALUE;
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, connected);
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, connected ? 0.5F : 1.0F);
ImGui::Combo(
"hex.windows.view.tty_console.port"_lang, &this->m_selectedPort, [](void *data, int idx) {
"hex.windows.view.tty_console.port"_lang, &m_selectedPort, [](void *data, int idx) {
auto &ports = *static_cast<std::vector<std::pair<std::string, std::string>> *>(data);
return ports[idx].first.c_str();
},
&this->m_comPorts,
this->m_comPorts.size());
&m_comPorts,
m_comPorts.size());
ImGui::SameLine();
if (ImGui::Button("hex.windows.view.tty_console.reload"_lang))
this->m_comPorts = getAvailablePorts();
m_comPorts = getAvailablePorts();
ImGui::Combo(
"hex.windows.view.tty_console.baud"_lang, &this->m_selectedBaudRate, [](void *data, int idx) {
"hex.windows.view.tty_console.baud"_lang, &m_selectedBaudRate, [](void *data, int idx) {
hex::unused(data);
return ViewTTYConsole::BaudRates[idx];
@@ -49,7 +49,7 @@ namespace hex::plugin::windows {
ViewTTYConsole::BaudRates.size());
ImGui::Combo(
"hex.windows.view.tty_console.num_bits"_lang, &this->m_selectedNumBits, [](void *data, int idx) {
"hex.windows.view.tty_console.num_bits"_lang, &m_selectedNumBits, [](void *data, int idx) {
hex::unused(data);
return ViewTTYConsole::NumBits[idx];
@@ -58,7 +58,7 @@ namespace hex::plugin::windows {
ViewTTYConsole::NumBits.size());
ImGui::Combo(
"hex.windows.view.tty_console.stop_bits"_lang, &this->m_selectedStopBits, [](void *data, int idx) {
"hex.windows.view.tty_console.stop_bits"_lang, &m_selectedStopBits, [](void *data, int idx) {
hex::unused(data);
return ViewTTYConsole::StopBits[idx];
@@ -67,7 +67,7 @@ namespace hex::plugin::windows {
ViewTTYConsole::StopBits.size());
ImGui::Combo(
"hex.windows.view.tty_console.parity_bits"_lang, &this->m_selectedParityBits, [](void *data, int idx) {
"hex.windows.view.tty_console.parity_bits"_lang, &m_selectedParityBits, [](void *data, int idx) {
hex::unused(data);
return ViewTTYConsole::ParityBits[idx];
@@ -75,14 +75,14 @@ namespace hex::plugin::windows {
nullptr,
ViewTTYConsole::ParityBits.size());
ImGui::Checkbox("hex.windows.view.tty_console.cts"_lang, &this->m_hasCTSFlowControl);
ImGui::Checkbox("hex.windows.view.tty_console.cts"_lang, &m_hasCTSFlowControl);
ImGui::PopStyleVar();
ImGui::PopItemFlag();
ImGui::NewLine();
if (this->m_portHandle == INVALID_HANDLE_VALUE) {
if (m_portHandle == INVALID_HANDLE_VALUE) {
if (ImGui::Button("hex.windows.view.tty_console.connect"_lang))
if (!this->connect())
RequestOpenErrorPopup::post("hex.windows.view.tty_console.connect_error"_lang);
@@ -94,15 +94,15 @@ namespace hex::plugin::windows {
ImGui::NewLine();
if (ImGui::Button("hex.windows.view.tty_console.clear"_lang)) {
std::scoped_lock lock(this->m_receiveBufferMutex);
std::scoped_lock lock(m_receiveBufferMutex);
this->m_receiveDataBuffer.clear();
this->m_wrapPositions.clear();
m_receiveDataBuffer.clear();
m_wrapPositions.clear();
}
ImGui::SameLine();
ImGui::Checkbox("hex.windows.view.tty_console.auto_scroll"_lang, &this->m_shouldAutoScroll);
ImGui::Checkbox("hex.windows.view.tty_console.auto_scroll"_lang, &m_shouldAutoScroll);
ImGuiExt::Header("hex.windows.view.tty_console.console"_lang);
@@ -110,21 +110,21 @@ namespace hex::plugin::windows {
consoleSize.y -= ImGui::GetTextLineHeight() + ImGui::GetStyle().FramePadding.y * 4;
if (ImGui::BeginChild("##scrolling", consoleSize, true, ImGuiWindowFlags_HorizontalScrollbar)) {
ImGuiListClipper clipper;
clipper.Begin(this->m_wrapPositions.size(), ImGui::GetTextLineHeight());
clipper.Begin(m_wrapPositions.size(), ImGui::GetTextLineHeight());
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 1));
while (clipper.Step()) {
std::scoped_lock lock(this->m_receiveBufferMutex);
std::scoped_lock lock(m_receiveBufferMutex);
for (int i = clipper.DisplayStart + 1; i < clipper.DisplayEnd; i++) {
ImGui::TextUnformatted(this->m_receiveDataBuffer.data() + this->m_wrapPositions[i - 1], this->m_receiveDataBuffer.data() + this->m_wrapPositions[i]);
ImGui::TextUnformatted(m_receiveDataBuffer.data() + m_wrapPositions[i - 1], m_receiveDataBuffer.data() + m_wrapPositions[i]);
}
if (!this->m_receiveDataBuffer.empty() && !this->m_wrapPositions.empty())
if (static_cast<size_t>(clipper.DisplayEnd) >= this->m_wrapPositions.size() - 1)
ImGui::TextUnformatted(this->m_receiveDataBuffer.data() + this->m_wrapPositions.back());
if (!m_receiveDataBuffer.empty() && !m_wrapPositions.empty())
if (static_cast<size_t>(clipper.DisplayEnd) >= m_wrapPositions.size() - 1)
ImGui::TextUnformatted(m_receiveDataBuffer.data() + m_wrapPositions.back());
if (this->m_shouldAutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
if (m_shouldAutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
ImGui::SetScrollHereY(0.0F);
}
}
@@ -133,18 +133,18 @@ namespace hex::plugin::windows {
ImGui::EndChild();
ImGui::PushItemWidth(-1);
if (ImGui::InputText("##transmit", this->m_transmitDataBuffer.data(), this->m_transmitDataBuffer.size() - 2, ImGuiInputTextFlags_EnterReturnsTrue)) {
auto size = strlen(this->m_transmitDataBuffer.data());
if (ImGui::InputText("##transmit", m_transmitDataBuffer.data(), m_transmitDataBuffer.size() - 2, ImGuiInputTextFlags_EnterReturnsTrue)) {
auto size = strlen(m_transmitDataBuffer.data());
this->m_transmitDataBuffer[size + 0] = '\n';
this->m_transmitDataBuffer[size + 1] = 0x00;
m_transmitDataBuffer[size + 0] = '\n';
m_transmitDataBuffer[size + 1] = 0x00;
this->transmitData(this->m_transmitDataBuffer);
this->transmitData(m_transmitDataBuffer);
ImGui::SetKeyboardFocusHere(0);
}
ImGui::PopItemWidth();
if (ImGui::IsMouseReleased(ImGuiMouseButton_Right) && ImGui::IsItemHovered() && this->m_portHandle != INVALID_HANDLE_VALUE && !this->m_transmitting)
if (ImGui::IsMouseReleased(ImGuiMouseButton_Right) && ImGui::IsItemHovered() && m_portHandle != INVALID_HANDLE_VALUE && !m_transmitting)
ImGui::OpenPopup("ConsoleMenu");
if (ImGui::BeginPopup("ConsoleMenu")) {
@@ -183,11 +183,11 @@ namespace hex::plugin::windows {
}
bool ViewTTYConsole::connect() {
if (this->m_comPorts.empty() || static_cast<size_t>(this->m_selectedPort) >= this->m_comPorts.size()) {
if (m_comPorts.empty() || static_cast<size_t>(m_selectedPort) >= m_comPorts.size()) {
RequestOpenErrorPopup::post("hex.windows.view.tty_console.no_available_port"_lang);
return true; // If false, connect_error error popup will override this error popup
}
this->m_portHandle = ::CreateFile((R"(\\.\)" + this->m_comPorts[this->m_selectedPort].first).c_str(),
m_portHandle = ::CreateFile((R"(\\.\)" + m_comPorts[m_selectedPort].first).c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
nullptr,
@@ -195,27 +195,27 @@ namespace hex::plugin::windows {
FILE_FLAG_OVERLAPPED,
nullptr);
if (this->m_portHandle == INVALID_HANDLE_VALUE)
if (m_portHandle == INVALID_HANDLE_VALUE)
return false;
auto closeHandle = SCOPE_GUARD { CloseHandle(this->m_portHandle); };
auto closeHandle = SCOPE_GUARD { CloseHandle(m_portHandle); };
if (!::SetupComm(this->m_portHandle, 10000, 10000))
if (!::SetupComm(m_portHandle, 10000, 10000))
return false;
DCB serialParams;
serialParams.DCBlength = sizeof(DCB);
if (!::GetCommState(this->m_portHandle, &serialParams))
if (!::GetCommState(m_portHandle, &serialParams))
return false;
serialParams.BaudRate = std::stoi(ViewTTYConsole::BaudRates[this->m_selectedBaudRate]);
serialParams.ByteSize = std::stoi(ViewTTYConsole::NumBits[this->m_selectedNumBits]);
serialParams.StopBits = this->m_selectedStopBits;
serialParams.Parity = this->m_selectedParityBits;
serialParams.fOutxCtsFlow = this->m_hasCTSFlowControl;
serialParams.BaudRate = std::stoi(ViewTTYConsole::BaudRates[m_selectedBaudRate]);
serialParams.ByteSize = std::stoi(ViewTTYConsole::NumBits[m_selectedNumBits]);
serialParams.StopBits = m_selectedStopBits;
serialParams.Parity = m_selectedParityBits;
serialParams.fOutxCtsFlow = m_hasCTSFlowControl;
if (!::SetCommState(this->m_portHandle, &serialParams))
if (!::SetCommState(m_portHandle, &serialParams))
return false;
COMMTIMEOUTS timeouts;
@@ -225,12 +225,12 @@ namespace hex::plugin::windows {
timeouts.WriteTotalTimeoutConstant = 500;
timeouts.WriteTotalTimeoutMultiplier = 100;
if (!::SetCommTimeouts(this->m_portHandle, &timeouts))
if (!::SetCommTimeouts(m_portHandle, &timeouts))
return false;
closeHandle.release();
this->m_receiveThread = std::jthread([this](const std::stop_token &token) {
m_receiveThread = std::jthread([this](const std::stop_token &token) {
bool waitingOnRead = false;
OVERLAPPED overlapped = { };
@@ -238,19 +238,19 @@ namespace hex::plugin::windows {
ON_SCOPE_EXIT { ::CloseHandle(&overlapped); };
auto addByte = [this](char byte) {
std::scoped_lock lock(this->m_receiveBufferMutex);
std::scoped_lock lock(m_receiveBufferMutex);
if (byte >= 0x20 && byte <= 0x7E) {
this->m_receiveDataBuffer.back() = byte;
this->m_receiveDataBuffer.push_back(0x00);
m_receiveDataBuffer.back() = byte;
m_receiveDataBuffer.push_back(0x00);
} else if (byte == '\n' || byte == '\r') {
if (this->m_receiveDataBuffer.empty())
if (m_receiveDataBuffer.empty())
return;
u32 wrapPos = this->m_receiveDataBuffer.size() - 1;
u32 wrapPos = m_receiveDataBuffer.size() - 1;
if (this->m_wrapPositions.empty() || this->m_wrapPositions.back() != wrapPos)
this->m_wrapPositions.push_back(wrapPos);
if (m_wrapPositions.empty() || m_wrapPositions.back() != wrapPos)
m_wrapPositions.push_back(wrapPos);
}
};
@@ -259,7 +259,7 @@ namespace hex::plugin::windows {
char byte = 0;
if (!waitingOnRead) {
if (::ReadFile(this->m_portHandle, &byte, sizeof(char), &bytesRead, &overlapped)) {
if (::ReadFile(m_portHandle, &byte, sizeof(char), &bytesRead, &overlapped)) {
addByte(byte);
} else if (::GetLastError() == ERROR_IO_PENDING) {
waitingOnRead = true;
@@ -268,7 +268,7 @@ namespace hex::plugin::windows {
byte = 0;
switch (::WaitForSingleObject(overlapped.hEvent, 500)) {
case WAIT_OBJECT_0:
if (::GetOverlappedResult(this->m_portHandle, &overlapped, &bytesRead, false)) {
if (::GetOverlappedResult(m_portHandle, &overlapped, &bytesRead, false)) {
addByte(byte);
waitingOnRead = false;
}
@@ -283,18 +283,18 @@ namespace hex::plugin::windows {
}
bool ViewTTYConsole::disconnect() {
::SetCommMask(this->m_portHandle, EV_TXEMPTY);
this->m_receiveThread.request_stop();
this->m_receiveThread.join();
::SetCommMask(m_portHandle, EV_TXEMPTY);
m_receiveThread.request_stop();
m_receiveThread.join();
::CloseHandle(this->m_portHandle);
this->m_portHandle = INVALID_HANDLE_VALUE;
::CloseHandle(m_portHandle);
m_portHandle = INVALID_HANDLE_VALUE;
return true;
}
void ViewTTYConsole::transmitData(std::vector<char> &data) {
if (this->m_transmitting)
if (m_transmitting)
return;
TaskManager::createBackgroundTask("Transmitting data", [&, this](auto&) {
@@ -303,19 +303,19 @@ namespace hex::plugin::windows {
overlapped.hEvent = ::CreateEvent(nullptr, true, false, nullptr);
ON_SCOPE_EXIT { ::CloseHandle(&overlapped); };
this->m_transmitting = true;
m_transmitting = true;
DWORD bytesWritten = 0;
if (!::WriteFile(this->m_portHandle, data.data(), strlen(data.data()), &bytesWritten, &overlapped)) {
if (!::WriteFile(m_portHandle, data.data(), strlen(data.data()), &bytesWritten, &overlapped)) {
if (::GetLastError() == ERROR_IO_PENDING) {
::GetOverlappedResult(this->m_portHandle, &overlapped, &bytesWritten, true);
::GetOverlappedResult(m_portHandle, &overlapped, &bytesWritten, true);
}
}
if (bytesWritten > 0)
data[0] = 0x00;
this->m_transmitting = false;
m_transmitting = false;
});
}