From bff9b8b4b1b3bcb4fa46d85fe22d1994d9a69692 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Tue, 11 Feb 2025 23:05:56 +0100 Subject: [PATCH] feat: Fixed string/char names in data inspector, added utf16 and utf32 string and char types --- plugins/builtin/romfs/lang/de_DE.json | 4 +- plugins/builtin/romfs/lang/en_US.json | 8 +- plugins/builtin/romfs/lang/es_ES.json | 4 +- plugins/builtin/romfs/lang/hu_HU.json | 4 +- plugins/builtin/romfs/lang/it_IT.json | 4 +- plugins/builtin/romfs/lang/ja_JP.json | 4 +- plugins/builtin/romfs/lang/ko_KR.json | 4 +- plugins/builtin/romfs/lang/pt_BR.json | 4 +- plugins/builtin/romfs/lang/ru_RU.json | 4 +- plugins/builtin/romfs/lang/zh_CN.json | 4 +- plugins/builtin/romfs/lang/zh_TW.json | 4 +- .../builtin/source/content/data_inspector.cpp | 157 ++++++++++++++++-- 12 files changed, 172 insertions(+), 33 deletions(-) diff --git a/plugins/builtin/romfs/lang/de_DE.json b/plugins/builtin/romfs/lang/de_DE.json index ee6307cd2..a0b92049b 100644 --- a/plugins/builtin/romfs/lang/de_DE.json +++ b/plugins/builtin/romfs/lang/de_DE.json @@ -94,7 +94,7 @@ "hex.builtin.inspector.rgba8": "RGBA8 Farbe", "hex.builtin.inspector.sleb128": "Signed LEB128", "hex.builtin.inspector.string": "String", - "hex.builtin.inspector.string16": "Wide String", + "hex.builtin.inspector.wstring": "Wide String", "hex.builtin.inspector.time": "time_t", "hex.builtin.inspector.time32": "time32_t", "hex.builtin.inspector.time64": "time64_t", @@ -106,7 +106,7 @@ "hex.builtin.inspector.u8": "uint8_t", "hex.builtin.inspector.uleb128": "Unsigned LEB128", "hex.builtin.inspector.utf8": "UTF-8 code point", - "hex.builtin.inspector.wide": "Wide Character", + "hex.builtin.inspector.wide": "wchar_t", "hex.builtin.layouts.default": "Standard", "hex.builtin.layouts.none.restore_default": "Standard-Layout wiederherstellen", "hex.builtin.menu.edit": "Bearbeiten", diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index 820e9a0dc..94346fd12 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -97,7 +97,9 @@ "hex.builtin.inspector.rgba8": "RGBA8 Color", "hex.builtin.inspector.sleb128": "Signed LEB128", "hex.builtin.inspector.string": "String", - "hex.builtin.inspector.string16": "Wide String", + "hex.builtin.inspector.wstring": "Wide String", + "hex.builtin.inspector.string16": "String16", + "hex.builtin.inspector.string32": "String32", "hex.builtin.inspector.time": "time_t", "hex.builtin.inspector.time32": "time32_t", "hex.builtin.inspector.time64": "time64_t", @@ -109,7 +111,9 @@ "hex.builtin.inspector.u8": "uint8_t", "hex.builtin.inspector.uleb128": "Unsigned LEB128", "hex.builtin.inspector.utf8": "UTF-8 code point", - "hex.builtin.inspector.wide": "Wide Character", + "hex.builtin.inspector.wide": "wchar_t", + "hex.builtin.inspector.char16": "char16_t", + "hex.builtin.inspector.char32": "char32_t", "hex.builtin.layouts.default": "Default", "hex.builtin.layouts.none.restore_default": "Restore default layout", "hex.builtin.menu.edit": "Edit", diff --git a/plugins/builtin/romfs/lang/es_ES.json b/plugins/builtin/romfs/lang/es_ES.json index c65ab003e..ec4377f6f 100644 --- a/plugins/builtin/romfs/lang/es_ES.json +++ b/plugins/builtin/romfs/lang/es_ES.json @@ -94,7 +94,7 @@ "hex.builtin.inspector.rgba8": "Color RGBA8", "hex.builtin.inspector.sleb128": "LEB128 con Signo", "hex.builtin.inspector.string": "Cadena ", - "hex.builtin.inspector.string16": "Cadena (wide)", + "hex.builtin.inspector.wstring": "Cadena (wide)", "hex.builtin.inspector.time": "time_t", "hex.builtin.inspector.time32": "time32_t", "hex.builtin.inspector.time64": "time64_t", @@ -106,7 +106,7 @@ "hex.builtin.inspector.u8": "", "hex.builtin.inspector.uleb128": "LEB128 sin Signo", "hex.builtin.inspector.utf8": "Código UTF-8", - "hex.builtin.inspector.wide": "Carácter (wide)", + "hex.builtin.inspector.wide": "wchar_t", "hex.builtin.layouts.default": "Por defecto", "hex.builtin.layouts.none.restore_default": "", "hex.builtin.menu.edit": "Editar", diff --git a/plugins/builtin/romfs/lang/hu_HU.json b/plugins/builtin/romfs/lang/hu_HU.json index 6f3e7dcc3..dd2848768 100644 --- a/plugins/builtin/romfs/lang/hu_HU.json +++ b/plugins/builtin/romfs/lang/hu_HU.json @@ -94,7 +94,7 @@ "hex.builtin.inspector.rgba8": "RGBA8 Szín", "hex.builtin.inspector.sleb128": "Előjeles LEB128", "hex.builtin.inspector.string": "String", - "hex.builtin.inspector.string16": "Széles string", + "hex.builtin.inspector.wstring": "Széles string", "hex.builtin.inspector.time": "time_t", "hex.builtin.inspector.time32": "time32_t", "hex.builtin.inspector.time64": "time64_t", @@ -106,7 +106,7 @@ "hex.builtin.inspector.u8": "uint8_t", "hex.builtin.inspector.uleb128": "Előjeletlen LEB128", "hex.builtin.inspector.utf8": "UTF-8 kód pont", - "hex.builtin.inspector.wide": "Széles karakter", + "hex.builtin.inspector.wide": "wchar_t", "hex.builtin.layouts.default": "Alapértelmezett", "hex.builtin.layouts.none.restore_default": "Alapértelmezett elrendezés visszaállítása", "hex.builtin.menu.edit": "Szerkesztés", diff --git a/plugins/builtin/romfs/lang/it_IT.json b/plugins/builtin/romfs/lang/it_IT.json index 7af3101f1..eddf84c16 100644 --- a/plugins/builtin/romfs/lang/it_IT.json +++ b/plugins/builtin/romfs/lang/it_IT.json @@ -94,7 +94,7 @@ "hex.builtin.inspector.rgba8": "Colori RGBA8", "hex.builtin.inspector.sleb128": "", "hex.builtin.inspector.string": "String", - "hex.builtin.inspector.string16": "Wide String", + "hex.builtin.inspector.wstring": "Wide String", "hex.builtin.inspector.time": "time_t", "hex.builtin.inspector.time32": "time32_t", "hex.builtin.inspector.time64": "time64_t", @@ -106,7 +106,7 @@ "hex.builtin.inspector.u8": "uint8_t", "hex.builtin.inspector.uleb128": "", "hex.builtin.inspector.utf8": "UTF-8 code point", - "hex.builtin.inspector.wide": "Wide Character", + "hex.builtin.inspector.wide": "wchar_t", "hex.builtin.layouts.default": "Default", "hex.builtin.layouts.none.restore_default": "", "hex.builtin.menu.edit": "Modifica", diff --git a/plugins/builtin/romfs/lang/ja_JP.json b/plugins/builtin/romfs/lang/ja_JP.json index 8aedbd8ad..4654c780e 100644 --- a/plugins/builtin/romfs/lang/ja_JP.json +++ b/plugins/builtin/romfs/lang/ja_JP.json @@ -94,7 +94,7 @@ "hex.builtin.inspector.rgba8": "RGBA8 Color", "hex.builtin.inspector.sleb128": "", "hex.builtin.inspector.string": "String", - "hex.builtin.inspector.string16": "Wide String", + "hex.builtin.inspector.wstring": "Wide String", "hex.builtin.inspector.time": "time_t", "hex.builtin.inspector.time32": "time32_t", "hex.builtin.inspector.time64": "time64_t", @@ -106,7 +106,7 @@ "hex.builtin.inspector.u8": "uint8_t", "hex.builtin.inspector.uleb128": "", "hex.builtin.inspector.utf8": "UTF-8 code point", - "hex.builtin.inspector.wide": "Wide Character", + "hex.builtin.inspector.wide": "wchar_t", "hex.builtin.layouts.default": "標準", "hex.builtin.layouts.none.restore_default": "", "hex.builtin.menu.edit": "編集", diff --git a/plugins/builtin/romfs/lang/ko_KR.json b/plugins/builtin/romfs/lang/ko_KR.json index 3aee5f4f7..05e8621d3 100644 --- a/plugins/builtin/romfs/lang/ko_KR.json +++ b/plugins/builtin/romfs/lang/ko_KR.json @@ -94,7 +94,7 @@ "hex.builtin.inspector.rgba8": "RGBA8 색상", "hex.builtin.inspector.sleb128": "부호 있는 LEB128", "hex.builtin.inspector.string": "문자열", - "hex.builtin.inspector.string16": "와이드 문자열", + "hex.builtin.inspector.wstring": "와이드 문자열", "hex.builtin.inspector.time": "time_t", "hex.builtin.inspector.time32": "time32_t", "hex.builtin.inspector.time64": "time64_t", @@ -106,7 +106,7 @@ "hex.builtin.inspector.u8": "uint8_t", "hex.builtin.inspector.uleb128": "부호 없는 LEB128", "hex.builtin.inspector.utf8": "UTF-8 코드 포인트", - "hex.builtin.inspector.wide": "와이드 문자", + "hex.builtin.inspector.wide": "wchar_t", "hex.builtin.layouts.default": "기본", "hex.builtin.layouts.none.restore_default": "기본 레이아웃 복원", "hex.builtin.menu.edit": "편집", diff --git a/plugins/builtin/romfs/lang/pt_BR.json b/plugins/builtin/romfs/lang/pt_BR.json index 2ec81e8be..d457c83ae 100644 --- a/plugins/builtin/romfs/lang/pt_BR.json +++ b/plugins/builtin/romfs/lang/pt_BR.json @@ -94,7 +94,7 @@ "hex.builtin.inspector.rgba8": "RGBA8 Color", "hex.builtin.inspector.sleb128": "", "hex.builtin.inspector.string": "String", - "hex.builtin.inspector.string16": "Wide String", + "hex.builtin.inspector.wstring": "Wide String", "hex.builtin.inspector.time": "time_t", "hex.builtin.inspector.time32": "time32_t", "hex.builtin.inspector.time64": "time64_t", @@ -106,7 +106,7 @@ "hex.builtin.inspector.u8": "uint8_t", "hex.builtin.inspector.uleb128": "", "hex.builtin.inspector.utf8": "UTF-8 code point", - "hex.builtin.inspector.wide": "Wide Character", + "hex.builtin.inspector.wide": "wchar_t", "hex.builtin.layouts.default": "Default", "hex.builtin.layouts.none.restore_default": "", "hex.builtin.menu.edit": "Editar", diff --git a/plugins/builtin/romfs/lang/ru_RU.json b/plugins/builtin/romfs/lang/ru_RU.json index 12a5b4751..a482e05e3 100644 --- a/plugins/builtin/romfs/lang/ru_RU.json +++ b/plugins/builtin/romfs/lang/ru_RU.json @@ -96,7 +96,7 @@ "hex.builtin.inspector.rgba8": "RGBA8 цвет", "hex.builtin.inspector.sleb128": "Знаковый LEB128", "hex.builtin.inspector.string": "Строка", - "hex.builtin.inspector.string16": "Wide строка", + "hex.builtin.inspector.wstring": "Wide строка", "hex.builtin.inspector.time": "time_t", "hex.builtin.inspector.time32": "time32_t", "hex.builtin.inspector.time64": "time64_t", @@ -108,7 +108,7 @@ "hex.builtin.inspector.u8": "uint8_t", "hex.builtin.inspector.uleb128": "Беззнаковый LEB128", "hex.builtin.inspector.utf8": "UTF-8 код", - "hex.builtin.inspector.wide": "Wide символ", + "hex.builtin.inspector.wide": "wchar_t", "hex.builtin.layouts.default": "По умолчанию", "hex.builtin.layouts.none.restore_default": "Восстановить макет по умолчанию", "hex.builtin.menu.edit": "Правка", diff --git a/plugins/builtin/romfs/lang/zh_CN.json b/plugins/builtin/romfs/lang/zh_CN.json index 7a8d7a7d5..1e45205df 100644 --- a/plugins/builtin/romfs/lang/zh_CN.json +++ b/plugins/builtin/romfs/lang/zh_CN.json @@ -123,7 +123,7 @@ "hex.builtin.inspector.rgba8": "RGBA8 颜色", "hex.builtin.inspector.sleb128": "有符号LEB128", "hex.builtin.inspector.string": "字符串", - "hex.builtin.inspector.string16": "宽字符串", + "hex.builtin.inspector.wstring": "宽字符串", "hex.builtin.inspector.time": "time_t", "hex.builtin.inspector.time32": "time32_t", "hex.builtin.inspector.time64": "time64_t", @@ -135,7 +135,7 @@ "hex.builtin.inspector.u8": "uint8_t", "hex.builtin.inspector.uleb128": "无符号LEB128", "hex.builtin.inspector.utf8": "UTF-8 码位", - "hex.builtin.inspector.wide": "宽字符", + "hex.builtin.inspector.wide": "wchar_t", "hex.builtin.layouts.default": "默认", "hex.builtin.layouts.none.restore_default": "恢复默认布局", "hex.builtin.menu.edit": "编辑", diff --git a/plugins/builtin/romfs/lang/zh_TW.json b/plugins/builtin/romfs/lang/zh_TW.json index 190a2e769..dc6ffd2c0 100644 --- a/plugins/builtin/romfs/lang/zh_TW.json +++ b/plugins/builtin/romfs/lang/zh_TW.json @@ -94,7 +94,7 @@ "hex.builtin.inspector.rgba8": "RGBA8 顏色", "hex.builtin.inspector.sleb128": "有號數 LEB128", "hex.builtin.inspector.string": "字串", - "hex.builtin.inspector.string16": "寬字串", + "hex.builtin.inspector.wstring": "寬字串", "hex.builtin.inspector.time": "time_t", "hex.builtin.inspector.time32": "time32_t", "hex.builtin.inspector.time64": "time64_t", @@ -106,7 +106,7 @@ "hex.builtin.inspector.u8": "uint8_t", "hex.builtin.inspector.uleb128": "無號數 LEB128", "hex.builtin.inspector.utf8": "UTF-8 code point", - "hex.builtin.inspector.wide": "框字元", + "hex.builtin.inspector.wide": "wchar_t", "hex.builtin.layouts.default": "預設", "hex.builtin.layouts.none.restore_default": "還原預設版面配置", "hex.builtin.menu.edit": "編輯", diff --git a/plugins/builtin/source/content/data_inspector.cpp b/plugins/builtin/source/content/data_inspector.cpp index 0f1e7951f..ed9c8cf67 100644 --- a/plugins/builtin/source/content/data_inspector.cpp +++ b/plugins/builtin/source/content/data_inspector.cpp @@ -363,16 +363,73 @@ namespace hex::plugin::builtin { auto c = hex::changeEndianness(wideChar, endian); - auto value = hex::format("{0}", c <= 255 ? makePrintable(c) : wolv::util::wstringToUtf8(std::wstring(&c, 1))); + auto value = hex::format("{0}", c <= 255 ? makePrintable(c) : wolv::util::wstringToUtf8(std::wstring(&c, 1)).value_or("???")); return [value] { ImGuiExt::TextFormatted("'{0}'", value.c_str()); return value; }; }, [](const std::string &value, std::endian endian) -> std::vector { std::vector bytes; - auto wideString = wolv::util::utf8ToWstring(value.c_str(), ""); - if (wideString.empty()) return bytes; + auto wideString = wolv::util::utf8ToWstring(value.c_str()); + if (!wideString.has_value()) + return bytes; - bytes.resize(wideString.size() * sizeof(wchar_t)); - std::memcpy(bytes.data(), wideString.data(), bytes.size()); + bytes.resize(wideString->size() * sizeof(wchar_t)); + std::memcpy(bytes.data(), wideString->data(), bytes.size()); + + if (endian != std::endian::native) + std::reverse(bytes.begin(), bytes.end()); + + return bytes; + } + ); + + ContentRegistry::DataInspector::add("hex.builtin.inspector.char16", sizeof(char16_t), + [](auto buffer, auto endian, auto style) { + std::ignore = style; + + char16_t wideChar = '\x00'; + std::memcpy(&wideChar, buffer.data(), std::min(sizeof(char16_t), buffer.size())); + + auto c = hex::changeEndianness(wideChar, endian); + + auto value = hex::format("{0}", c <= 255 ? makePrintable(c) : wolv::util::utf16ToUtf8(std::u16string(&c, 1)).value_or("???")); + return [value] { ImGuiExt::TextFormatted("'{0}'", value.c_str()); return value; }; + }, + [](const std::string &value, std::endian endian) -> std::vector { + std::vector bytes; + auto wideString = wolv::util::utf8ToUtf16(value); + if (!wideString.has_value()) + return bytes; + + bytes.resize(wideString->size() * sizeof(char16_t)); + std::memcpy(bytes.data(), wideString->data(), bytes.size()); + + if (endian != std::endian::native) + std::reverse(bytes.begin(), bytes.end()); + + return bytes; + } + ); + + ContentRegistry::DataInspector::add("hex.builtin.inspector.char32", sizeof(char32_t), + [](auto buffer, auto endian, auto style) { + std::ignore = style; + + char32_t wideChar = '\x00'; + std::memcpy(&wideChar, buffer.data(), std::min(sizeof(char32_t), buffer.size())); + + auto c = hex::changeEndianness(wideChar, endian); + + auto value = hex::format("{0}", c <= 255 ? makePrintable(c) : wolv::util::utf32ToUtf8(std::u32string(&c, 1)).value_or("???")); + return [value] { ImGuiExt::TextFormatted("'{0}'", value.c_str()); return value; }; + }, + [](const std::string &value, std::endian endian) -> std::vector { + std::vector bytes; + auto wideString = wolv::util::utf8ToUtf32(value); + if (!wideString.has_value()) + return bytes; + + bytes.resize(wideString->size() * sizeof(char32_t)); + std::memcpy(bytes.data(), wideString->data(), bytes.size()); if (endian != std::endian::native) std::reverse(bytes.begin(), bytes.end()); @@ -439,7 +496,7 @@ namespace hex::plugin::builtin { } ); - ContentRegistry::DataInspector::add("hex.builtin.inspector.string16", 2, + ContentRegistry::DataInspector::add("hex.builtin.inspector.wstring", sizeof(wchar_t), [](auto buffer, auto endian, auto style) { std::ignore = buffer; std::ignore = endian; @@ -450,17 +507,15 @@ namespace hex::plugin::builtin { std::string value, copyValue; if (currSelection.has_value()) { - std::u16string stringBuffer(std::min(currSelection->size, 0x1000), 0x00); + std::wstring stringBuffer(std::min(currSelection->size * sizeof(wchar_t), 0x1000), 0x00); ImHexApi::Provider::get()->read(currSelection->address, stringBuffer.data(), stringBuffer.size()); for (auto &c : stringBuffer) c = hex::changeEndianness(c, endian); - auto it = std::remove_if(buffer.begin(), buffer.end(), - [](auto c) { return c == 0x00; }); - buffer.erase(it, buffer.end()); + std::erase_if(buffer, [](auto c) { return c == 0x00; }); - auto string = wolv::util::utf16ToUtf8(stringBuffer, "Invalid"); + auto string = wolv::util::wstringToUtf8(stringBuffer).value_or("Invalid"); value = copyValue = hex::encodeByteString({ string.begin(), string.end() }); if (value.size() > MaxStringLength) { @@ -481,6 +536,86 @@ namespace hex::plugin::builtin { } ); + ContentRegistry::DataInspector::add("hex.builtin.inspector.string16", sizeof(char16_t), + [](auto buffer, auto endian, auto style) { + std::ignore = buffer; + std::ignore = endian; + std::ignore = style; + + auto currSelection = ImHexApi::HexEditor::getSelection(); + + std::string value, copyValue; + + if (currSelection.has_value()) { + std::u16string stringBuffer(std::min(currSelection->size * sizeof(char16_t), 0x1000), 0x00); + ImHexApi::Provider::get()->read(currSelection->address, stringBuffer.data(), stringBuffer.size()); + + for (auto &c : stringBuffer) + c = hex::changeEndianness(c, endian); + + std::erase_if(buffer, [](auto c) { return c == 0x00; }); + + auto string = wolv::util::utf16ToUtf8(stringBuffer).value_or("Invalid"); + value = copyValue = hex::encodeByteString({ string.begin(), string.end() }); + + if (value.size() > MaxStringLength) { + value.resize(MaxStringLength); + value += "..."; + } + } else { + value = ""; + copyValue = ""; + } + + return [value, copyValue] { ImGuiExt::TextFormatted("u\"{0}\"", value.c_str()); return copyValue; }; + }, + [](const std::string &value, std::endian endian) -> std::vector { + std::ignore = endian; + + return hex::decodeByteString(value); + } + ); + + ContentRegistry::DataInspector::add("hex.builtin.inspector.string32", sizeof(char32_t), + [](auto buffer, auto endian, auto style) { + std::ignore = buffer; + std::ignore = endian; + std::ignore = style; + + auto currSelection = ImHexApi::HexEditor::getSelection(); + + std::string value, copyValue; + + if (currSelection.has_value()) { + std::u32string stringBuffer(std::min(currSelection->size * sizeof(char32_t), 0x1000), 0x00); + ImHexApi::Provider::get()->read(currSelection->address, stringBuffer.data(), stringBuffer.size()); + + for (auto &c : stringBuffer) + c = hex::changeEndianness(c, endian); + + std::erase_if(buffer, [](auto c) { return c == 0x00; }); + + auto string = wolv::util::utf32ToUtf8(stringBuffer).value_or("Invalid"); + value = copyValue = hex::encodeByteString({ string.begin(), string.end() }); + + if (value.size() > MaxStringLength) { + value.resize(MaxStringLength); + value += "..."; + } + } else { + value = ""; + copyValue = ""; + } + + return [value, copyValue] { ImGuiExt::TextFormatted("U\"{0}\"", value.c_str()); return copyValue; }; + }, + [](const std::string &value, std::endian endian) -> std::vector { + std::ignore = endian; + + return hex::decodeByteString(value); + } + ); + #if defined(OS_WINDOWS) ContentRegistry::DataInspector::add("hex.builtin.inspector.time32", sizeof(u32), [](auto buffer, auto endian, auto style) {