#include "stringv.h" #include #include #include #include #include /* * @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); }