/* Copyright (C) 2025 Aryadev Chavali * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License Version 2 for * details. * You may distribute and modify this code under the terms of the GNU General * Public License Version 2, which you should have received a copy of along with * this program. If not, please go to . * Created: 2025-04-14 * Description: String View implementation */ #include #include #include #include #include sv_t sv_make(arena_t *allocator, const char *data, u64 size) { sv_t s = {0}; if (data) s = sv_append(allocator, s, data, size); else { s.data = arena_alloc(allocator, size); s.size = size; } return s; } sv_t sv_copy(arena_t *allocator, sv_t sv) { return sv_make(allocator, sv.data, sv.size); } sv_t sv_substr(sv_t sv, u64 index, u64 size) { sv_t newsv = {0}; if (index + size > sv.size) return newsv; newsv.data = sv.data + index; newsv.size = size; return newsv; } sv_t sv_cut(sv_t sv, u64 index) { return sv_substr(sv, index, sv.size < index ? 0 : sv.size - index); } sv_t sv_chop(sv_t sv, u64 size) { return sv_substr(sv, 0, size); } sv_t sv_concat(arena_t *allocator, sv_t a, sv_t b) { sv_t c = sv_make(allocator, NULL, a.size + b.size); memcpy(c.data, a.data, a.size); memcpy(c.data + a.size, b.data, b.size); return c; } sv_t sv_append(arena_t *allocator, sv_t sv, const char *data, u64 size) { if (!allocator) return (sv_t){0}; sv_t newsv = {0}; newsv.size = sv.size + size; newsv.data = arena_realloc(allocator, sv.data, sv.size, newsv.size); if (data) memcpy(newsv.data + sv.size, data, size); return newsv; } sv_t sv_prepend(arena_t *allocator, sv_t sv, const char *data, u64 size) { if (!allocator) return (sv_t){0}; // TODO: Can we make this cheaper to do? sv_t newsv = sv_make(allocator, NULL, size + sv.size); // Copy over `data` to the left side memcpy(newsv.data, data, size); // Copy old string to the right side if (sv.data) memcpy(newsv.data + size, sv.data, sv.size); return newsv; } sv_t sv_fmt(arena_t *allocator, char *fmt, ...) { if (!allocator) return (sv_t){0}; va_list ap_1, ap_2; va_start(ap_1, fmt); va_copy(ap_2, ap_1); u64 size = vsnprintf(NULL, 0, fmt, ap_2); va_end(ap_2); sv_t sv = sv_make(allocator, NULL, size); vsprintf(sv.data, fmt, ap_1); va_end(ap_1); return sv; } i64 sv_find_substr(const sv_t sv, const sv_t substr) { if (substr.size == 0) return 0; else if (sv.size < substr.size) return -1; else if (sv.size == substr.size) return strncmp(sv.data, substr.data, sv.size) == 0 ? 0 : -1; for (u64 i = 0; i < (sv.size - substr.size); ++i) if (strncmp(sv.data + i, substr.data, substr.size) == 0) return i; return -1; } i64 sv_find_subcstr(const sv_t sv, const char *substr, u64 size) { return sv_find_substr(sv, SV((char *)substr, size)); } i64 sv_find_any(const sv_t sv, const char *bag) { for (u64 i = 0; i < sv.size; ++i) if (strchr(bag, sv.data[i])) return i; return -1; } u64 sv_while(const sv_t sv, bool (*pred)(char)) { u64 i; for (i = 0; i < sv.size && pred(sv.data[i]); ++i) continue; return i; } u64 sv_till(const sv_t sv, bool (*pred)(char)) { u64 i; for (i = 0; i < sv.size && !pred(sv.data[i]); ++i) continue; return i; }