c++ utf8 和 utf16 转换

需求 有一个 xml 文件,是 utf16-be 格式的,直接使用 firefox 打开不对,所以考虑先转码为 utf8 然后再打开。 解决 int Utf16leToUtf8(uint8_t* dest, int dest_size, int* dest_len, uint16_t* src, int src_len) { uint8_t* dest_start = dest; uint8_t* dest_end = dest + dest_size; //uint16_t* src_end = (uint16_t*)((uint8_t*)src + src_len); uint16_t* src_end = src + src_len; while (src < src_end) { if (*src < UTF16_2 && dest + 1 < dest_end) { //0000 - 007F : 0xxxxxxx *dest++ = (uint8_t)*src; } else if(*src >= UTF16_2 && *src < UTF16_3 && dest + 2 < dest_end) { //0080 - 07FF : 110xxxxx 10xxxxxx *dest++ = ((*src >> 6) & 0x1F) | 0xC0; *dest++ = (*src & 0x3F) | 0x80; } else if(*src >= UTF16_3 && *src < UTF16_4 && dest + 3 < dest_end) { //0800 - FFFF : 1110xxxx 10xxxxxx 10xxxxxx *dest++ = ((*src >> 12) & 0x0F) | 0xE0; *dest++ = ((*src >> 6) & 0x3F) | 0x80; *dest++ = (*src & 0x3F) | 0x80; } else if(*src >= UTF16_4 && *src < UTF16_4_SECOND && dest + 4 < dest_end) { // 代理项对部分(4字节表示) //0001 0000 - 001F FFFF : 1111 0xxx 10xxxxxx 10xxxxxx 10xxxxxx // 从代理项对到UNICODE代码点转换 // 1、从高代理项减去0xD800,获取有效10bit // 2、从低代理项减去0xDC00,获取有效10bit // 3、加上0x10000,获取UNICODE代码点值 uint16_t high_sur = *src++; uint16_t low_sur = *src; uint32_t code_point = high_sur - UTF16_4; code_point <<= 10; code_point |= low_sur - UTF16_4_SECOND; code_point += UTF16_4_PLUS; *dest++ = (code_point >> 18) | 0xF0; *dest++ = ((code_point >> 12) & 0x3F) | 0x80; *dest++ = ((code_point >> 06) & 0x3F) | 0x80; *dest++ = (code_point & 0x3F) | 0x80; } else { break; } src++; } *dest = 0; *dest_len = dest - dest_start; if (src < src_end) { return -1; } return 0; } int Utf16beToUtf8(uint8_t* dest, int dest_size, int* dest_len, uint16_t* src, int src_len) { uint16_t le[src_len]; union { uint16_t s; uint8_t buf[sizeof(uint16_t)]; } data; for (int i = 0; i < src_len; i++) { /* uint8_t * d = (uint8_t *)(src + i); uint8_t tmp = *d; *d = *(d + 1); *(d + 1) = tmp; */ data....

2023-04-10 · 2 min · 367 words · RamLife