From 23febcee51751330d4b31a9c9bc20424b1f618e3 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 30 Sep 2026 10:03:02 +0200 Subject: [PATCH] Merge duplicate byte-to-hex helper and drop stale '| 0' promotions serializer::hex_bytes() and binary_writer::hex_byte() had identical bodies. Keep one, detail::hex_byte() in string_utils.hpp, and use it from both. Also drop the `| 0` at the two serializer call sites (hex_bytes(byte | 0) and hex_bytes(s.back() | 0)): #3088 (7440786b8) added it so that `ss << std::hex << (byte | 0)` printed a number rather than a char with the old stringstream writer; the int result just narrows back to uint8_t now, so it was a no-op. Behavior is unchanged: unit-serialization, unit-bon8 (whose type_error.316 messages exercise this code) and unit-diagnostics pass, and both headers still compile standalone with -Werror. Part of #5709 Signed-off-by: Niels Lohmann --- .../nlohmann/detail/output/binary_writer.hpp | 13 +----- include/nlohmann/detail/output/serializer.hpp | 18 +------- include/nlohmann/detail/string_utils.hpp | 10 +++++ single_include/nlohmann/json.hpp | 42 +++++++------------ 4 files changed, 29 insertions(+), 54 deletions(-) diff --git a/include/nlohmann/detail/output/binary_writer.hpp b/include/nlohmann/detail/output/binary_writer.hpp index 9da4269a8..9b7541bcc 100644 --- a/include/nlohmann/detail/output/binary_writer.hpp +++ b/include/nlohmann/detail/output/binary_writer.hpp @@ -29,6 +29,7 @@ #include #include #include +#include NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail @@ -2278,20 +2279,10 @@ class binary_writer const std::size_t valid = valid_utf8_prefix(data, s.size()); if (JSON_HEDLEY_UNLIKELY(valid != s.size())) { - JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(valid), ": 0x", hex_byte(data[valid])), &context)); + JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(valid), ": 0x", detail::hex_byte(data[valid])), &context)); } } - /// @return a byte as two uppercase hexadecimal digits - static std::string hex_byte(const std::uint8_t byte) - { - std::string result = "00"; - constexpr const char* nibble_to_hex = "0123456789ABCDEF"; - result[0] = nibble_to_hex[byte / 16]; - result[1] = nibble_to_hex[byte % 16]; - return result; - } - /*! @brief write an integer in the shortest encoding diff --git a/include/nlohmann/detail/output/serializer.hpp b/include/nlohmann/detail/output/serializer.hpp index 23185b17e..5d6f3293e 100644 --- a/include/nlohmann/detail/output/serializer.hpp +++ b/include/nlohmann/detail/output/serializer.hpp @@ -882,7 +882,7 @@ class serializer { case error_handler_t::strict: { - JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr)); + JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", detail::hex_byte(byte)), nullptr)); } case error_handler_t::ignore: @@ -974,7 +974,7 @@ class serializer { case error_handler_t::strict: { - JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast(s[s.size() - 1] | 0))), nullptr)); + JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", detail::hex_byte(static_cast(s[s.size() - 1]))), nullptr)); } case error_handler_t::ignore: @@ -1195,20 +1195,6 @@ class serializer } } - /*! - * @brief convert a byte to a uppercase hex representation - * @param[in] byte byte to represent - * @return representation ("00".."FF") - */ - static std::string hex_bytes(std::uint8_t byte) - { - std::string result = "FF"; - constexpr const char* nibble_to_hex = "0123456789ABCDEF"; - result[0] = nibble_to_hex[byte / 16]; - result[1] = nibble_to_hex[byte % 16]; - return result; - } - /*! * @brief write a lowercase "\uXXXX" escape sequence into @a string_buffer * diff --git a/include/nlohmann/detail/string_utils.hpp b/include/nlohmann/detail/string_utils.hpp index 142943cd6..04eccb562 100644 --- a/include/nlohmann/detail/string_utils.hpp +++ b/include/nlohmann/detail/string_utils.hpp @@ -36,6 +36,16 @@ StringType to_string(std::size_t value) return result; } +/// @return a byte as two uppercase hexadecimal digits +inline std::string hex_byte(const std::uint8_t byte) +{ + std::string result = "00"; + constexpr const char* nibble_to_hex = "0123456789ABCDEF"; + result[0] = nibble_to_hex[byte / 16]; + result[1] = nibble_to_hex[byte % 16]; + return result; +} + /////////////////// // UTF-8 decoding // /////////////////// diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 1b0bc1f41..0183fe854 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -6234,6 +6234,16 @@ StringType to_string(std::size_t value) return result; } +/// @return a byte as two uppercase hexadecimal digits +inline std::string hex_byte(const std::uint8_t byte) +{ + std::string result = "00"; + constexpr const char* nibble_to_hex = "0123456789ABCDEF"; + result[0] = nibble_to_hex[byte / 16]; + result[1] = nibble_to_hex[byte % 16]; + return result; +} + /////////////////// // UTF-8 decoding // /////////////////// @@ -20358,6 +20368,8 @@ NLOHMANN_JSON_NAMESPACE_END // #include +// #include + NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail @@ -22607,20 +22619,10 @@ class binary_writer const std::size_t valid = valid_utf8_prefix(data, s.size()); if (JSON_HEDLEY_UNLIKELY(valid != s.size())) { - JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(valid), ": 0x", hex_byte(data[valid])), &context)); + JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(valid), ": 0x", detail::hex_byte(data[valid])), &context)); } } - /// @return a byte as two uppercase hexadecimal digits - static std::string hex_byte(const std::uint8_t byte) - { - std::string result = "00"; - constexpr const char* nibble_to_hex = "0123456789ABCDEF"; - result[0] = nibble_to_hex[byte / 16]; - result[1] = nibble_to_hex[byte % 16]; - return result; - } - /*! @brief write an integer in the shortest encoding @@ -24961,7 +24963,7 @@ class serializer { case error_handler_t::strict: { - JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr)); + JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", detail::hex_byte(byte)), nullptr)); } case error_handler_t::ignore: @@ -25053,7 +25055,7 @@ class serializer { case error_handler_t::strict: { - JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast(s[s.size() - 1] | 0))), nullptr)); + JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", detail::hex_byte(static_cast(s[s.size() - 1]))), nullptr)); } case error_handler_t::ignore: @@ -25274,20 +25276,6 @@ class serializer } } - /*! - * @brief convert a byte to a uppercase hex representation - * @param[in] byte byte to represent - * @return representation ("00".."FF") - */ - static std::string hex_bytes(std::uint8_t byte) - { - std::string result = "FF"; - constexpr const char* nibble_to_hex = "0123456789ABCDEF"; - result[0] = nibble_to_hex[byte / 16]; - result[1] = nibble_to_hex[byte % 16]; - return result; - } - /*! * @brief write a lowercase "\uXXXX" escape sequence into @a string_buffer *