Files
c-programming/c/stringview/stringv.c
T
2026-11-14 20:11:26 -03:00

152 lines
3.4 KiB
C

#include "stringv.h"
#include <ctype.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
/*
* @brief Create a string view from a const char* and set their length
*
* @details This string view provides a view of a string. It does not allocate
* memory, therefore, it lives only while the source is alive. The
* length is a bytes number of the string. It does not represents the number of
* characters.
*
* @param str pointer from the original string. It can be NULL.
*
* @return a StringView with the view of original string with corresponding
* length.
*/
StringView sv_from_cstr(const char *str) {
if (str == NULL) {
return SV_NULL;
}
return (StringView){.text = (char *)str, .length = strlen(str)};
}
void sv_left(StringView *sv, size_t l) {
if (sv == NULL) {
return;
}
if (sv->text == NULL) {
return;
}
if (sv->length < l) {
return;
}
sv->length = l;
}
void sv_right(StringView *sv, size_t r) {
if (sv == NULL) {
return;
}
if (sv->text == NULL) {
return;
}
if (sv->length < r) {
return;
}
size_t nlength = sv->length - r;
sv->text = sv->text + nlength;
sv->length = r;
}
void sv_ltrim(StringView *sv) {
if (sv == NULL)
return;
if (sv->length == 0)
return;
if (sv->text == NULL)
return;
size_t offset = 0;
while (offset < sv->length && isspace((int)*(sv->text + offset))) {
offset++;
}
if (offset > sv->length)
return;
sv->text += offset;
sv->length -= offset;
}
void sv_rtrim(StringView *sv) {
if (sv == NULL)
return;
if (sv->length == 0)
return;
if (sv->text == NULL)
return;
size_t offset = 0;
while (offset < sv->length &&
isspace((int)*(sv->text + sv->length - 1 - offset))) {
offset++;
}
if (offset > sv->length)
return;
sv->length -= offset;
}
void sv_trim(StringView *sv) {
sv_ltrim(sv);
sv_rtrim(sv);
}
int sv_index_of(StringView sv, char c) {
size_t offset = 0;
while (offset < sv.length && *(sv.text + offset) != c) {
offset++;
}
if (offset > sv.length)
return -1;
return offset;
}
StringView sv_chop_by_delim(StringView *sv, char delim) {
StringView returnsv = SV_NULL;
int find = sv_index_of(*sv, delim);
if (!find) {
return returnsv;
}
returnsv.text = sv->text;
returnsv.length = find;
sv->text += find + 1;
sv->length = sv->length - find;
return returnsv;
}
bool sv_equals(StringView *sv1, StringView *sv2) {
if (sv1 == NULL)
return false;
if (sv2 == NULL)
return false;
if (sv1->text == NULL)
return false;
if (sv2->text == NULL)
return false;
if (sv1->length != sv2->length)
return false;
return memcmp(sv1->text, sv2->text, sv1->length) == 0;
}
bool sv_starts_with(StringView *sv, StringView *prefix) {
if (sv->length < prefix->length)
return false;
StringView cut = {.text = sv->text, .length = prefix->length};
return sv_equals(&cut, prefix);
}
bool sv_ends_with(StringView *sv, StringView *suffix) {
if (sv->length < suffix->length)
return false;
StringView cut = {.text = sv->text, .length = sv->length};
sv_right(&cut, suffix->length);
return sv_equals(&cut, suffix);
}