#include #include "malunal/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 res = { self->beg, self->end }; malunal_size_t len = strview_length(&res); if (start > len) return strview(null, 0); strview_ltrim(&res, start); len = strview_length(&res); if (count > len) return strview(null, 0); strview_rtrim(&res, len - count); return res; } 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 ) { if (self == null || other == null) { if (self < other) return -1; if (self > other) return 1; if (self == other) return 0; } malunal_size_t hlen = strview_length(self); malunal_size_t nlen = strview_length(other); if (hlen < nlen) return -1; if (hlen > nlen) return 1; malunal_size_t smallest = hlen < nlen ? hlen : nlen; return strncmp(self->beg, other->beg, smallest); } 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); if (nlen == 0) return true; 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 (nlen == 0) return true; 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 (nlen == 0) return true; 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) == 0) return true; beg++; hlen--; } return false; }