#ifndef __SMCC_CORE_STR_H__ #define __SMCC_CORE_STR_H__ #include "core_impl.h" #include "core_log.h" #include "core_type.h" /** * @brief 动态字符串结构体 * @attention 创建的字符串对象需要使用 cstring_free 释放 */ typedef struct cstring { usize size; /**< 字符串当前大小(包括结尾的'\0')*/ usize cap; /**< 分配的容量 */ char *data; /**< 实际存储数据的指针 */ } cstring_t; /** * @brief 创建一个新的空动态字符串对象 * * @return cstring_t 初始化后的对象 */ static inline cstring_t cstring_new(void) { return (cstring_t){.data = null, .size = 0, .cap = 0}; } /** * @brief 从 C 风格字符串创建一个动态字符串副本 * * @param s 输入的 C 风格字符串 * @return cstring_t 新建对象,包含输入字符串的副本 */ static inline cstring_t cstring_from_cstr(const char *s) { if (s == null) { return cstring_new(); } usize len = 0; const char *p = s; while (*p++) len++; char *data = (char *)smcc_malloc(len + 1); Assert(data != null); smcc_memcpy(data, s, len); data[len] = '\0'; return (cstring_t){.size = len + 1, .cap = len + 1, .data = data}; } /** * @brief 释放动态字符串占用的内存资源 * * @param str 要被释放的字符串指针 */ static inline void cstring_free(cstring_t *str) { if (str == null) { return; } if (str->cap != 0 && str->data != null) { smcc_free(str->data); str->data = null; } str->size = 0; str->cap = 0; } /** * @brief 向动态字符串末尾追加一段 C 风格字符串 * * @param str 目标动态字符串指针 * @param data 要追加的 C 字符串指针 * @param len 要追加的 C 字符串长度 */ static inline void cstring_append_cstr(cstring_t *str, const char *data, usize len) { if (str == null || data == null || len == 0) { return; } if (str->cap == 0) { // add '\0' to str str->size = 1; } // 如果需要扩容 if (str->size + len > str->cap) { usize new_cap = str->cap; while (new_cap < str->size + len) { if (new_cap == 0) { new_cap = str->size + len; break; } else { new_cap *= 2; } // FIXME 处理溢出情况 } char *new_data = (char *)smcc_realloc(str->data, new_cap); Assert(new_data != null); str->data = new_data; str->cap = new_cap; } smcc_memcpy(str->data + str->size - 1, data, len); str->size += len; str->data[str->size - 1] = '\0'; // 保证 C 字符串兼容性 } /** * @brief 向动态字符串末尾追加另一个动态字符串 * * @param str 目标动态字符串指针 * @param other 要追加的动态字符串指针 */ static inline void cstring_append(cstring_t *str, const cstring_t *other) { cstring_append_cstr(str, other->data, other->size - 1); } /** * @brief 向动态字符串末尾追加一个字符 * * @param str 目标动态字符串指针 * @param ch 要追加的字符 */ static inline void cstring_append_ch(cstring_t *str, char ch) { cstring_append_cstr(str, &ch, 1); } /** * @brief 获取动态字符串的实际内容长度 不包括结尾的'\0' * * @param str 动态字符串指针 * @return usize 字符串实际长度 */ static inline usize cstring_len(const cstring_t *str) { return str ? str->size - 1 : 0; } /** * @brief 判断动态字符串是否为空 * * @param str 动态字符串指针 * @return cbool */ static inline cbool cstring_is_empty(const cstring_t *str) { return str == null || str->size == 0; } /** * @brief 清空动态字符串内容但保留已分配的内存空间 * * @param str 动态字符串指针 */ static inline void cstring_clear(cstring_t *str) { if (str) { str->size = 1; if (str->data) { str->data[0] = '\0'; } } } /** * @brief 将动态字符串转换为 C 风格字符串 * * @param str 动态字符串指针 * @return char* 返回指向内部缓冲区的 C 风格字符串指针 */ static inline char *cstring_as_cstr(const cstring_t *str) { if (str == null || str->data == null) { return ""; } return str->data; } #endif /* __SMCC_CORE_STR_H__ */