| 2414 | } |
| 2415 | |
| 2416 | Error String::parse_utf16(const char16_t* p_utf16, int p_len) |
| 2417 | { |
| 2418 | if (!p_utf16) |
| 2419 | { |
| 2420 | return ERR_INVALID_DATA; |
| 2421 | } |
| 2422 | |
| 2423 | String aux; |
| 2424 | |
| 2425 | int cstr_size = 0; |
| 2426 | int str_size = 0; |
| 2427 | |
| 2428 | /* HANDLE BOM (Byte Order Mark) */ |
| 2429 | bool byteswap = false; // assume correct endianness if no BOM found |
| 2430 | if (p_len < 0 || p_len >= 1) |
| 2431 | { |
| 2432 | bool has_bom = false; |
| 2433 | if (uint16_t(p_utf16[0]) == 0xfeff) |
| 2434 | { // correct BOM, read as is |
| 2435 | has_bom = true; |
| 2436 | byteswap = false; |
| 2437 | } |
| 2438 | else if (uint16_t(p_utf16[0]) == 0xfffe) |
| 2439 | { // backwards BOM, swap bytes |
| 2440 | has_bom = true; |
| 2441 | byteswap = true; |
| 2442 | } |
| 2443 | if (has_bom) |
| 2444 | { |
| 2445 | if (p_len >= 0) |
| 2446 | { |
| 2447 | p_len -= 1; |
| 2448 | } |
| 2449 | p_utf16 += 1; |
| 2450 | } |
| 2451 | } |
| 2452 | |
| 2453 | bool decode_error = false; |
| 2454 | { |
| 2455 | const char16_t* ptrtmp = p_utf16; |
| 2456 | const char16_t* ptrtmp_limit = &p_utf16[p_len]; |
| 2457 | uint32_t c_prev = 0; |
| 2458 | bool skip = false; |
| 2459 | while (ptrtmp != ptrtmp_limit && *ptrtmp) |
| 2460 | { |
| 2461 | uint32_t c = (byteswap) ? BSWAP16(*ptrtmp) : *ptrtmp; |
| 2462 | |
| 2463 | if ((c & 0xfffffc00) == 0xd800) |
| 2464 | { // lead surrogate |
| 2465 | if (skip) |
| 2466 | { |
| 2467 | print_unicode_error("Unpaired lead surrogate (" + num_uint64(c_prev) + " [trail?] " + num_uint64(c) + ")"); |
| 2468 | decode_error = true; |
| 2469 | } |
| 2470 | skip = true; |
| 2471 | } |
| 2472 | else if ((c & 0xfffffc00) == 0xdc00) |
| 2473 | { // trail surrogate |