Luna/libluna/src/StringView.cpp

163 lines
3.5 KiB
C++
Raw Normal View History

2023-03-29 15:43:10 +00:00
#include <luna/CString.h>
2023-04-20 18:08:34 +00:00
#include <luna/NumberParsing.h>
#include <luna/ScopeGuard.h>
2023-03-29 15:43:10 +00:00
#include <luna/String.h>
#include <luna/StringView.h>
static const char* empty = "";
StringView::StringView()
{
m_string = empty;
m_length = 0;
}
StringView::StringView(const StringView& other)
{
m_string = other.m_string;
m_length = other.m_length;
}
StringView::StringView(const char* c_str)
{
check(c_str);
m_string = c_str;
m_length = strlen(m_string);
}
StringView::StringView(const char* c_str, usize length)
{
check(c_str);
m_string = c_str;
m_length = length;
}
2023-04-11 20:45:13 +00:00
StringView& StringView::operator=(const StringView& other)
{
if (&other == this) return *this;
m_string = other.m_string;
m_length = other.m_length;
return *this;
}
2023-03-29 15:43:10 +00:00
const char& StringView::operator[](usize index) const
{
expect(index < m_length, "index out of range");
return m_string[index];
}
bool StringView::operator==(const char* other) const
{
if (m_length != strlen(other)) return false;
return !strncmp(m_string, other, m_length);
}
bool StringView::operator==(StringView other) const
{
if (m_length != other.m_length) return false;
return !strncmp(m_string, other.m_string, m_length);
}
2023-04-07 13:14:46 +00:00
Result<Vector<String>> StringView::split(StringView delim) const
{
Vector<String> result;
String str;
char* copy = strndup(m_string, m_length);
2023-04-20 18:08:34 +00:00
auto guard = make_scope_guard([copy] { free_impl(copy); });
2023-04-07 13:14:46 +00:00
char* segment = strtok(copy, delim.chars());
2023-04-20 18:08:34 +00:00
if (!segment) return result;
2023-04-07 13:14:46 +00:00
str = TRY(String::from_cstring(segment));
TRY(result.try_append(move(str)));
while (true)
{
segment = strtok(nullptr, delim.chars());
2023-04-20 18:08:34 +00:00
if (!segment) return result;
2023-04-07 13:14:46 +00:00
str = TRY(String::from_cstring(segment));
TRY(result.try_append(move(str)));
}
2023-04-20 18:08:34 +00:00
return result;
}
Result<Vector<String>> StringView::split_once(char delim) const
{
Vector<String> result;
char* copy = strndup(m_string, m_length);
auto guard = make_scope_guard([copy] { free_impl(copy); });
char* middle = strchr(copy, delim);
if (!middle)
{
auto str = TRY(String::from_cstring(copy));
TRY(result.try_append(move(str)));
return result;
}
*middle = '\0';
auto begin = TRY(String::from_cstring(copy));
auto end = TRY(String::from_cstring(middle + 1));
TRY(result.try_append(move(begin)));
TRY(result.try_append(move(end)));
return result;
}
Result<Vector<StringView>> StringView::split_view(char delim) const
{
Vector<StringView> result;
char* middle = strchr(m_string, delim);
if (!middle)
{
TRY(result.try_append(*this));
return result;
}
// begin will not contain a null terminator.
auto begin = StringView::from_fixed_size_cstring(m_string, middle - m_string);
auto end = StringView { middle + 1 };
TRY(result.try_append(begin));
TRY(result.try_append(end));
return result;
}
bool StringView::contains(char v) const
{
return strchr(m_string, v);
}
2023-04-20 18:08:34 +00:00
Result<usize> StringView::to_uint() const
{
const char* endptr = nullptr;
auto result = parse_unsigned_integer(m_string, &endptr, 0);
if (endptr == m_string) return err(EINVAL);
2023-04-07 13:14:46 +00:00
return result;
}
2023-03-29 15:43:10 +00:00
Result<String> StringView::to_string()
{
return String::from_string_view(*this);
}
StringView StringView::from_fixed_size_cstring(const char* string, usize max)
{
return { string, strnlen(string, max) };
2023-03-29 15:43:10 +00:00
}
template <> u64 hash(const StringView& value, u64 salt)
{
return hash_memory(value.chars(), value.length(), salt);
}