Files
cKit/Foundation/c_StringBuffer.t.c
2026-08-30 03:52:23 +08:00

156 lines
6.7 KiB
C
Raw Permalink 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.
#include "c_StringBuffer.h"
#include "c_Test.h"
#include <stdlib.h>
#include <stdio.h>
// 模拟多态分配器的桩监控(用于审计自建内存池在频繁 Split 时的块变化)
static size_t g_str_pool_active_chunks = 0;
static void* mock_str_pool_alloc(size_t size, void* ctx) {
(void)ctx; g_str_pool_active_chunks++; return malloc(size);
}
static void mock_str_pool_free(void* ptr, void* ctx) {
(void)ctx; if (ptr) g_str_pool_active_chunks--; free(ptr);
}
// 模拟的伪 realloc 桥接(桩实现)
static void* mock_str_pool_realloc(void* ptr, size_t old_size, size_t new_size, void* ctx) {
(void)ctx; (void)old_size;
return realloc(ptr, new_size);
}
TEST_CASE(test_string_buffer_ultimate_matrix_flow) {
g_str_pool_active_chunks = 0;
// 1. 初始化多态自治内存池(模拟伙伴系统或 Arena 物理底座)
c_Allocator_t str_pool = {
.alloc = mock_str_pool_alloc,
.realloc = mock_str_pool_realloc,
.free = mock_str_pool_free,
.dtor = NULL,
.ud = NULL
};
c_StringBuffer_t sb;
// 初始有效容量设为 4(底层物理分配 5 字节含 \0 预留位)
ASSERT_INT_EQ(C_ERR_OK, c_StringBuffer_Init(&sb, 4, &str_pool));
ASSERT_INT_EQ(0, (int)c_StringBuffer_Size(&sb));
ASSERT_INT_EQ(1, (int)g_str_pool_active_chunks);
ASSERT_TRUE(strcmp(c_StringBuffer_CStr(&sb), "") == 0); // 初始应为空串
// 2. 验证常规追加、前缀插入及重叠区域随机增删( memmove 移位安全)
ASSERT_INT_EQ(C_ERR_OK, c_StringBuffer_AppendStr(&sb, "WORLD"));
ASSERT_INT_EQ(C_ERR_OK, c_StringBuffer_PrependStr(&sb, "HELLO_")); // 此时: "HELLO_WORLD"
ASSERT_INT_EQ(11, (int)c_StringBuffer_Size(&sb));
ASSERT_TRUE(c_StringBuffer_Equals(&sb, "HELLO_WORLD"));
// 随机位置定点插入
ASSERT_INT_EQ(C_ERR_OK, c_StringBuffer_InsertStrAt(&sb, "MY_", 6)); // 此时: "HELLO_MY_WORLD"
ASSERT_TRUE(c_StringBuffer_Equals(&sb, "HELLO_MY_WORLD"));
// 随机位置定点删除
ASSERT_INT_EQ(C_ERR_OK, c_StringBuffer_RemoveAt(&sb, 5, 4)); // 移去 "_MY_",此时: "HELLOWORLD"
ASSERT_TRUE(c_StringBuffer_Equals(&sb, "HELLOWORLD"));
// 3. 验证试探型双向写入 Printf 格式化接口
ASSERT_INT_EQ(C_ERR_OK, c_StringBuffer_PrintfAt(&sb, 5, "NEW_%s", "BUFFER")); // 此时: "HELLONEW_BUFFER"
ASSERT_TRUE(c_StringBuffer_Equals(&sb, "HELLONEW_BUFFERWORLD"));
// 4. 验证高速特征指纹匹配(IndexOf / LastIndexOf
c_StringBuffer_Clear(&sb);
c_StringBuffer_AppendStr(&sb, "TOKEN_A_TOKEN_B_TOKEN_A");
c_index_t idx_first = c_StringBuffer_IndexOfStr(&sb, 0, "TOKEN_A");
c_index_t idx_last = c_StringBuffer_LastIndexOfStr(&sb, sb.size, "TOKEN_A");
ASSERT_INT_EQ(0, (int)idx_first);
ASSERT_INT_EQ(16, (int)idx_last); // 尾部反向查找成功
ASSERT_INT_EQ(5, (int)c_StringBuffer_IndexOfChar(&sb, 0, '_'));
// 全词全局高效替换
ASSERT_INT_EQ(C_ERR_OK, c_StringBuffer_ReplaceStr(&sb, "TOKEN_A", "KEY")); // 此时: "KEY_TOKEN_B_KEY"
ASSERT_TRUE(c_StringBuffer_Equals(&sb, "KEY_TOKEN_B_KEY"));
// 5. 验证全词高级文本规整(Trim家族)与大小写强转
c_StringBuffer_Clear(&sb);
c_StringBuffer_AppendStr(&sb, " \t DATA_LOG \r\n ");
ASSERT_INT_EQ(C_ERR_OK, c_StringBuffer_Trim(&sb));
ASSERT_TRUE(c_StringBuffer_Equals(&sb, "DATA_LOG"));
c_StringBuffer_ToLower(&sb);
ASSERT_TRUE(c_StringBuffer_Equals(&sb, "data_log"));
c_StringBuffer_ToUpper(&sb);
ASSERT_TRUE(c_StringBuffer_Equals(&sb, "DATA_LOG"));
// 6. 【核心大演进】:高能分包(Split)与重新粘合(Join)机制闭环审计
c_StringBuffer_Clear(&sb);
c_StringBuffer_AppendStr(&sb, "Linux;RTOS;FreeRTOS;BareMetal");
c_StringBuffer_t* tokens = NULL;
c_size_t token_count = 0;
// 执行精准多态切片拆分
c_err_t split_err = c_StringBuffer_Split(&sb, ";", &tokens, &token_count);
ASSERT_INT_EQ(C_ERR_OK, split_err);
ASSERT_INT_EQ(4, (int)token_count); // 必须切出 4 个 Token
// 校验切片内容的值复制隔离性及内嵌分配器继承血脉
ASSERT_TRUE(c_StringBuffer_Equals(&tokens[0], "Linux"));
ASSERT_TRUE(c_StringBuffer_Equals(&tokens[3], "BareMetal"));
// 将切片利用 Join 重新粘合为一个以逗号 "," 隔开的全新大串
c_StringBuffer_t joined_sb;
c_StringBuffer_Init(&joined_sb, 32, &str_pool);
ASSERT_INT_EQ(C_ERR_OK, c_StringBuffer_Join(&joined_sb, tokens, token_count, ","));
ASSERT_TRUE(c_StringBuffer_Equals(&joined_sb, "Linux,RTOS,FreeRTOS,BareMetal"));
// 深度火化销毁切片资源沙盒
for (c_size_t i = 0; i < token_count; i++) {
c_StringBuffer_Destroy(&tokens[i]);
}
c_Allocator_Free(&str_pool, tokens);
// 7. 验证高级文本有限状态机数值解析提取 (strtoul 闭环重塑)
c_StringBuffer_Clear(&sb);
c_StringBuffer_AppendStr(&sb, " -0x7FFFFFFF_PADDING_DATA");
unsigned long parsed_numeric = 0;
c_size_t end_parse_index = 0;
c_err_t s2u_err = c_StringBuffer_strtoul(&sb, 0, 0, &parsed_numeric, &end_parse_index);
ASSERT_INT_EQ(C_ERR_OK, s2u_err);
// 0x7FFFFFFF 在取负后以补码形式转换为无符号形式
ASSERT_TRUE(parsed_numeric == (unsigned long)(-0x7FFFFFFF));
ASSERT_INT_EQ(14, (int)end_parse_index); // 精准停留在第一个非合法十六进制字符下划线 '_' 处
// 8. 验证契约容量扩容与零填充(SetLength)
c_StringBuffer_Clear(&sb);
c_StringBuffer_AppendStr(&sb, "XYZ");
ASSERT_INT_EQ(C_ERR_OK, c_StringBuffer_SetLength(&sb, 55)); // 扩容并对齐零填充
ASSERT_INT_EQ(55, (int)c_StringBuffer_Size(&sb));
ASSERT_INT_EQ('\0', sb.buffer[3]); // 确认空白区域零填充就位
ASSERT_INT_EQ('\0', sb.buffer[5]); // 确认隐式尾部安全封底
// 9. 验证子串与切片深度抽取复制(Substr / Slice
c_StringBuffer_t slice_out;
ASSERT_INT_EQ(C_ERR_OK, c_StringBuffer_Slice(&joined_sb, 6, 10, &slice_out)); // 截取 "RTOS"
ASSERT_TRUE(c_StringBuffer_Equals(&slice_out, "RTOS"));
// 彻底解体火化释放所有资源
c_StringBuffer_Destroy(&sb);
c_StringBuffer_Destroy(&joined_sb);
c_StringBuffer_Destroy(&slice_out);
// 终极一致性内存池大审判:全量大缓冲区底座、切片原子核卸载,分配块必须完美清算归零!
ASSERT_INT_EQ_MSG(0, (int)g_str_pool_active_chunks, "CRITICAL: c_StringBuffer_t leaked heap space inside the dynamic allocator pool!");
}
int main(void) {
printf("\n");
TEST_START(C_StringBuffer_Ultimate_Matrix_Tests);
// 驱动高防御动态字符串缓冲区全 API 功能流验证
RUN_TEST(test_string_buffer_ultimate_matrix_flow);
TEST_REPORT();
RETURN_TEST_STATUS;
}