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