MCPcopy Create free account
hub / github.com/NativeScript/android / utf8_to_utf32

Function utf8_to_utf32

test-app/runtime/src/main/cpp/ada/ada.cpp:148–243  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

146namespace ada::idna {
147
148size_t utf8_to_utf32(const char* buf, size_t len, char32_t* utf32_output) {
149 const uint8_t* data = reinterpret_cast<const uint8_t*>(buf);
150 size_t pos = 0;
151 const char32_t* start{utf32_output};
152 while (pos < len) {
153 // try to convert the next block of 16 ASCII bytes
154 if (pos + 16 <= len) { // if it is safe to read 16 more
155 // bytes, check that they are ascii
156 uint64_t v1;
157 std::memcpy(&v1, data + pos, sizeof(uint64_t));
158 uint64_t v2;
159 std::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t));
160 uint64_t v{v1 | v2};
161 if ((v & 0x8080808080808080) == 0) {
162 size_t final_pos = pos + 16;
163 while (pos < final_pos) {
164 *utf32_output++ = char32_t(buf[pos]);
165 pos++;
166 }
167 continue;
168 }
169 }
170 uint8_t leading_byte = data[pos]; // leading byte
171 if (leading_byte < 0b10000000) {
172 // converting one ASCII byte !!!
173 *utf32_output++ = char32_t(leading_byte);
174 pos++;
175 } else if ((leading_byte & 0b11100000) == 0b11000000) {
176 // We have a two-byte UTF-8
177 if (pos + 1 >= len) {
178 return 0;
179 } // minimal bound checking
180 if ((data[pos + 1] & 0b11000000) != 0b10000000) {
181 return 0;
182 }
183 // range check
184 uint32_t code_point =
185 (leading_byte & 0b00011111) << 6 | (data[pos + 1] & 0b00111111);
186 if (code_point < 0x80 || 0x7ff < code_point) {
187 return 0;
188 }
189 *utf32_output++ = char32_t(code_point);
190 pos += 2;
191 } else if ((leading_byte & 0b11110000) == 0b11100000) {
192 // We have a three-byte UTF-8
193 if (pos + 2 >= len) {
194 return 0;
195 } // minimal bound checking
196
197 if ((data[pos + 1] & 0b11000000) != 0b10000000) {
198 return 0;
199 }
200 if ((data[pos + 2] & 0b11000000) != 0b10000000) {
201 return 0;
202 }
203 // range check
204 uint32_t code_point = (leading_byte & 0b00001111) << 12 |
205 (data[pos + 1] & 0b00111111) << 6 |

Callers 1

to_asciiFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected