libluna: Make String::from_string_view handle non-null-terminated strings properly

This commit is contained in:
apio 2023-05-02 10:48:38 +02:00
parent 1444cbb3df
commit 6982a8c07e
Signed by: apio
GPG Key ID: B8A7D06E42258954
2 changed files with 29 additions and 10 deletions

View File

@ -9,35 +9,53 @@ class String
typedef const char* ConstIterator; typedef const char* ConstIterator;
public: public:
/* Constructs a String, which will take ownership of the given c-string. To create a String that makes its own
* internal copy of the passed string, use String::from_cstring(). */
String(char* c_str); String(char* c_str);
/* Constructs a String with precalculated length, which will take ownership of the given c-string. To create a
* String that makes its own internal copy of the passed string, use String::from_cstring(). */
String(char* c_str, usize length); String(char* c_str, usize length);
/* Constructs an empty String. */
String(); String();
String(String&&); String(String&&);
/* Implicit copying is disabled for Strings, as copy constructors cannot use value-based error handling. To copy a
* string, please use the clone() method. */
String(const String&) = delete; String(const String&) = delete;
String& operator=(String&&); String& operator=(String&&);
/* Implicit copying is disabled for Strings, as copy constructors cannot use value-based error handling. To copy a
* string, please use the clone() method. */
String& operator=(const String&) = delete; String& operator=(const String&) = delete;
~String(); ~String();
/* Creates a copy of this String and returns it. */
Result<String> clone() const; Result<String> clone() const;
/* Creates a copy of a specific segment of this String and returns it. */
Result<String> substring(usize begin, usize size) const; Result<String> substring(usize begin, usize size) const;
/* Splits a String with a delimiter. */
Result<Vector<String>> split(StringView delim) const Result<Vector<String>> split(StringView delim) const
{ {
return view().split(delim); return view().split(delim);
} }
/* Splits a String into two parts with a delimiter. */
Result<Vector<String>> split_once(char delim) const Result<Vector<String>> split_once(char delim) const
{ {
return view().split_once(delim); return view().split_once(delim);
} }
/* Creates a single String consisting of a list of strings separated by a delimiter. */
static Result<String> join(const Vector<String>& vec, StringView delim); static Result<String> join(const Vector<String>& vec, StringView delim);
/* Removes all trailing characters contained in delim. */
void trim(StringView delim); void trim(StringView delim);
static Result<String> format(const String& fmt, ...); static Result<String> format(const String& fmt, ...);
@ -45,10 +63,7 @@ class String
static Result<String> vformat(StringView fmt, va_list ap); static Result<String> vformat(StringView fmt, va_list ap);
static Result<String> from_cstring(const char* str); static Result<String> from_cstring(const char* str);
static Result<String> from_string_view(StringView str) static Result<String> from_string_view(StringView str);
{
return from_cstring(str.chars());
}
const char* chars() const const char* chars() const
{ {

View File

@ -145,19 +145,23 @@ Result<String> String::vformat(StringView fmt, va_list ap)
Result<String> String::from_cstring(const char* str) Result<String> String::from_cstring(const char* str)
{ {
usize len = strlen(str); return from_string_view(StringView { str });
if (len < sizeof(m_inline_storage)) }
Result<String> String::from_string_view(StringView str)
{
if (str.length() < sizeof(m_inline_storage))
{ {
String result; String result;
result.m_inline = true; result.m_inline = true;
result.m_length = len; result.m_length = str.length();
strncpy(result.m_inline_storage, str, sizeof(m_inline_storage)); strncpy(result.m_inline_storage, str.chars(), sizeof(m_inline_storage));
return result; return result;
} }
char* const dup = strdup(str); char* const dup = strndup(str.chars(), str.length());
if (!dup) return err(ENOMEM); if (!dup) return err(ENOMEM);
return String { dup }; return String { dup, str.length() };
} }
Result<String> String::join(const Vector<String>& vec, StringView delim) Result<String> String::join(const Vector<String>& vec, StringView delim)