#include #include #include char* c_StringView_ToCStr(const c_StringView_t* self, char* buf, c_size_t buf_size) { // 边界防御:缓冲区必须有效且大小至少为 1(以便容纳 \0) if (!buf || buf_size == 0) { return NULL; } // 边界防御:如果 self 为空或底层无数据,直接赋予空字符串并返回 if (!self || self->size == 0 || !self->str) { buf[0] = '\0'; return buf; } // 计算实际能够安全拷贝的数据字节数(预留 1 字节给 '\0') c_size_t max_copy = buf_size - 1; c_size_t actual_copy = (self->size < max_copy) ? self->size : max_copy; // 执行内存拷贝(允许中间包含 \0 字符的特殊视图) if (actual_copy > 0) { memcpy(buf, self->str, actual_copy); } // 在缓冲区末尾强行补上标准传统 C 字符串的结束符 buf[actual_copy] = '\0'; return buf; } unsigned long c_StringView_ToUL(const c_StringView_t* self, const char** endptr, int base) { if (!self || self->size == 0 || !self->str) { if (endptr) *endptr = (self ? self->str : NULL); return 0; } const char* start = self->str; const char* end = self->str + self->size; // 1. 跳过前导空白字符 while (start < end && isspace((unsigned char)*start)) { start++; } // 如果全是空格,直接返回 0 if (start >= end) { if (endptr) *endptr = self->str; return 0; } // 2. 处理正负号 (虽然是无符号转码,标准 strtoul 仍允许 '-' 号并对其求补码) int negate = 0; if (*start == '+') { start++; } else if (*start == '-') { negate = 1; start++; } // 3. 自动识别进制 (Base == 0) 或校验 16 进制前缀 if (base == 0) { if ((c_size_t)(end - start) >= 2 && *start == '0' && (start[1] == 'x' || start[1] == 'X')) { base = 16; start += 2; } else if (start < end && *start == '0') { base = 8; start++; } else { base = 10; } } else if (base == 16) { // 如果显式指定了16进制,允许略过 0x/0X 前缀 if ((c_size_t)(end - start) >= 2 && *start == '0' && (start[1] == 'x' || start[1] == 'X')) { start += 2; } } unsigned long result = 0; unsigned long cutoff = ULONG_MAX / (unsigned long)base; int cutlim = ULONG_MAX % (unsigned long)base; int any_digits = 0; int overflow = 0; // 4. 核心解析循环,严格受限于底层 View 的 End 边界 while (start < end) { unsigned char c = (unsigned char)*start; int digit; if (isdigit(c)) { digit = c - '0'; } else if (isalpha(c)) { digit = tolower(c) - 'a' + 10; } else { break; // 遇到非法字符,退出解析 } if (digit >= base) { break; // 超过当前进制最大范围,退出解析 } any_digits = 1; // 检查溢出 if (overflow || result > cutoff || (result == cutoff && digit > cutlim)) { overflow = 1; } else { result = result * (unsigned long)base + (unsigned long)digit; } start++; } // 5. 组装返回值与写回结束指针 if (endptr) { *endptr = any_digits ? start : self->str; } if (overflow) { return ULONG_MAX; } return negate ? (unsigned long)(-(long)result) : result; } double c_StringView_ToDouble(const c_StringView_t* self, const char** endptr) { if (!self || self->size == 0 || !self->str) { if (endptr) *endptr = (self ? self->str : NULL); return 0.0; } // 1. 跳过前导空白字符 const char* start = self->str; const char* end = self->str + self->size; while (start < end && isspace((unsigned char)*start)) { start++; } // 计算实际可能包含有效浮点数据的长度 size_t active_len = end - start; if (active_len == 0) { if (endptr) *endptr = self->str; return 0.0; } // 2. 核心避坑:由于 strtod 需要 \0 结尾,但 StringView 并没有。 // 我们在栈上开辟一个小缓冲区(256字节足够容纳任何有效的 IEEE 754 浮点数字符串,包括极其冗长的科学计数法)。 // 这避免了 malloc 带来的堆内存分配开销,同时保证了线程安全。 char local_buf[256]; size_t copy_len = (active_len < sizeof(local_buf) - 1) ? active_len : (sizeof(local_buf) - 1); memcpy(local_buf, start, copy_len); local_buf[copy_len] = '\0'; // 3. 调用标准库进行高精度解析(能完美处理 NaN、Inf 以及复杂的科学计数法扩展) char* local_endptr = NULL; double result = strtod(local_buf, &local_endptr); // 4. 将本地缓冲区的相对终止偏移量映射回原始的 StringView 真实指针 if (endptr) { if (local_endptr == local_buf) { // 如果 strtod 完全未能识别出任何数字 *endptr = self->str; } else { ptrdiff_t parsed_offset = local_endptr - local_buf; *endptr = start + parsed_offset; } } return result; } c_index_t c_StringView_FindStr(const c_StringView_t* self, const c_size_t start_pos, const c_StringView_t* needle) { // 1. 边界与有效性防御 if (!self || !self->str || !needle || !needle->str) { return -1; } // 子串为空时,根据标准 C/C++ 行为,默认在有效起点处直接匹配成功 if (needle->size == 0) { return (start_pos <= self->size) ? (c_index_t)start_pos : -1; } // 起始位置越界,或者子串长度已经超过了可供查找的剩余主串长度 if (start_pos >= self->size || (self->size - start_pos) < needle->size) { return -1; } // 2. 核心搜索算法:在主串死边界内进行滑窗 memcmp 匹配 c_size_t max_search_idx = self->size - needle->size; c_size_t needle_len = needle->size; const char* haystack = self->str; for (c_size_t i = start_pos; i <= max_search_idx; i++) { // 第一步快筛:首字符匹配时再执行深度 memcmp,极大提升非匹配时滑窗的执行效率 if (haystack[i] == needle->str[0]) { if (memcmp(haystack + i, needle->str, needle_len) == 0) { return (c_index_t)i; // 找到匹配,返回主串对应下标 } } } return -1; // 遍历完毕,未找到匹配项 }