3_meta_inline _Pure uint32 _strUTF8SeqLen(uint8 u)
9 if (u >= 0x80 && u <= 0xbf)
11 else if (u == 0xc0 || u == 0xc1)
13 else if (u >= 0xc2 && u <= 0xdf)
15 else if (u >= 0xe0 && u <= 0xef)
17 else if (u >= 0xf0 && u <= 0xf4)
23_meta_inline
bool _strUTF8DecodeSeq(
striter* _Nonnull it, uint32 len, uint8 ch,
24 int32* _Nullable codepoint)
39 for (; len > 1; --len) {
43 if (ch < 0x80 || ch > 0xbf)
46 ret = (ret << 6) | (ch & 0x3f);
50 (ret >= 0xd800 && ret <= 0xdfff) ||
51 (seqlen == 2 && ret < 0x80) ||
52 (seqlen == 3 && ret < 0x800) || (seqlen == 4 && ret < 0x10000))
61_meta_inline uint32 _strUTF8Decode(
striter* _Nonnull it, int32* _Nullable codepoint)
67 uint32 len = _strUTF8SeqLen(first);
75 if (_strUTF8DecodeSeq(it, len, first, codepoint))
81_meta_inline uint32 _strUTF8Encode(uint8* _Nonnull buffer, int32 codepoint)
83 if (codepoint < 0 || codepoint > 0x10ffff || (codepoint >= 0xd800 && codepoint <= 0xdfff))
86 if (codepoint < 0x80) {
87 buffer[0] = (uint8)codepoint;
89 }
else if (codepoint < 0x800) {
90 buffer[0] = 0xc0 | ((codepoint & 0x7c0) >> 6);
91 buffer[1] = 0x80 | ((codepoint & 0x03f));
93 }
else if (codepoint < 0x10000) {
94 buffer[0] = 0xe0 | ((codepoint & 0xf000) >> 12);
95 buffer[1] = 0x80 | ((codepoint & 0x0fc0) >> 6);
96 buffer[2] = 0x80 | ((codepoint & 0x003f));
100 buffer[0] = 0xf0 | ((codepoint & 0x1c0000) >> 18);
101 buffer[1] = 0x80 | ((codepoint & 0x03f000) >> 12);
102 buffer[2] = 0x80 | ((codepoint & 0x000fc0) >> 6);
103 buffer[3] = 0x80 | ((codepoint & 0x00003f));
bool striChar(striter *i, uint8 *out)