in src/Windows/libraries/multi_byte/include/m/multi_byte/convert.h [214:267]
OutIter utf16_to_multi_byte(code_page cp,
std::basic_string_view<Utf16CharT, CharTraitsT> const& in,
OutIter it)
{
std::array<char, BufferSize> buffer;
auto input_cursor{in.data()};
auto chars_left{in.size()};
while (chars_left != 0)
{
std::size_t chars_to_convert{(std::min)(chars_left, buffer.size())};
// mbcs -> Utf16 cannot (proof separate, as long as chars
// above U+FFFF aren't encoded in single byte form in the
// source) expand in terms of count, so we assume that
// failures are either fundamentally bad encodings or
// that we ran out of output buffer. We will assume out of
// output buffer and trim down conversion length until
// we get a successful conversion or zero length.
//
// If we hit zero length, we will assume it was a bad
// encoding, because it must have been. Otherwise we have
// to make the interface with try_acp_to_utf16()
// significantly more complicated.
//
for (;;)
{
// This should probably be converted to use std::size_t
// indices and .substr() or such that way the type
// wouldn't have to be named here.
auto const view = std::basic_string_view<Utf16CharT, CharTraitsT>(
input_cursor, chars_to_convert);
auto span = m::make_span(buffer);
if (windows::is_success(try_utf16_to_multi_byte(cp, view, span)))
{
it = std::ranges::copy(span, it).out;
chars_left -= chars_to_convert;
input_cursor += chars_to_convert;
break;
}
chars_to_convert--;
if (chars_to_convert == 0)
throw std::runtime_error("invalid UTF-16 character data");
}
}
return it;
}