重构
This commit is contained in:
@@ -1,242 +0,0 @@
|
||||
#ifndef INCLUDED_C_UTF8_H
|
||||
#define INCLUDED_C_UTF8_H
|
||||
|
||||
#ifndef INCLUDED_C_TYPES_H
|
||||
#include <c_Types.h>
|
||||
#endif /*INCLUDED_C_TYPES_H*/
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
#ifndef C_UNICODE_MAX
|
||||
#define C_UNICODE_MAX 0x10FFFFU
|
||||
#endif
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
/* --- Unicode Codepoint Type Definition --- */
|
||||
typedef uint32_t c_ucs4_t; // UCS-4 / UTF-32 representation for a single Unicode Codepoint
|
||||
typedef uint16_t c_uint16_t;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
C_STATIC_FORCE_INLINE
|
||||
bool c_is_valid_unicode(uint32_t code) {
|
||||
// Unicode 码点不能超过 0x10FFFF,且必须排除 UTF-16 代理对范围 (0xD800 ~ 0xDFFF)
|
||||
if (code > C_UNICODE_MAX) return false;
|
||||
if (code >= 0xD800 && code <= 0xDFFF) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取一个 UTF-8 字符在当前指针位置所占用的实际字节数 (1 ~ 4 字节)
|
||||
*/
|
||||
C_STATIC_FORCE_INLINE c_size_t c_utf8_char_len(char leading_byte) {
|
||||
unsigned char b = (unsigned char)leading_byte;
|
||||
if (b < 0x80) return 1; // 单字节 ASCII: 0xxxxxxx
|
||||
if ((b & 0xE0) == 0xC0) return 2; // 双字节字符: 110xxxxx
|
||||
if ((b & 0xF0) == 0xE0) return 3; // 三字节字符(大部分汉字): 1110xxxx
|
||||
if ((b & 0xF8) == 0xF0) return 4; // 四字节字符(Emoji等): 11110xxx
|
||||
return 1; // 非法 UTF-8 引导字节,防御性返回 1 防止死循环
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
/**
|
||||
* @brief 计算一个 UTF-8 字符串的有效字形数(字符数),而非字节数 (兼容 strlen)
|
||||
*/
|
||||
c_size_t c_utf8_strlen(const char* str);
|
||||
|
||||
/**
|
||||
* @brief 查找字符在 UTF-8 字符串中第一次出现的位置 (兼容 strchr)
|
||||
* @param str 源字符串
|
||||
* @param utf8_char 待查找的 UTF-8 字符(支持多字节字符,如 "中")
|
||||
* @return const char* 指向找到的第一个字节的指针,未找到返回 NULL
|
||||
*/
|
||||
const char* c_utf8_strchr(const char* str, const char* utf8_char);
|
||||
|
||||
/**
|
||||
* @brief 复制指定字形数量的 UTF-8 字符串 (兼容 strncpy)
|
||||
* @note 能够完美感知 UTF-8 字符边界,绝不会切断汉字,且自动在末尾补 '\0'
|
||||
* @param dest 目标缓冲区
|
||||
* @param src 源字符串
|
||||
* @param char_num 要复制的 UTF-8 字符/字形数量
|
||||
* @return char* 指向目标缓冲区 dest 的指针
|
||||
*/
|
||||
char* c_utf8_strncpy(char* dest, const char* src, c_size_t char_num);
|
||||
|
||||
/**
|
||||
* @brief 比较两个 UTF-8 字符串的前 n 个字符 (兼容 strncmp)
|
||||
* @param str1 字符串 1
|
||||
* @param str2 字符串 2
|
||||
* @param char_num 要比较的 UTF-8 字符/字形数量
|
||||
* @return int 小于 0、等于 0 或大于 0
|
||||
*/
|
||||
int c_utf8_strncmp(const char* str1, const char* str2, c_size_t char_num);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Converts a UTF-8 character string to lowercase in-place.
|
||||
* Supports standard ASCII case folding and common multi-byte scripts.
|
||||
* @param str Pointer to the mutable null-terminated UTF-8 string.
|
||||
* @return char* Pointer to the original string.
|
||||
*/
|
||||
char* c_utf8_tolower(char* str);
|
||||
|
||||
/**
|
||||
* @brief Converts a UTF-8 character string to uppercase in-place.
|
||||
* Supports standard ASCII case folding and common multi-byte scripts.
|
||||
* @param str Pointer to the mutable null-terminated UTF-8 string.
|
||||
* @return char* Pointer to the original string.
|
||||
*/
|
||||
char* c_utf8_toupper(char* str);
|
||||
|
||||
/**
|
||||
* @brief Appends the source UTF-8 string to the destination string buffer (Compatible with strcat).
|
||||
* @param dest Pointer to the null-terminated destination buffer.
|
||||
* @param src Pointer to the null-terminated source string.
|
||||
* @return char* Pointer to the destination string destination pointer.
|
||||
*/
|
||||
char* c_utf8_strcat(char* dest, const char* src);
|
||||
|
||||
/**
|
||||
* @brief Finds the first occurrence of a substring in a UTF-8 string (Compatible with strstr).
|
||||
* @param haystack The null-terminated UTF-8 string to scan.
|
||||
* @param needle The null-terminated UTF-8 substring to search for.
|
||||
* @return const char* Pointer to the first byte of the matched substring in haystack, or NULL if not found.
|
||||
*/
|
||||
const char* c_utf8_strstr(const char* haystack, const char* needle);
|
||||
|
||||
/**
|
||||
* @brief Finds the last occurrence of a specific character in a UTF-8 string (Compatible with strrchr).
|
||||
* @param str The null-terminated UTF-8 string to scan.
|
||||
* @param utf8_char The null-terminated UTF-8 character string to find (can be a multi-byte sequence like "中").
|
||||
* @return const char* Pointer to the last occurrence of the matched character in str, or NULL if not found.
|
||||
*/
|
||||
const char* c_utf8_strrchr(const char* str, const char* utf8_char);
|
||||
|
||||
/**
|
||||
* @brief Tokenizes a string into a series of tokens based on multiple multi-byte delimiters.
|
||||
* This function is thread-safe and reentrant, operating similarly to POSIX strtok_r.
|
||||
* @param str The mutable UTF-8 string to tokenize. Pass NULL on subsequent calls.
|
||||
* @param delims A raw byte sequence containing multi-byte UTF-8 delimiters.
|
||||
* @param saveptr A user-allocated tracking pointer to maintain state context across consecutive calls.
|
||||
* @return char* Pointer to the beginning of the next valid token, or NULL when no more tokens are found.
|
||||
*/
|
||||
char* c_utf8_strtok(char* str, const char* delims, char** saveptr);
|
||||
|
||||
/**
|
||||
* @brief Compares two UTF-8 strings case-insensitively up to a specified number of characters.
|
||||
* @param str1 Pointer to the first null-terminated UTF-8 string.
|
||||
* @param str2 Pointer to the second null-terminated UTF-8 string.
|
||||
* @param char_num Maximum number of UTF-8 characters (codepoints) to compare.
|
||||
* @return int An integer less than, equal to, or greater than zero if str1 is found,
|
||||
* respectively, to be less than, to match, or be greater than str2.
|
||||
*/
|
||||
int c_utf8_strncasecmp(const char* str1, const char* str2, c_size_t char_num);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
/**
|
||||
* @brief Converts the next UTF-8 byte sequence at a given pointer into a single Unicode Codepoint.
|
||||
* @param str Pointer to the current position in a null-terminated UTF-8 string.
|
||||
* @param out_codepoint Pointer to the destination where the decoded Unicode integer is saved.
|
||||
* @param out_bytes_consumed Pointer to save the number of source bytes processed (1 to 4).
|
||||
* @return c_err_t C_ERR_OK on success, or C_ERR_PARAM on invalid/corrupted UTF-8 byte streams.
|
||||
*/
|
||||
c_err_t c_utf8_to_unicode(const char* str, c_ucs4_t* out_codepoint, c_size_t* out_bytes_consumed);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Encodes a single Unicode Codepoint (UCS-4) into a destination UTF-8 byte array.
|
||||
* @param codepoint The source Unicode integer character point to encode.
|
||||
* @param dest_buffer Pointer to a char array buffer (must have at least 5 bytes capacity).
|
||||
* @param out_bytes_written Pointer to save the number of encoded bytes stored in dest_buffer.
|
||||
* @return c_err_t C_ERR_OK on success, or C_ERR_PARAM if the codepoint is out of valid Unicode ranges or parameters are NULL.
|
||||
*/
|
||||
c_err_t c_utf8_from_unicode(c_ucs4_t codepoint, char* dest_buffer, c_size_t* out_bytes_written);
|
||||
|
||||
/**
|
||||
* @brief Decodes an entire null-terminated UTF-8 string into an array of Unicode Codepoints.
|
||||
* @param str Pointer to the null-terminated source UTF-8 string.
|
||||
* @param dest_array Pointer to the destination array where decoded codepoints will be stored.
|
||||
* @param array_capacity Maximum number of elements that dest_array can hold.
|
||||
* @param out_chars_written Pointer to save the total number of codepoints successfully stored.
|
||||
* @return c_err_t C_ERR_OK on success, C_ERR_PARAM on invalid/NULL parameters or if the destination array capacity is exceeded.
|
||||
*/
|
||||
c_err_t c_utf8_to_unicode_array(const char* str, c_ucs4_t* dest_array, c_size_t array_capacity, c_size_t* out_chars_written);
|
||||
|
||||
/**
|
||||
* @brief Encodes an array of Unicode Codepoints back into a null-terminated UTF-8 byte stream.
|
||||
* @param src_array Pointer to the source array of Unicode codepoints.
|
||||
* @param src_array_len The number of codepoint elements inside src_array to process.
|
||||
* @param dest_buffer Pointer to the destination char buffer.
|
||||
* @param dest_capacity Maximum byte capacity of the destination buffer (including room for '\0').
|
||||
* @param out_bytes_written Pointer to save the total number of bytes written to dest_buffer (excluding '\0').
|
||||
* @return c_err_t C_ERR_OK on success, C_ERR_PARAM on invalid/NULL parameters or if dest_capacity is exceeded.
|
||||
*/
|
||||
c_err_t c_utf8_from_unicode_array(const c_ucs4_t* src_array, c_size_t src_array_len, char* dest_buffer, c_size_t dest_capacity, c_size_t* out_bytes_written);
|
||||
|
||||
/**
|
||||
* @brief Converts an entire null-terminated UTF-8 string into an array of UTF-16 code units.
|
||||
* @param str Pointer to the null-terminated source UTF-8 string.
|
||||
* @param dest_array Pointer to the destination array where UTF-16 code units will be stored.
|
||||
* @param array_capacity Maximum number of 16-bit elements that dest_array can hold.
|
||||
* @param out_units_written Pointer to save the total number of UTF-16 code units successfully stored (excluding terminal '\0').
|
||||
* @return c_err_t C_ERR_OK on success, C_ERR_PARAM on invalid/NULL parameters or if capacity is exceeded.
|
||||
*/
|
||||
c_err_t c_utf8_to_utf16(const char* str, c_uint16_t* dest_array, c_size_t array_capacity, c_size_t* out_units_written);
|
||||
|
||||
/**
|
||||
* @brief Converts an array of UTF-16 code units back into a null-terminated UTF-8 byte stream.
|
||||
* @param src_array Pointer to the source array of UTF-16 code units.
|
||||
* @param src_array_len The number of 16-bit elements inside src_array to process.
|
||||
* @param dest_buffer Pointer to the destination char buffer.
|
||||
* @param dest_capacity Maximum byte capacity of the destination buffer (including room for '\0').
|
||||
* @param out_bytes_written Pointer to save the total number of bytes written to dest_buffer (excluding '\0').
|
||||
* @return c_err_t C_ERR_OK on success, C_ERR_PARAM on invalid/NULL parameters, malformed surrogates, or if dest_capacity is exceeded.
|
||||
*/
|
||||
c_err_t c_utf8_from_utf16(const c_uint16_t* src_array, c_size_t src_array_len, char* dest_buffer, c_size_t dest_capacity, c_size_t* out_bytes_written);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
/**
|
||||
* @brief Swaps the byte order (endianness) of a UTF-16 string array in-place.
|
||||
* @param utf16_array Pointer to the source/destination array of UTF-16 code units.
|
||||
* @param length The number of 16-bit elements inside the array to process.
|
||||
* @return c_err_t C_ERR_OK on success, or C_ERR_PARAM if the array pointer is NULL.
|
||||
*/
|
||||
c_err_t c_utf16_swap_endian(c_uint16_t* utf16_array, c_size_t length);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Decodes a UTF-16 character stream starting at a given pointer into a single Unicode codepoint.
|
||||
* @param src_units Pointer to the current code unit position in a UTF-16 array.
|
||||
* @param src_capacity Remaining elements left available to read inside the source array.
|
||||
* @param out_codepoint Pointer to the destination where the decoded Unicode integer is saved.
|
||||
* @param out_units_read Pointer to save the number of 16-bit code units processed (1 for BMP, 2 for Surrogate Pairs).
|
||||
* @return c_err_t C_ERR_OK on success, or C_ERR_PARAM on malformed surrogate sequences or missing parameters.
|
||||
*/
|
||||
c_err_t c_utf16_to_unicode(const c_uint16_t* src_units, c_size_t src_capacity, c_ucs4_t* out_codepoint, c_size_t* out_units_read);
|
||||
|
||||
/**
|
||||
* @brief Encodes a single Unicode codepoint into a target UTF-16 array buffer.
|
||||
* @param codepoint The source Unicode integer character point to encode.
|
||||
* @param dest_units Pointer to the destination 16-bit code unit array buffer.
|
||||
* @param dest_capacity Maximum number of 16-bit elements the destination buffer can accept.
|
||||
* @param out_units_written Pointer to save the number of 16-bit code units generated (1 or 2).
|
||||
* @return c_err_t C_ERR_OK on success, or C_ERR_PARAM if the codepoint is invalid or destination space is insufficient.
|
||||
*/
|
||||
c_err_t c_utf16_from_unicode(c_ucs4_t codepoint, c_uint16_t* dest_units, c_size_t dest_capacity, c_size_t* out_units_written);
|
||||
|
||||
|
||||
|
||||
#endif /*INCLUDED_C_UTF8_H*/
|
||||
Reference in New Issue
Block a user