From 58f54caf55b9cbd67087a11612643dd8d458e6a9 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Fri, 5 Aug 2022 12:19:50 +0200 Subject: [PATCH] ui: Added u24, i24, u48 and i48 to data inspector Closes #651 --- lib/libimhex/include/hex/helpers/utils.hpp | 78 ++------- .../builtin/source/content/data_inspector.cpp | 165 +++++++++--------- plugins/builtin/source/lang/de_DE.cpp | 4 + plugins/builtin/source/lang/en_US.cpp | 4 + plugins/builtin/source/lang/it_IT.cpp | 4 + plugins/builtin/source/lang/ja_JP.cpp | 4 + plugins/builtin/source/lang/pt_BR.cpp | 4 + plugins/builtin/source/lang/zh_CN.cpp | 4 + plugins/builtin/source/lang/zh_TW.cpp | 4 + 9 files changed, 128 insertions(+), 143 deletions(-) diff --git a/lib/libimhex/include/hex/helpers/utils.hpp b/lib/libimhex/include/hex/helpers/utils.hpp index 98a12a7e0..025b5f766 100644 --- a/lib/libimhex/include/hex/helpers/utils.hpp +++ b/lib/libimhex/include/hex/helpers/utils.hpp @@ -107,86 +107,34 @@ namespace hex { using SizeType = typename SizeTypeImpl::Type; template - constexpr T changeEndianess(const T &value, std::endian endian) { + constexpr T changeEndianess(const T &value, size_t size, std::endian endian) { if (endian == std::endian::native) return value; - constexpr auto Size = sizeof(T); + size = std::min(size, sizeof(T)); - SizeType unswapped; - std::memcpy(&unswapped, &value, Size); + std::array data = { 0 }; + std::memcpy(&data[0], &value, size); - SizeType swapped; - - if constexpr (!std::has_single_bit(Size) || Size > 16) - static_assert(always_false::value, "Invalid type provided!"); - - switch (Size) { - case 1: - swapped = unswapped; - break; - case 2: - swapped = __builtin_bswap16(unswapped); - break; - case 4: - swapped = __builtin_bswap32(unswapped); - break; - case 8: - swapped = __builtin_bswap64(unswapped); - break; - case 16: - swapped = (u128(__builtin_bswap64(unswapped & 0xFFFF'FFFF'FFFF'FFFF)) << 64) | __builtin_bswap64(u128(unswapped) >> 64); - break; - default: - hex::unreachable(); + for (uint32_t i = 0; i < size / 2; i++) { + std::swap(data[i], data[size - 1 - i]); } - T result; - std::memcpy(&result, &swapped, Size); + T result = { }; + std::memcpy(&result, &data[0], size); return result; } + template + constexpr T changeEndianess(const T &value, std::endian endian) { + return changeEndianess(value, sizeof(value), endian); + } + [[nodiscard]] constexpr u128 bitmask(u8 bits) { return u128(-1) >> (128 - bits); } - template - constexpr T changeEndianess(T value, size_t size, std::endian endian) { - if (endian == std::endian::native) - return value; - - u128 unswapped = 0; - std::memcpy(&unswapped, &value, size); - - u128 swapped; - - switch (size) { - case 1: - swapped = unswapped; - break; - case 2: - swapped = __builtin_bswap16(unswapped); - break; - case 4: - swapped = __builtin_bswap32(unswapped); - break; - case 8: - swapped = __builtin_bswap64(unswapped); - break; - case 16: - swapped = (u128(__builtin_bswap64(unswapped & 0xFFFF'FFFF'FFFF'FFFF)) << 64) | __builtin_bswap64(u128(unswapped) >> 64); - break; - default: - hex::unreachable(); - } - - T result = 0; - std::memcpy(&result, &swapped, size); - - return result; - } - template constexpr T bit_width(T x) noexcept { return std::numeric_limits::digits - std::countl_zero(x); diff --git a/plugins/builtin/source/content/data_inspector.cpp b/plugins/builtin/source/content/data_inspector.cpp index 63da05112..6642e9392 100644 --- a/plugins/builtin/source/content/data_inspector.cpp +++ b/plugins/builtin/source/content/data_inspector.cpp @@ -18,6 +18,8 @@ namespace hex::plugin::builtin { + using Style = ContentRegistry::DataInspector::NumberDisplayStyle; + struct GUID { u32 data1; u16 data2; @@ -25,12 +27,12 @@ namespace hex::plugin::builtin { u8 data4[8]; }; - template + template static std::vector stringToUnsigned(const std::string &value, std::endian endian) requires(sizeof(T) <= sizeof(u64)) { u64 result = std::strtoull(value.c_str(), nullptr, 0); if (result > std::numeric_limits::max()) return {}; - std::vector bytes(sizeof(T), 0x00); + std::vector bytes(Size, 0x00); std::memcpy(bytes.data(), &result, bytes.size()); if (endian != std::endian::native) @@ -39,12 +41,12 @@ namespace hex::plugin::builtin { return bytes; } - template + template static std::vector stringToSigned(const std::string &value, std::endian endian) requires(sizeof(T) <= sizeof(u64)) { i64 result = std::strtoll(value.c_str(), nullptr, 0); if (result > std::numeric_limits::max() || result < std::numeric_limits::min()) return {}; - std::vector bytes(sizeof(T), 0x00); + std::vector bytes(Size, 0x00); std::memcpy(bytes.data(), &result, bytes.size()); if (endian != std::endian::native) @@ -66,21 +68,64 @@ namespace hex::plugin::builtin { return bytes; } - template + template static std::vector stringToInteger(const std::string &value, std::endian endian) requires(sizeof(T) <= sizeof(u64)) { - if constexpr (std::is_unsigned_v) - return stringToUnsigned(value, endian); - else if constexpr (std::is_signed_v) - return stringToSigned(value, endian); + if constexpr (std::unsigned_integral) + return stringToUnsigned(value, endian); + else if constexpr (std::signed_integral) + return stringToSigned(value, endian); else return {}; } + template + static std::string unsignedToString(const std::vector &buffer, std::endian endian, Style style) requires(sizeof(T) <= sizeof(u64)) { + if (buffer.size() < Size) + return { }; + + auto format = (style == Style::Decimal) ? "{0:d}" : ((style == Style::Hexadecimal) ? hex::format("0x{{0:0{}X}}", Size * 2) : hex::format("0o{{0:0{}o}}", Size * 3)); + + T value = 0x00; + std::memcpy(&value, buffer.data(), Size); + return hex::format(format, hex::changeEndianess(value, Size, endian)); + } + + template + static std::string signedToString(const std::vector &buffer, std::endian endian, Style style) requires(sizeof(T) <= sizeof(u64)) { + if (buffer.size() < Size) + return { }; + + auto format = (style == Style::Decimal) ? "{0}{1:d}" : ((style == Style::Hexadecimal) ? hex::format("{{0}}0x{{1:0{}X}}", Size * 2) : hex::format("{{0}}0o{{1:0{}o}}", Size * 3)); + + T value = 0x00; + std::memcpy(&value, buffer.data(), Size); + auto number = hex::signExtend(Size * 8, hex::changeEndianess(value, Size, endian)); + bool negative = number < 0; + + return hex::format(format, negative ? "-" : "", std::abs(number)); + } + + template + static std::string integerToString(const std::vector &buffer, std::endian endian, Style style) requires(sizeof(T) <= sizeof(u64)) { + if constexpr (std::unsigned_integral) + return unsignedToString(buffer, endian, style); + else if constexpr (std::signed_integral) + return signedToString(buffer, endian, style); + else + return {}; + } + + template + static hex::ContentRegistry::DataInspector::impl::GeneratorFunction drawString(T func) { + return [func](const std::vector &buffer, std::endian endian, Style style) { + return [value = func(buffer, endian, style)] -> std::string { ImGui::TextUnformatted(value.c_str()); return value; }; + }; + + } + // clang-format off void registerDataInspectorEntries() { - using Style = ContentRegistry::DataInspector::NumberDisplayStyle; - ContentRegistry::DataInspector::add("hex.builtin.inspector.binary", sizeof(u8), [](auto buffer, auto endian, auto style) { hex::unused(endian, style); @@ -115,101 +160,65 @@ namespace hex::plugin::builtin { } ); + + ContentRegistry::DataInspector::add("hex.builtin.inspector.u8", sizeof(u8), - [](auto buffer, auto endian, auto style) { - hex::unused(endian); - - auto format = (style == Style::Decimal) ? "{0:d}" : ((style == Style::Hexadecimal) ? "0x{0:02X}" : "0o{0:03o}"); - - auto value = hex::format(format, *reinterpret_cast(buffer.data())); - - return [value] { ImGui::TextUnformatted(value.c_str()); return value; }; - }, + drawString(integerToString), stringToInteger ); ContentRegistry::DataInspector::add("hex.builtin.inspector.i8", sizeof(i8), - [](auto buffer, auto endian, auto style) { - auto format = (style == Style::Decimal) ? "{0}{1:d}" : ((style == Style::Hexadecimal) ? "{0}0x{1:02X}" : "{0}0o{1:03o}"); - - auto number = hex::changeEndianess(*reinterpret_cast(buffer.data()), endian); - bool negative = number < 0; - auto value = hex::format(format, negative ? "-" : "", std::abs(number)); - - return [value] { ImGui::TextUnformatted(value.c_str()); return value; }; - }, - stringToInteger + drawString(integerToString), + stringToInteger ); ContentRegistry::DataInspector::add("hex.builtin.inspector.u16", sizeof(u16), - [](auto buffer, auto endian, auto style) { - auto format = (style == Style::Decimal) ? "{0:d}" : ((style == Style::Hexadecimal) ? "0x{0:04X}" : "0o{0:06o}"); - - auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); - - return [value] { ImGui::TextUnformatted(value.c_str()); return value; }; - }, + drawString(integerToString), stringToInteger ); ContentRegistry::DataInspector::add("hex.builtin.inspector.i16", sizeof(i16), - [](auto buffer, auto endian, auto style) { - auto format = (style == Style::Decimal) ? "{0}{1:d}" : ((style == Style::Hexadecimal) ? "{0}0x{1:04X}" : "{0}0o{1:06o}"); - - auto number = hex::changeEndianess(*reinterpret_cast(buffer.data()), endian); - bool negative = number < 0; - auto value = hex::format(format, negative ? "-" : "", std::abs(number)); - - return [value] { ImGui::TextUnformatted(value.c_str()); return value; }; - }, + drawString(integerToString), stringToInteger ); + ContentRegistry::DataInspector::add("hex.builtin.inspector.u24", 3, + drawString(integerToString), + stringToInteger + ); + + ContentRegistry::DataInspector::add("hex.builtin.inspector.i24", 3, + drawString(integerToString), + stringToInteger + ); + ContentRegistry::DataInspector::add("hex.builtin.inspector.u32", sizeof(u32), - [](auto buffer, auto endian, auto style) { - auto format = (style == Style::Decimal) ? "{0:d}" : ((style == Style::Hexadecimal) ? "0x{0:08X}" : "0o{0:011o}"); - - auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); - - return [value] { ImGui::TextUnformatted(value.c_str()); return value; }; - }, + drawString(integerToString), stringToInteger ); ContentRegistry::DataInspector::add("hex.builtin.inspector.i32", sizeof(i32), - [](auto buffer, auto endian, auto style) { - auto format = (style == Style::Decimal) ? "{0}{1:d}" : ((style == Style::Hexadecimal) ? "{0}0x{1:08X}" : "{0}0o{1:011o}"); - - auto number = hex::changeEndianess(*reinterpret_cast(buffer.data()), endian); - bool negative = number < 0; - auto value = hex::format(format, negative ? "-" : "", std::abs(number)); - - return [value] { ImGui::TextUnformatted(value.c_str()); return value; }; - }, + drawString(integerToString), stringToInteger ); + ContentRegistry::DataInspector::add("hex.builtin.inspector.u48", 6, + drawString(integerToString), + stringToInteger + ); + + ContentRegistry::DataInspector::add("hex.builtin.inspector.i48", 6, + drawString(integerToString), + stringToInteger + ); + ContentRegistry::DataInspector::add("hex.builtin.inspector.u64", sizeof(u64), - [](auto buffer, auto endian, auto style) { - auto format = (style == Style::Decimal) ? "{0:d}" : ((style == Style::Hexadecimal) ? "0x{0:016X}" : "0o{0:022o}"); - - auto value = hex::format(format, hex::changeEndianess(*reinterpret_cast(buffer.data()), endian)); - - return [value] { ImGui::TextUnformatted(value.c_str()); return value; }; - }, + drawString(integerToString), stringToInteger ); ContentRegistry::DataInspector::add("hex.builtin.inspector.i64", sizeof(i64), - [](auto buffer, auto endian, auto style) { - auto format = (style == Style::Decimal) ? "{0}{1:d}" : ((style == Style::Hexadecimal) ? "{0}0x{1:016X}" : "{0}0o{1:022o}"); - - auto number = hex::changeEndianess(*reinterpret_cast(buffer.data()), endian); - bool negative = number < 0; - auto value = hex::format(format, negative ? "-" : "", std::abs(number)); - - return [value] { ImGui::TextUnformatted(value.c_str()); return value; }; - }, + drawString(integerToString), stringToInteger ); diff --git a/plugins/builtin/source/lang/de_DE.cpp b/plugins/builtin/source/lang/de_DE.cpp index e7da88498..c9912d9f6 100644 --- a/plugins/builtin/source/lang/de_DE.cpp +++ b/plugins/builtin/source/lang/de_DE.cpp @@ -419,8 +419,12 @@ namespace hex::plugin::builtin { { "hex.builtin.inspector.i8", "int8_t" }, { "hex.builtin.inspector.u16", "uint16_t" }, { "hex.builtin.inspector.i16", "int16_t" }, + { "hex.builtin.inspector.u24", "uint24_t" }, + { "hex.builtin.inspector.i24", "int24_t" }, { "hex.builtin.inspector.u32", "uint32_t" }, { "hex.builtin.inspector.i32", "int32_t" }, + { "hex.builtin.inspector.u48", "uint48_t" }, + { "hex.builtin.inspector.i48", "int48_t" }, { "hex.builtin.inspector.u64", "uint64_t" }, { "hex.builtin.inspector.i64", "int64_t" }, { "hex.builtin.inspector.float16", "half float (16 bit)" }, diff --git a/plugins/builtin/source/lang/en_US.cpp b/plugins/builtin/source/lang/en_US.cpp index 9face57b6..55924389f 100644 --- a/plugins/builtin/source/lang/en_US.cpp +++ b/plugins/builtin/source/lang/en_US.cpp @@ -424,8 +424,12 @@ namespace hex::plugin::builtin { { "hex.builtin.inspector.i8", "int8_t" }, { "hex.builtin.inspector.u16", "uint16_t" }, { "hex.builtin.inspector.i16", "int16_t" }, + { "hex.builtin.inspector.u24", "uint24_t" }, + { "hex.builtin.inspector.i24", "int24_t" }, { "hex.builtin.inspector.u32", "uint32_t" }, { "hex.builtin.inspector.i32", "int32_t" }, + { "hex.builtin.inspector.u48", "uint48_t" }, + { "hex.builtin.inspector.i48", "int48_t" }, { "hex.builtin.inspector.u64", "uint64_t" }, { "hex.builtin.inspector.i64", "int64_t" }, { "hex.builtin.inspector.float16", "half float (16 bit)" }, diff --git a/plugins/builtin/source/lang/it_IT.cpp b/plugins/builtin/source/lang/it_IT.cpp index b1325f95a..7b197948b 100644 --- a/plugins/builtin/source/lang/it_IT.cpp +++ b/plugins/builtin/source/lang/it_IT.cpp @@ -422,8 +422,12 @@ namespace hex::plugin::builtin { { "hex.builtin.inspector.i8", "int8_t" }, { "hex.builtin.inspector.u16", "uint16_t" }, { "hex.builtin.inspector.i16", "int16_t" }, + { "hex.builtin.inspector.u24", "uint24_t" }, + { "hex.builtin.inspector.i24", "int24_t" }, { "hex.builtin.inspector.u32", "uint32_t" }, { "hex.builtin.inspector.i32", "int32_t" }, + { "hex.builtin.inspector.u48", "uint48_t" }, + { "hex.builtin.inspector.i48", "int48_t" }, { "hex.builtin.inspector.u64", "uint64_t" }, { "hex.builtin.inspector.i64", "int64_t" }, { "hex.builtin.inspector.float16", "half float (16 bit)" }, diff --git a/plugins/builtin/source/lang/ja_JP.cpp b/plugins/builtin/source/lang/ja_JP.cpp index 43996265c..b57bb1ee1 100644 --- a/plugins/builtin/source/lang/ja_JP.cpp +++ b/plugins/builtin/source/lang/ja_JP.cpp @@ -423,8 +423,12 @@ namespace hex::plugin::builtin { { "hex.builtin.inspector.i8", "int8_t" }, { "hex.builtin.inspector.u16", "uint16_t" }, { "hex.builtin.inspector.i16", "int16_t" }, + { "hex.builtin.inspector.u24", "uint24_t" }, + { "hex.builtin.inspector.i24", "int24_t" }, { "hex.builtin.inspector.u32", "uint32_t" }, { "hex.builtin.inspector.i32", "int32_t" }, + { "hex.builtin.inspector.u48", "uint48_t" }, + { "hex.builtin.inspector.i48", "int48_t" }, { "hex.builtin.inspector.u64", "uint64_t" }, { "hex.builtin.inspector.i64", "int64_t" }, { "hex.builtin.inspector.float16", "half float (16 bit)" }, diff --git a/plugins/builtin/source/lang/pt_BR.cpp b/plugins/builtin/source/lang/pt_BR.cpp index 2d0a09886..9619eae28 100644 --- a/plugins/builtin/source/lang/pt_BR.cpp +++ b/plugins/builtin/source/lang/pt_BR.cpp @@ -420,8 +420,12 @@ namespace hex::plugin::builtin { { "hex.builtin.inspector.i8", "int8_t" }, { "hex.builtin.inspector.u16", "uint16_t" }, { "hex.builtin.inspector.i16", "int16_t" }, + { "hex.builtin.inspector.u24", "uint24_t" }, + { "hex.builtin.inspector.i24", "int24_t" }, { "hex.builtin.inspector.u32", "uint32_t" }, { "hex.builtin.inspector.i32", "int32_t" }, + { "hex.builtin.inspector.u48", "uint48_t" }, + { "hex.builtin.inspector.i48", "int48_t" }, { "hex.builtin.inspector.u64", "uint64_t" }, { "hex.builtin.inspector.i64", "int64_t" }, { "hex.builtin.inspector.float16", "half float (16 bit)" }, diff --git a/plugins/builtin/source/lang/zh_CN.cpp b/plugins/builtin/source/lang/zh_CN.cpp index 5c5d0d7f5..a375a9f24 100644 --- a/plugins/builtin/source/lang/zh_CN.cpp +++ b/plugins/builtin/source/lang/zh_CN.cpp @@ -424,8 +424,12 @@ namespace hex::plugin::builtin { { "hex.builtin.inspector.i8", "int8_t" }, { "hex.builtin.inspector.u16", "uint16_t" }, { "hex.builtin.inspector.i16", "int16_t" }, + { "hex.builtin.inspector.u24", "uint24_t" }, + { "hex.builtin.inspector.i24", "int24_t" }, { "hex.builtin.inspector.u32", "uint32_t" }, { "hex.builtin.inspector.i32", "int32_t" }, + { "hex.builtin.inspector.u48", "uint48_t" }, + { "hex.builtin.inspector.i48", "int48_t" }, { "hex.builtin.inspector.u64", "uint64_t" }, { "hex.builtin.inspector.i64", "int64_t" }, { "hex.builtin.inspector.float16", "半精度浮点(16位)" }, diff --git a/plugins/builtin/source/lang/zh_TW.cpp b/plugins/builtin/source/lang/zh_TW.cpp index 3ca5fc4ad..f9435d83a 100644 --- a/plugins/builtin/source/lang/zh_TW.cpp +++ b/plugins/builtin/source/lang/zh_TW.cpp @@ -421,8 +421,12 @@ namespace hex::plugin::builtin { { "hex.builtin.inspector.i8", "int8_t" }, { "hex.builtin.inspector.u16", "uint16_t" }, { "hex.builtin.inspector.i16", "int16_t" }, + { "hex.builtin.inspector.u24", "uint24_t" }, + { "hex.builtin.inspector.i24", "int24_t" }, { "hex.builtin.inspector.u32", "uint32_t" }, { "hex.builtin.inspector.i32", "int32_t" }, + { "hex.builtin.inspector.u48", "uint48_t" }, + { "hex.builtin.inspector.i48", "int48_t" }, { "hex.builtin.inspector.u64", "uint64_t" }, { "hex.builtin.inspector.i64", "int64_t" }, { "hex.builtin.inspector.float16", "half float (16 位元)" },