Files
cAI/cKit/Foundation/c_utf8.h
T
pchen e6a29bcdfd c_NlpCharGraph: 分析一篇文章,建立字与字的关系
c_NlpNgramGraph: 基于 n 个已经出现的词,预估后续可能出现的词
c_NlpLanguageModel: 如果有的词组合形式没有出现过,找到之前学习过最长类似的词句进行预测
2026-08-10 03:12:45 +08:00

242 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef INCLUDED_C_UTF8_H
#define INCLUDED_C_UTF8_H
#ifndef INCLUDED_C_BASE_H
#include <c_Base.h>
#endif /*INCLUDED_C_BASE_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*/