Initial implementation
This commit is contained in:
158
sv.c
Normal file
158
sv.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/* 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
* Created: 2025-04-14
|
||||
* Description: String View implementation
|
||||
*/
|
||||
|
||||
#include "./sv.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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, a.data, a.size + b.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;
|
||||
}
|
||||
Reference in New Issue
Block a user