| 11518 | |
| 11519 | template <typename It> |
| 11520 | inline decoded_result<It> utf8_to_code_point(It it, It last) { |
| 11521 | decoded_result<It> dr; |
| 11522 | if (it == last) { |
| 11523 | dr.next = it; |
| 11524 | dr.error = error_code::sequence_too_short; |
| 11525 | return dr; |
| 11526 | } |
| 11527 | |
| 11528 | unsigned char b0 = *it; |
| 11529 | std::size_t length = unicode_detail::sequence_length(b0); |
| 11530 | |
| 11531 | if (length == 1) { |
| 11532 | dr.codepoint = static_cast<char32_t>(b0); |
| 11533 | dr.error = error_code::ok; |
| 11534 | ++it; |
| 11535 | dr.next = it; |
| 11536 | return dr; |
| 11537 | } |
| 11538 | |
| 11539 | if (unicode_detail::is_invalid(b0) || unicode_detail::is_continuation(b0)) { |
| 11540 | dr.error = error_code::invalid_code_unit; |
| 11541 | dr.next = it; |
| 11542 | return dr; |
| 11543 | } |
| 11544 | |
| 11545 | ++it; |
| 11546 | std::array<unsigned char, 4> b; |
| 11547 | b[0] = b0; |
| 11548 | for (std::size_t i = 1; i < length; ++i) { |
| 11549 | b[i] = *it; |
| 11550 | if (!unicode_detail::is_continuation(b[i])) { |
| 11551 | dr.error = error_code::invalid_code_unit; |
| 11552 | dr.next = it; |
| 11553 | return dr; |
| 11554 | } |
| 11555 | ++it; |
| 11556 | } |
| 11557 | |
| 11558 | char32_t decoded; |
| 11559 | switch (length) { |
| 11560 | case 2: |
| 11561 | decoded = unicode_detail::decode(b[0], b[1]); |
| 11562 | break; |
| 11563 | case 3: |
| 11564 | decoded = unicode_detail::decode(b[0], b[1], b[2]); |
| 11565 | break; |
| 11566 | default: |
| 11567 | decoded = unicode_detail::decode(b[0], b[1], b[2], b[3]); |
| 11568 | break; |
| 11569 | } |
| 11570 | |
| 11571 | if (unicode_detail::is_overlong(decoded, length)) { |
| 11572 | dr.error = error_code::overlong_sequence; |
| 11573 | return dr; |
| 11574 | } |
| 11575 | if (unicode_detail::is_surrogate(decoded) || decoded > unicode_detail::last_code_point) { |
| 11576 | dr.error = error_code::invalid_code_point; |
| 11577 | return dr; |