| 2062 | } |
| 2063 | |
| 2064 | Error String::parse_utf8(const char* p_utf8, int p_len, bool p_skip_cr) |
| 2065 | { |
| 2066 | if (!p_utf8) |
| 2067 | { |
| 2068 | return ERR_INVALID_DATA; |
| 2069 | } |
| 2070 | |
| 2071 | String aux; |
| 2072 | |
| 2073 | int cstr_size = 0; |
| 2074 | int str_size = 0; |
| 2075 | |
| 2076 | /* HANDLE BOM (Byte Order Mark) */ |
| 2077 | if (p_len < 0 || p_len >= 3) |
| 2078 | { |
| 2079 | bool has_bom = uint8_t(p_utf8[0]) == 0xef && uint8_t(p_utf8[1]) == 0xbb && uint8_t(p_utf8[2]) == 0xbf; |
| 2080 | if (has_bom) |
| 2081 | { |
| 2082 | // 8-bit encoding, byte order has no meaning in UTF-8, just skip it |
| 2083 | if (p_len >= 0) |
| 2084 | { |
| 2085 | p_len -= 3; |
| 2086 | } |
| 2087 | p_utf8 += 3; |
| 2088 | } |
| 2089 | } |
| 2090 | |
| 2091 | bool decode_error = false; |
| 2092 | bool decode_failed = false; |
| 2093 | { |
| 2094 | const char* ptrtmp = p_utf8; |
| 2095 | const char* ptrtmp_limit = &p_utf8[p_len]; |
| 2096 | int skip = 0; |
| 2097 | uint8_t c_start = 0; |
| 2098 | while (ptrtmp != ptrtmp_limit && *ptrtmp) |
| 2099 | { |
| 2100 | uint8_t c = *ptrtmp >= 0 ? *ptrtmp : uint8_t(256 + *ptrtmp); |
| 2101 | |
| 2102 | if (skip == 0) |
| 2103 | { |
| 2104 | if (p_skip_cr && c == '\r') |
| 2105 | { |
| 2106 | ptrtmp++; |
| 2107 | continue; |
| 2108 | } |
| 2109 | /* Determine the number of characters in sequence */ |
| 2110 | if ((c & 0x80) == 0) |
| 2111 | { |
| 2112 | skip = 0; |
| 2113 | } |
| 2114 | else if ((c & 0xe0) == 0xc0) |
| 2115 | { |
| 2116 | skip = 1; |
| 2117 | } |
| 2118 | else if ((c & 0xf0) == 0xe0) |
| 2119 | { |
| 2120 | skip = 2; |
| 2121 | } |