simdutf 8.0.0
Unicode at GB/s.
Loading...
Searching...
No Matches
utf32_to_latin1.h
1#ifndef SIMDUTF_UTF32_TO_LATIN1_H
2#define SIMDUTF_UTF32_TO_LATIN1_H
3
4namespace simdutf {
5namespace scalar {
6namespace {
7namespace utf32_to_latin1 {
8
9inline simdutf_constexpr23 size_t convert(const char32_t *data, size_t len,
10 char *latin1_output) {
11 char *start = latin1_output;
12 uint32_t utf32_char;
13 size_t pos = 0;
14 uint32_t too_large = 0;
15
16 while (pos < len) {
17 utf32_char = (uint32_t)data[pos];
18 too_large |= utf32_char;
19 *latin1_output++ = (char)(utf32_char & 0xFF);
20 pos++;
21 }
22 if ((too_large & 0xFFFFFF00) != 0) {
23 return 0;
24 }
25 return latin1_output - start;
26}
27
28inline simdutf_constexpr23 result convert_with_errors(const char32_t *data,
29 size_t len,
30 char *latin1_output) {
31 char *start{latin1_output};
32 size_t pos = 0;
33 while (pos < len) {
34#if SIMDUTF_CPLUSPLUS23
35 if !consteval
36#endif
37 {
38 if (pos + 2 <= len) { // if it is safe to read 8 more bytes, check that
39 // they are Latin1
40 uint64_t v;
41 ::memcpy(&v, data + pos, sizeof(uint64_t));
42 if ((v & 0xFFFFFF00FFFFFF00) == 0) {
43 *latin1_output++ = char(data[pos]);
44 *latin1_output++ = char(data[pos + 1]);
45 pos += 2;
46 continue;
47 }
48 }
49 }
50
51 uint32_t utf32_char = data[pos];
52 if ((utf32_char & 0xFFFFFF00) ==
53 0) { // Check if the character can be represented in Latin-1
54 *latin1_output++ = (char)(utf32_char & 0xFF);
55 pos++;
56 } else {
57 return result(error_code::TOO_LARGE, pos);
58 };
59 }
60 return result(error_code::SUCCESS, latin1_output - start);
61}
62
63} // namespace utf32_to_latin1
64} // unnamed namespace
65} // namespace scalar
66} // namespace simdutf
67
68#endif