diff --git a/libluna/include/luna/String.h b/libluna/include/luna/String.h index fa3ca9e0..84f7d3ab 100644 --- a/libluna/include/luna/String.h +++ b/libluna/include/luna/String.h @@ -27,6 +27,10 @@ class String Result substring(usize begin, usize size) const; Result> split(StringView delim) const; + Result> split_once(char delim) const + { + return view().split_once(delim); + } static Result format(const String& fmt, ...); static Result format(StringView fmt, ...); diff --git a/libluna/include/luna/StringView.h b/libluna/include/luna/StringView.h index dacdc572..1e57e434 100644 --- a/libluna/include/luna/StringView.h +++ b/libluna/include/luna/StringView.h @@ -41,6 +41,9 @@ class StringView bool operator==(StringView other) const; Result> split(StringView delim) const; + Result> split_once(char delim) const; + + Result to_uint() const; Iterator begin() const { diff --git a/libluna/src/StringView.cpp b/libluna/src/StringView.cpp index ba9ef207..234f116a 100644 --- a/libluna/src/StringView.cpp +++ b/libluna/src/StringView.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include @@ -62,9 +64,10 @@ Result> StringView::split(StringView delim) const String str; char* copy = strndup(m_string, m_length); + auto guard = make_scope_guard([copy] { free_impl(copy); }); char* segment = strtok(copy, delim.chars()); - if (!segment) goto end; + if (!segment) return result; str = TRY(String::from_cstring(segment)); TRY(result.try_append(move(str))); @@ -72,14 +75,46 @@ Result> StringView::split(StringView delim) const while (true) { segment = strtok(nullptr, delim.chars()); - if (!segment) goto end; + if (!segment) return result; str = TRY(String::from_cstring(segment)); TRY(result.try_append(move(str))); } -end: - free_impl(copy); + return result; +} + +Result> StringView::split_once(char delim) const +{ + Vector 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 StringView::to_uint() const +{ + const char* endptr = nullptr; + auto result = parse_unsigned_integer(m_string, &endptr, 0); + if (endptr == m_string) return err(EINVAL); return result; }