| 2153 | } |
| 2154 | |
| 2155 | Char16String String::utf16() const { |
| 2156 | int l = length(); |
| 2157 | if (!l) { |
| 2158 | return Char16String(); |
| 2159 | } |
| 2160 | |
| 2161 | const char32_t *d = &operator[](0); |
| 2162 | int fl = 0; |
| 2163 | for (int i = 0; i < l; i++) { |
| 2164 | uint32_t c = d[i]; |
| 2165 | if (c <= 0xffff) { // 16 bits. |
| 2166 | fl += 1; |
| 2167 | if ((c & 0xfffff800) == 0xd800) { |
| 2168 | print_unicode_error(vformat("Unpaired surrogate (%x)", c)); |
| 2169 | } |
| 2170 | } else if (c <= 0x10ffff) { // 32 bits. |
| 2171 | fl += 2; |
| 2172 | } else { |
| 2173 | print_unicode_error(vformat("Invalid unicode codepoint (%x), cannot represent as UTF-16", c), true); |
| 2174 | fl += 1; |
| 2175 | } |
| 2176 | } |
| 2177 | |
| 2178 | Char16String utf16s; |
| 2179 | if (fl == 0) { |
| 2180 | return utf16s; |
| 2181 | } |
| 2182 | |
| 2183 | utf16s.resize_uninitialized(fl + 1); |
| 2184 | uint16_t *cdst = (uint16_t *)utf16s.get_data(); |
| 2185 | |
| 2186 | #define APPEND_CHAR(m_c) *(cdst++) = m_c |
| 2187 | |
| 2188 | for (int i = 0; i < l; i++) { |
| 2189 | uint32_t c = d[i]; |
| 2190 | |
| 2191 | if (c <= 0xffff) { // 16 bits. |
| 2192 | APPEND_CHAR(c); |
| 2193 | } else if (c <= 0x10ffff) { // 32 bits. |
| 2194 | APPEND_CHAR(uint32_t((c >> 10) + 0xd7c0)); // lead surrogate. |
| 2195 | APPEND_CHAR(uint32_t((c & 0x3ff) | 0xdc00)); // trail surrogate. |
| 2196 | } else { |
| 2197 | // the string is a valid UTF32, so it should never happen ... |
| 2198 | APPEND_CHAR(uint32_t((_replacement_char >> 10) + 0xd7c0)); |
| 2199 | APPEND_CHAR(uint32_t((_replacement_char & 0x3ff) | 0xdc00)); |
| 2200 | } |
| 2201 | } |
| 2202 | #undef APPEND_CHAR |
| 2203 | *cdst = 0; //trailing zero |
| 2204 | |
| 2205 | return utf16s; |
| 2206 | } |
| 2207 | |
| 2208 | int64_t String::hex_to_int() const { |
| 2209 | int len = length(); |
no test coverage detected