| 5677 | } |
| 5678 | |
| 5679 | static bool extract_codepoint(const char*& begin, const char* end, int bytes_to_read, char32_t& codepoint) { |
| 5680 | const bool has_enough_room = static_cast<int>(std::distance(begin, end)) >= (bytes_to_read - 1); |
| 5681 | if (!has_enough_room) { |
| 5682 | return false; |
| 5683 | } |
| 5684 | |
| 5685 | const int read_size = bytes_to_read * 2; |
| 5686 | uint8_t byte {0}; |
| 5687 | codepoint = 0; |
| 5688 | |
| 5689 | for (int i = read_size - 1; i >= 0; i--) { |
| 5690 | const bool is_valid = convert_hexchar_to_byte(*++begin, byte); |
| 5691 | if (!is_valid) { |
| 5692 | return false; |
| 5693 | } |
| 5694 | // NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) |
| 5695 | codepoint |= static_cast<char32_t>(byte << (4 * i)); |
| 5696 | } |
| 5697 | |
| 5698 | return true; |
| 5699 | } |
| 5700 | |
| 5701 | static void unescape_escaped_unicode(char32_t codepoint, std::string& buff) { |
| 5702 | // the inner curly braces are necessary to build with older compilers. |