@brief Converts UTF-16 encoded characters to UTF-8 encoded bytes. @param[in] utf16 UTF-16 encoded character(s). @param[out] utf8 UTF-8 encoded bytes. @param[out] consumed_size The number of UTF-16 encoded characters used for the conversion. @param[out] encoded_size The size of UTF-encoded bytes.
| 1999 | /// @param[out] consumed_size The number of UTF-16 encoded characters used for the conversion. |
| 2000 | /// @param[out] encoded_size The size of UTF-encoded bytes. |
| 2001 | inline void from_utf16( |
| 2002 | std::array<char16_t, 2> utf16, std::array<uint8_t, 4>& utf8, uint32_t& consumed_size, uint32_t& encoded_size) { |
| 2003 | const auto first = utf16[0]; |
| 2004 | const auto second = utf16[1]; |
| 2005 | if (first < 0x80u) { |
| 2006 | utf8[0] = static_cast<uint8_t>(first & 0x7Fu); |
| 2007 | consumed_size = 1; |
| 2008 | encoded_size = 1; |
| 2009 | } |
| 2010 | else if (first <= 0x7FFu) { |
| 2011 | const auto utf8_chunk = static_cast<uint16_t>(0xC080u | ((first & 0x07C0u) << 2) | (first & 0x3Fu)); |
| 2012 | utf8[0] = static_cast<uint8_t>(utf8_chunk >> 8); |
| 2013 | utf8[1] = static_cast<uint8_t>(utf8_chunk); |
| 2014 | consumed_size = 1; |
| 2015 | encoded_size = 2; |
| 2016 | } |
| 2017 | else if (first < 0xD800u || 0xE000u <= first) { |
| 2018 | const auto utf8_chunk = |
| 2019 | static_cast<uint32_t>(0xE08080u | ((first & 0xF000u) << 4) | ((first & 0x0FC0u) << 2) | (first & 0x3Fu)); |
| 2020 | utf8[0] = static_cast<uint8_t>(utf8_chunk >> 16); |
| 2021 | utf8[1] = static_cast<uint8_t>(utf8_chunk >> 8); |
| 2022 | utf8[2] = static_cast<uint8_t>(utf8_chunk); |
| 2023 | consumed_size = 1; |
| 2024 | encoded_size = 3; |
| 2025 | } |
| 2026 | else if (first <= 0xDBFFu && 0xDC00u <= second && second <= 0xDFFFu) { |
| 2027 | // surrogate pair |
| 2028 | const uint32_t code_point = 0x10000u + ((first & 0x03FFu) << 10) + (second & 0x03FFu); |
| 2029 | const auto utf8_chunk = static_cast<uint32_t>( |
| 2030 | 0xF0808080u | ((code_point & 0x1C0000u) << 6) | ((code_point & 0x03F000u) << 4) | |
| 2031 | ((code_point & 0x0FC0u) << 2) | (code_point & 0x3Fu)); |
| 2032 | utf8[0] = static_cast<uint8_t>(utf8_chunk >> 24); |
| 2033 | utf8[1] = static_cast<uint8_t>(utf8_chunk >> 16); |
| 2034 | utf8[2] = static_cast<uint8_t>(utf8_chunk >> 8); |
| 2035 | utf8[3] = static_cast<uint8_t>(utf8_chunk); |
| 2036 | consumed_size = 2; |
| 2037 | encoded_size = 4; |
| 2038 | } |
| 2039 | else { |
| 2040 | throw invalid_encoding("Invalid UTF-16 encoding detected.", utf16); |
| 2041 | } |
| 2042 | } |
| 2043 | |
| 2044 | /// @brief Converts a UTF-32 encoded character to UTF-8 encoded bytes. |
| 2045 | /// @param[in] utf32 A UTF-32 encoded character. |
no test coverage detected