#ifndef GBK_ENCODING_H #define GBK_ENCODING_H #include #include #include "gbk_map.h" // 引入映射表 #include #define GBK_UTIL_TAG "GBK_ENCODING" #ifdef __cplusplus extern "C" { #endif /** * @brief 将GBK编码转换为UTF-8编码 * * @param gbk_str 输入的GBK编码字符串 * @param utf8_buf 输出的UTF-8字符串缓冲区 * @param buf_size 缓冲区大小 * @return size_t 转换后的字符串长度,如果失败则返回0 */ size_t gbk_to_utf8(const char* gbk_str, char* utf8_buf, size_t buf_size); /** * @brief 获取转换GBK到UTF-8所需的缓冲区大小 * * @param gbk_str 输入的GBK编码字符串 * @return size_t 所需的UTF-8缓冲区大小 */ size_t gbk_to_utf8_buffer_size(const char* gbk_str); /** * @brief 将GBK编码转换为UTF-8编码,并分配新内存 * * @param gbk_str 输入的GBK编码字符串 * @return char* 新分配的UTF-8字符串,使用后需要free */ char* gbk_to_utf8_alloc(const char* gbk_str); /** * @brief 初始化GBK编码转换表 * 这个函数会加载编码转换表到内存中 */ void gbk_encoding_init(void); // GBK到Unicode的映射表 static const uint16_t gbk_to_unicode_map[] = { 0x4E02, 0x4E04, 0x4E05, 0x4E06, 0x4E0F, 0x4E12, 0x4E17, 0x4E1F, // ... 这里是完整的映射表 }; // GBK到Unicode的转换函数 static inline uint16_t gbk_to_unicode(uint8_t ch, uint8_t cl) { if (ch <= 0x7F) { return ch; // ASCII字符 } // GBK区域判断 if (ch >= 0x81 && ch <= 0xFE) { if (cl >= 0x40 && cl <= 0x7E || cl >= 0x80 && cl <= 0xFE) { uint32_t gbk = (ch << 8) | cl; // GBK-1区域 (0xB0A1-0xF7FE) if (gbk >= 0xB0A1 && gbk <= 0xF7FE) { uint32_t offset = ((ch - 0xB0) * 94 + (cl - 0xA1)); return 0x4E00 + offset; // 基本汉字区 } // GBK-2区域 (0x8140-0xA0FE) if (gbk >= 0x8140 && gbk <= 0xA0FE) { uint32_t offset = ((ch - 0x81) * 190 + (cl - (cl >= 0x80 ? 0x41 : 0x40))); return 0x3000 + offset; // 符号区 } // GBK-3区域 (0xAA40-0xFEA0) if (gbk >= 0xAA40 && gbk <= 0xFEA0) { uint32_t offset = ((ch - 0xAA) * 96 + (cl - 0x40)); return 0x4E00 + 6768 + offset; // 扩展汉字区 } } } ESP_LOGW(GBK_UTIL_TAG, "未找到映射的GBK编码: 0x%04X [高字节:0x%02X, 低字节:0x%02X]", (ch << 8) | cl, ch, cl); return 0x3F; // 返回'?'的Unicode编码 } // Unicode到UTF-8的转换函数 static inline int unicode_to_utf8(uint16_t uni, uint8_t *utf8) { if (uni <= 0x7F) { utf8[0] = (uint8_t)uni; return 1; } else if (uni <= 0x7FF) { utf8[0] = 0xC0 | ((uni >> 6) & 0x1F); utf8[1] = 0x80 | (uni & 0x3F); return 2; } else { utf8[0] = 0xE0 | ((uni >> 12) & 0x0F); utf8[1] = 0x80 | ((uni >> 6) & 0x3F); utf8[2] = 0x80 | (uni & 0x3F); return 3; } } // GBK到UTF-8的转换函数 static inline int gbk_to_utf8(const char* gbk, char* utf8, int len) { int utf8_len = 0; for (int i = 0; i < len;) { uint8_t ch = (uint8_t)gbk[i]; if (ch <= 0x7F) { // ASCII字符 utf8[utf8_len++] = ch; i++; } else { // GBK字符 if (i + 1 >= len) break; uint8_t cl = (uint8_t)gbk[i + 1]; uint16_t unicode = gbk_to_unicode(ch, cl); utf8_len += unicode_to_utf8(unicode, (uint8_t*)&utf8[utf8_len]); i += 2; } } utf8[utf8_len] = '\0'; return utf8_len; } // 处理文件名的函数 static inline void process_filename(const char* filename, char* utf8_filename, int max_len) { gbk_to_utf8(filename, utf8_filename, strlen(filename)); } #ifdef __cplusplus } #endif #endif /* GBK_ENCODING_H */