MCPcopy Create free account
hub / github.com/apache/fory / utf8_to_utf16_simd

Function utf8_to_utf16_simd

cpp/fory/util/string_util.cc:28–150  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

26namespace fory {
27
28std::u16string utf8_to_utf16_simd(const std::string &utf8,
29 bool is_little_endian) {
30 std::u16string utf16;
31 utf16.reserve(utf8.size()); // reserve space to avoid frequent reallocations
32
33 char buffer[64]; // Buffer to hold temporary UTF-16 results
34 char16_t *output =
35 reinterpret_cast<char16_t *>(buffer); // Use char16_t for output
36
37 size_t i = 0;
38 size_t n = utf8.size();
39
40 while (i + 32 <= n) {
41
42 for (int j = 0; j < 32; ++j) {
43 uint8_t byte = utf8[i + j];
44
45 if (byte < 0x80) {
46 // 1-byte character (ASCII)
47 *output++ = static_cast<char16_t>(byte);
48 } else if (byte < 0xE0) {
49 // 2-byte character
50 uint16_t utf16_char = ((byte & 0x1F) << 6) | (utf8[i + j + 1] & 0x3F);
51 if (!is_little_endian) {
52 utf16_char = (utf16_char >> 8) |
53 (utf16_char << 8); // Swap bytes for big-endian
54 }
55 *output++ = utf16_char;
56 ++j;
57 } else if (byte < 0xF0) {
58 // 3-byte character
59 uint16_t utf16_char = ((byte & 0x0F) << 12) |
60 ((utf8[i + j + 1] & 0x3F) << 6) |
61 (utf8[i + j + 2] & 0x3F);
62 if (!is_little_endian) {
63 utf16_char = (utf16_char >> 8) |
64 (utf16_char << 8); // Swap bytes for big-endian
65 }
66 *output++ = utf16_char;
67 j += 2;
68 } else {
69 // 4-byte character (surrogate pair handling required)
70 uint32_t code_point =
71 ((byte & 0x07) << 18) | ((utf8[i + j + 1] & 0x3F) << 12) |
72 ((utf8[i + j + 2] & 0x3F) << 6) | (utf8[i + j + 3] & 0x3F);
73
74 // Convert the code point to a surrogate pair
75 uint16_t high_surrogate = 0xD800 + ((code_point - 0x10000) >> 10);
76 uint16_t low_surrogate = 0xDC00 + (code_point & 0x3FF);
77
78 if (!is_little_endian) {
79 high_surrogate = (high_surrogate >> 8) |
80 (high_surrogate << 8); // Swap bytes for big-endian
81 low_surrogate = (low_surrogate >> 8) |
82 (low_surrogate << 8); // Swap bytes for big-endian
83 }
84
85 *output++ = high_surrogate;

Callers 1

utf8_to_utf16Function · 0.85

Calls 3

reserveMethod · 0.45
sizeMethod · 0.45
appendMethod · 0.45

Tested by

no test coverage detected