MCPcopy Create free account
hub / github.com/danoon2/Boxedwine / utf8_decoder

Class utf8_decoder

lib/pugixml/src/pugixml.cpp:1619–1684  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1617 };
1618
1619 struct utf8_decoder
1620 {
1621 typedef uint8_t type;
1622
1623 template <typename Traits> static inline typename Traits::value_type process(const uint8_t* data, size_t size, typename Traits::value_type result, Traits)
1624 {
1625 const uint8_t utf8_byte_mask = 0x3f;
1626
1627 while (size)
1628 {
1629 uint8_t lead = *data;
1630
1631 // 0xxxxxxx -> U+0000..U+007F
1632 if (lead < 0x80)
1633 {
1634 result = Traits::low(result, lead);
1635 data += 1;
1636 size -= 1;
1637
1638 // process aligned single-byte (ascii) blocks
1639 if ((reinterpret_cast<uintptr_t>(data) & 3) == 0)
1640 {
1641 // round-trip through void* to silence 'cast increases required alignment of target type' warnings
1642 while (size >= 4 && (*static_cast<const uint32_t*>(static_cast<const void*>(data)) & 0x80808080) == 0)
1643 {
1644 result = Traits::low(result, data[0]);
1645 result = Traits::low(result, data[1]);
1646 result = Traits::low(result, data[2]);
1647 result = Traits::low(result, data[3]);
1648 data += 4;
1649 size -= 4;
1650 }
1651 }
1652 }
1653 // 110xxxxx -> U+0080..U+07FF
1654 else if (static_cast<unsigned int>(lead - 0xC0) < 0x20 && size >= 2 && (data[1] & 0xc0) == 0x80)
1655 {
1656 result = Traits::low(result, ((lead & ~0xC0) << 6) | (data[1] & utf8_byte_mask));
1657 data += 2;
1658 size -= 2;
1659 }
1660 // 1110xxxx -> U+0800-U+FFFF
1661 else if (static_cast<unsigned int>(lead - 0xE0) < 0x10 && size >= 3 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80)
1662 {
1663 result = Traits::low(result, ((lead & ~0xE0) << 12) | ((data[1] & utf8_byte_mask) << 6) | (data[2] & utf8_byte_mask));
1664 data += 3;
1665 size -= 3;
1666 }
1667 // 11110xxx -> U+10000..U+10FFFF
1668 else if (static_cast<unsigned int>(lead - 0xF0) < 0x08 && size >= 4 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80 && (data[3] & 0xc0) == 0x80)
1669 {
1670 result = Traits::high(result, ((lead & ~0xF0) << 18) | ((data[1] & utf8_byte_mask) << 12) | ((data[2] & utf8_byte_mask) << 6) | (data[3] & utf8_byte_mask));
1671 data += 4;
1672 size -= 4;
1673 }
1674 // 10xxxxxx or 11111xxx -> invalid
1675 else
1676 {

Callers 2

convert_bufferFunction · 0.85
convert_buffer_outputFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected