2022-01-13 00:27:31 +01:00
|
|
|
#include <hex/api/content_registry.hpp>
|
|
|
|
|
|
|
|
#include <hex/providers/provider.hpp>
|
|
|
|
#include <hex/helpers/fmt.hpp>
|
|
|
|
|
|
|
|
namespace hex::plugin::builtin {
|
|
|
|
|
|
|
|
static std::string formatLanguageArray(prv::Provider *provider, u64 offset, size_t size, const std::string &start, const std::string &byteFormat, const std::string &end) {
|
|
|
|
constexpr auto NewLineIndent = "\n ";
|
|
|
|
|
|
|
|
std::string result = start;
|
|
|
|
|
|
|
|
std::vector<u8> buffer(0x1'0000, 0x00);
|
|
|
|
for (u64 i = 0; i < size; i += buffer.size()) {
|
|
|
|
size_t readSize = std::min<u64>(buffer.size(), size - i);
|
|
|
|
provider->read(offset, buffer.data(), readSize);
|
|
|
|
|
|
|
|
for (u32 j = 0; j < readSize; j++) {
|
|
|
|
if (j % 0x10 == 0)
|
|
|
|
result += NewLineIndent;
|
|
|
|
|
|
|
|
result += hex::format(byteFormat, buffer[j]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove trailing comma
|
2022-01-24 20:53:17 +01:00
|
|
|
result.pop_back();
|
|
|
|
result.pop_back();
|
2022-01-13 00:27:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
result += "\n";
|
|
|
|
result += end;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void registerDataFormatters() {
|
|
|
|
|
2022-02-06 21:02:31 +01:00
|
|
|
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.c", [](prv::Provider *provider, u64 offset, size_t size) {
|
2022-01-24 20:53:17 +01:00
|
|
|
return formatLanguageArray(provider, offset, size, hex::format("const uint8_t data[{0}] = {{", size), "0x{0:02X}, ", "};");
|
2022-01-13 00:27:31 +01:00
|
|
|
});
|
|
|
|
|
2022-02-06 21:02:31 +01:00
|
|
|
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.cpp", [](prv::Provider *provider, u64 offset, size_t size) {
|
2022-01-24 20:53:17 +01:00
|
|
|
return formatLanguageArray(provider, offset, size, hex::format("constexpr std::array<uint8_t, {0}> data = {{", size), "0x{0:02X}, ", "};");
|
2022-01-13 00:27:31 +01:00
|
|
|
});
|
|
|
|
|
2022-02-06 21:02:31 +01:00
|
|
|
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.java", [](prv::Provider *provider, u64 offset, size_t size) {
|
2022-01-24 20:53:17 +01:00
|
|
|
return formatLanguageArray(provider, offset, size, "final byte[] data = {", "0x{0:02X}, ", "};");
|
2022-01-13 00:27:31 +01:00
|
|
|
});
|
|
|
|
|
2022-02-06 21:02:31 +01:00
|
|
|
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.csharp", [](prv::Provider *provider, u64 offset, size_t size) {
|
2022-01-24 20:53:17 +01:00
|
|
|
return formatLanguageArray(provider, offset, size, "const byte[] data = {", "0x{0:02X}, ", "};");
|
2022-01-13 00:27:31 +01:00
|
|
|
});
|
|
|
|
|
2022-02-06 21:02:31 +01:00
|
|
|
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.rust", [](prv::Provider *provider, u64 offset, size_t size) {
|
2022-01-24 20:53:17 +01:00
|
|
|
return formatLanguageArray(provider, offset, size, hex::format("let data: [u8; 0x{0:02X}] = [", size), "0x{0:02X}, ", "];");
|
2022-01-13 00:27:31 +01:00
|
|
|
});
|
|
|
|
|
2022-02-06 21:02:31 +01:00
|
|
|
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.python", [](prv::Provider *provider, u64 offset, size_t size) {
|
2022-01-24 20:53:17 +01:00
|
|
|
return formatLanguageArray(provider, offset, size, "data = bytes([", "0x{0:02X}, ", "]);");
|
2022-01-13 00:27:31 +01:00
|
|
|
});
|
|
|
|
|
2022-02-06 21:02:31 +01:00
|
|
|
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.js", [](prv::Provider *provider, u64 offset, size_t size) {
|
2022-01-24 20:53:17 +01:00
|
|
|
return formatLanguageArray(provider, offset, size, "const data = new Uint8Array([", "0x{0:02X}, ", "]);");
|
2022-01-13 00:27:31 +01:00
|
|
|
});
|
|
|
|
|
2022-02-06 21:02:31 +01:00
|
|
|
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.ascii", [](prv::Provider *provider, u64 offset, size_t size) {
|
2022-01-13 00:27:31 +01:00
|
|
|
std::string result = "Hex View 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n\n";
|
|
|
|
|
|
|
|
std::vector<u8> buffer(0x1'0000, 0x00);
|
|
|
|
for (u64 byte = 0; byte < size; byte += buffer.size()) {
|
|
|
|
size_t readSize = std::min<u64>(buffer.size(), size - byte);
|
|
|
|
provider->read(offset, buffer.data(), readSize);
|
|
|
|
|
|
|
|
const auto end = (offset + readSize) - 1;
|
|
|
|
|
|
|
|
for (u32 col = offset >> 4; col <= (end >> 4); col++) {
|
|
|
|
result += hex::format("{0:08X} ", col << 4);
|
2022-01-24 20:53:17 +01:00
|
|
|
for (u64 i = 0; i < 16; i++) {
|
2022-01-13 00:27:31 +01:00
|
|
|
|
|
|
|
if (col == (offset >> 4) && i < (offset & 0xF) || col == (end >> 4) && i > (end & 0xF))
|
|
|
|
result += " ";
|
|
|
|
else
|
|
|
|
result += hex::format("{0:02X} ", buffer[((col << 4) - offset) + i]);
|
|
|
|
|
|
|
|
if ((i & 0xF) == 0x7)
|
|
|
|
result += " ";
|
|
|
|
}
|
|
|
|
|
|
|
|
result += " ";
|
|
|
|
|
2022-01-24 20:53:17 +01:00
|
|
|
for (u64 i = 0; i < 16; i++) {
|
2022-01-13 00:27:31 +01:00
|
|
|
|
|
|
|
if (col == (offset >> 4) && i < (offset & 0xF) || col == (end >> 4) && i > (end & 0xF))
|
|
|
|
result += " ";
|
|
|
|
else {
|
2022-02-01 22:09:44 +01:00
|
|
|
u8 c = buffer[((col << 4) - offset) + i];
|
2022-01-13 00:27:31 +01:00
|
|
|
char displayChar = (c < 32 || c >= 128) ? '.' : c;
|
|
|
|
result += hex::format("{0}", displayChar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result += "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
});
|
|
|
|
|
2022-02-06 21:02:31 +01:00
|
|
|
ContentRegistry::DataFormatter::add("hex.builtin.view.hex_editor.copy.html", [](prv::Provider *provider, u64 offset, size_t size) {
|
2022-01-13 00:27:31 +01:00
|
|
|
std::string result =
|
2022-01-24 20:53:17 +01:00
|
|
|
"<div>\n"
|
|
|
|
" <style type=\"text/css\">\n"
|
|
|
|
" .offsetheader { color:#0000A0; line-height:200% }\n"
|
|
|
|
" .offsetcolumn { color:#0000A0 }\n"
|
|
|
|
" .hexcolumn { color:#000000 }\n"
|
|
|
|
" .textcolumn { color:#000000 }\n"
|
|
|
|
" </style>\n\n"
|
|
|
|
" <code>\n"
|
|
|
|
" <span class=\"offsetheader\">Hex View  00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F</span><br>\n";
|
2022-01-13 00:27:31 +01:00
|
|
|
|
|
|
|
|
|
|
|
std::vector<u8> buffer(0x1'0000, 0x00);
|
|
|
|
for (u64 byte = 0; byte < size; byte += buffer.size()) {
|
|
|
|
size_t readSize = std::min<u64>(buffer.size(), size - byte);
|
|
|
|
provider->read(offset, buffer.data(), readSize);
|
|
|
|
|
|
|
|
const auto end = (offset + readSize) - 1;
|
|
|
|
|
|
|
|
for (u32 col = offset >> 4; col <= (end >> 4); col++) {
|
|
|
|
result += hex::format(" <span class=\"offsetcolumn\">{0:08X}</span>  <span class=\"hexcolumn\">", col << 4);
|
2022-01-24 20:53:17 +01:00
|
|
|
for (u64 i = 0; i < 16; i++) {
|
2022-01-13 00:27:31 +01:00
|
|
|
|
|
|
|
if (col == (offset >> 4) && i < (offset & 0xF) || col == (end >> 4) && i > (end & 0xF))
|
|
|
|
result += "   ";
|
|
|
|
else
|
|
|
|
result += hex::format("{0:02X} ", buffer[((col << 4) - offset) + i]);
|
|
|
|
|
|
|
|
if ((i & 0xF) == 0x7)
|
|
|
|
result += " ";
|
|
|
|
}
|
|
|
|
|
|
|
|
result += "</span>  <span class=\"textcolumn\">";
|
|
|
|
|
2022-01-24 20:53:17 +01:00
|
|
|
for (u64 i = 0; i < 16; i++) {
|
2022-01-13 00:27:31 +01:00
|
|
|
|
|
|
|
if (col == (offset >> 4) && i < (offset & 0xF) || col == (end >> 4) && i > (end & 0xF))
|
|
|
|
result += " ";
|
|
|
|
else {
|
2022-02-01 22:09:44 +01:00
|
|
|
u8 c = buffer[((col << 4) - offset) + i];
|
2022-01-13 00:27:31 +01:00
|
|
|
char displayChar = (c < 32 || c >= 128) ? '.' : c;
|
|
|
|
result += hex::format("{0}", displayChar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result += "</span><br>\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result +=
|
2022-01-24 20:53:17 +01:00
|
|
|
" </code>\n"
|
|
|
|
"</div>\n";
|
2022-01-13 00:27:31 +01:00
|
|
|
|
|
|
|
return result;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|