MCPcopy Create free account
hub / github.com/StereoKit/StereoKit / utf8_decode_fast

Function utf8_decode_fast

StereoKitC/libraries/unicode.cpp:12–40  ·  view source on GitHub ↗

Source: https://github.com/skeeto/branchless-utf8 Should switch this to a SIMD implementation later, possibly: https://dirtyhandscoding.github.io/posts/utf8lut-vectorized-utf-8-converter-decoding-utf-8.html

Source from the content-addressed store, hash-verified

10// Should switch this to a SIMD implementation later, possibly:
11// https://dirtyhandscoding.github.io/posts/utf8lut-vectorized-utf-8-converter-decoding-utf-8.html
12char32_t utf8_decode_fast(const char *utf8_str, const char **out_next_char) {
13 static const uint32_t lengths[] = {
14 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
15 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0
16 };
17 static const int32_t masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
18 static const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
19 static const int32_t shiftc[] = {0, 18, 12, 6, 0};
20 static const int32_t shifte[] = {0, 6, 4, 2, 0};
21
22 const unsigned char *s = (unsigned char *)utf8_str;
23 int32_t len = lengths[s[0] >> 3];
24
25 // Compute the pointer to the next character early so that the next
26 // iteration can start working on the next character. Neither Clang
27 // nor GCC figure out this reordering on their own.
28 const unsigned char *next = s + len + !len;
29
30 // Assume a four-byte character and load four bytes. Unused bits are
31 // shifted out.
32 char32_t result = (char32_t)(s[0] & masks[len]) << 18;
33 result |= (char32_t)(s[1] & 0x3f) << 12;
34 result |= (char32_t)(s[2] & 0x3f) << 6;
35 result |= (char32_t)(s[3] & 0x3f) << 0;
36 result >>= shiftc[len];
37
38 *out_next_char = (const char *)next;
39 return result;
40}
41
42///////////////////////////////////////////
43

Callers 3

utf8_decode_fast_bFunction · 0.85
web_on_keyFunction · 0.85
platform_check_eventsFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected