#include #include "malunal/types/strview.h" strview_t strview( malunal_cstr_t data, malunal_size_t length ) { return (strview_t) { .beg = data, .end = data + length }; } strview_t strview_from_cstr( malunal_cstr_t data ) { return data != null ? strview(data, strlen(data)) : strview(null, 0); } malunal_size_t strview_length( strview_iptr_t self ) { return self != null ? self->end - self->beg : 0; } malunal_void_t strview_ltrim( strview_mptr_t self, malunal_size_t count ) { malunal_size_t length = strview_length(self); if (length == 0) return; if (length < count) count = length; self->beg += count; } malunal_void_t strview_rtrim( strview_mptr_t self, malunal_size_t count ) { malunal_size_t length = strview_length(self); if (length == 0) return; if (length < count) count = length; self->end -= count; } strview_t strview_subview( strview_iptr_t self, malunal_size_t start, malunal_size_t count ) { if (self == null) return strview(null, 0); strview_t result = { self->beg, self->end }; strview_ltrim(&result, start); malunal_size_t length = strview_length(&result); strview_rtrim(&result, length - count); return result; } malunal_bool_t strview_equals( strview_iptr_t self, strview_iptr_t other ) { return strview_compare(self, other) == 0; } malunal_int32_t strview_compare( strview_iptr_t self, strview_iptr_t other ) { // Check pointers. if (self < other) return -1; if (self > other) return 1; if (self == other) return 0; // Check internals. if (self->beg < other->beg) return -1; if (self->beg > other->beg) return 1; if (self->end < other->end) return -1; if (self->end > other->end) return 1; // They are equal by internals. return 0; } malunal_bool_t strview_starts_with( strview_iptr_t self, strview_iptr_t other ) { if (self == null) return false; if (other == null) return true; malunal_size_t hlen = strview_length(self); malunal_size_t nlen = strview_length(other); return hlen >= nlen ? strncmp(self->beg, other->beg, nlen) == 0 : false; } malunal_bool_t strview_ends_with( strview_iptr_t self, strview_iptr_t other ) { if (self == null) return false; if (other == null) return true; malunal_size_t hlen = strview_length(self); malunal_size_t nlen = strview_length(other); if (hlen < nlen) return false; malunal_size_t diff = hlen - nlen; malunal_cstr_t beg = self->beg + diff; return strncmp(beg, other->beg, nlen) == 0; } malunal_bool_t strview_contains( strview_iptr_t self, strview_iptr_t other ) { if (self == null) return false; if (other == null) return true; malunal_size_t hlen = strview_length(self); malunal_size_t nlen = strview_length(other); if (hlen < nlen) return false; // Poor man's sliding window malunal_cstr_t beg = self->beg; while (hlen >= nlen) { if (strncmp(beg, other->beg, nlen)) return true; beg++; hlen--; } return false; }