libluna: OwnedStringView -> String

Also with inline storage!
This commit is contained in:
apio 2023-03-29 17:28:22 +02:00
parent 7b0b3dabc4
commit b6c35124d6
Signed by: apio
GPG Key ID: B8A7D06E42258954
12 changed files with 138 additions and 113 deletions

View File

@ -433,7 +433,7 @@ namespace MemoryManager
}
// FIXME: Make this more efficient.
Result<OwnedStringView> strdup_from_user(u64 address)
Result<String> strdup_from_user(u64 address)
{
if (!validate_user_readable_page(address)) return err(EFAULT);
@ -451,7 +451,7 @@ namespace MemoryManager
TRY(result.try_append(0)); // null terminator
return OwnedStringView::from_string_literal(result.data());
return String::from_string_literal(result.data());
}
bool validate_user_write(void* user, usize size)

View File

@ -1,6 +1,6 @@
#pragma once
#include <luna/OwnedStringView.h>
#include <luna/Result.h>
#include <luna/String.h>
#include <luna/Types.h>
namespace MemoryManager
@ -26,7 +26,7 @@ namespace MemoryManager
bool validate_user_writable_page(u64 address);
bool validate_userspace_string(u64 address);
Result<OwnedStringView> strdup_from_user(u64 address);
Result<String> strdup_from_user(u64 address);
bool validate_user_write(void* user, usize size);
bool validate_user_read(const void* user, usize size);

View File

@ -11,9 +11,9 @@
#include <luna/ScopeGuard.h>
#include <luna/Vector.h>
static Result<Vector<OwnedStringView>> copy_string_vector_from_userspace(u64 address)
static Result<Vector<String>> copy_string_vector_from_userspace(u64 address)
{
Vector<OwnedStringView> result;
Vector<String> result;
const u64* user_vector = (const u64*)address;
@ -31,7 +31,7 @@ static Result<Vector<OwnedStringView>> copy_string_vector_from_userspace(u64 add
return result;
}
static Result<u64> copy_string_vector_to_userspace(const Vector<OwnedStringView>& vec, ThreadImage& image)
static Result<u64> copy_string_vector_to_userspace(const Vector<String>& vec, ThreadImage& image)
{
Vector<u64> user_vec;
for (const auto& item : vec)

View File

@ -13,7 +13,7 @@ set(FREESTANDING_SOURCES
src/Bitmap.cpp
src/Buffer.cpp
src/Stack.cpp
src/OwnedStringView.cpp
src/String.cpp
src/Utf8.cpp
src/TarStream.cpp
src/DebugLog.cpp

View File

@ -1,35 +0,0 @@
#pragma once
#include <luna/Result.h>
class OwnedStringView
{
public:
OwnedStringView(char* c_str);
OwnedStringView(char* c_str, usize length);
OwnedStringView();
OwnedStringView(OwnedStringView&&);
OwnedStringView(const OwnedStringView&) = delete;
~OwnedStringView();
Result<OwnedStringView> clone() const;
Result<OwnedStringView> substring(usize begin, usize size) const;
static Result<OwnedStringView> from_string_literal(const char* str);
const char* chars() const
{
return m_string;
}
usize length() const
{
return m_length;
}
const char& operator[](usize) const;
private:
char* m_string { nullptr };
usize m_length { 0 };
};

View File

@ -1,7 +1,7 @@
#pragma once
#include <luna/CString.h>
#include <luna/Heap.h>
#include <luna/OwnedStringView.h>
#include <luna/String.h>
class PathParser
{
@ -18,8 +18,8 @@ class PathParser
return *m_original == '/';
}
Result<OwnedStringView> basename();
Result<OwnedStringView> dirname();
Result<String> basename();
Result<String> dirname();
Option<const char*> next();

View File

@ -0,0 +1,44 @@
#pragma once
#include <luna/Result.h>
class String
{
public:
String(char* c_str);
String(char* c_str, usize length);
String();
String(String&&);
String(const String&) = delete;
~String();
Result<String> clone() const;
Result<String> substring(usize begin, usize size) const;
static Result<String> from_string_literal(const char* str);
const char* chars() const
{
return m_inline ? m_inline_storage : m_string;
}
usize length() const
{
return m_length;
}
const char& operator[](usize) const;
private:
union {
char* m_string { nullptr };
char m_inline_storage[sizeof(char*)];
};
bool m_inline { true };
usize m_length { 0 };
};

View File

@ -1,6 +1,6 @@
#pragma once
#include <luna/OwnedStringView.h>
#include <luna/Result.h>
#include <luna/String.h>
usize to_dynamic_unit_cstr(usize value, char* buffer, usize max);
Result<OwnedStringView> to_dynamic_unit(usize value);
Result<String> to_dynamic_unit(usize value);

View File

@ -1,59 +0,0 @@
#include <luna/Alloc.h>
#include <luna/CString.h>
#include <luna/OwnedStringView.h>
OwnedStringView::OwnedStringView()
{
}
OwnedStringView::OwnedStringView(OwnedStringView&& other)
{
m_string = other.m_string;
m_length = other.m_length;
other.m_string = nullptr;
}
OwnedStringView::OwnedStringView(char* c_str)
{
m_string = c_str;
if (m_string) { m_length = strlen(m_string); }
}
OwnedStringView::OwnedStringView(char* c_str, usize length)
{
m_string = c_str;
m_length = length;
}
OwnedStringView::~OwnedStringView()
{
if (m_string) free_impl(m_string);
}
Result<OwnedStringView> OwnedStringView::clone() const
{
return from_string_literal(m_string);
}
Result<OwnedStringView> OwnedStringView::substring(usize begin, usize size) const
{
if (begin + size >= size) return err(EINVAL);
char* const dup = strndup(m_string + begin, size);
if (!dup) return err(ENOMEM);
return OwnedStringView { dup, size };
}
const char& OwnedStringView::operator[](usize index) const
{
expect(index < m_length, "index out of range");
return m_string[index];
}
Result<OwnedStringView> OwnedStringView::from_string_literal(const char* str)
{
char* const dup = strdup(str);
if (!dup) return err(ENOMEM);
return OwnedStringView { dup };
}

View File

@ -34,7 +34,7 @@ Option<const char*> PathParser::next()
return result;
}
Result<OwnedStringView> PathParser::basename()
Result<String> PathParser::basename()
{
char* copy = strdup(m_original);
if (!copy) return err(ENOMEM);
@ -44,10 +44,10 @@ Result<OwnedStringView> PathParser::basename()
char* result = ::basename(copy);
// We must copy this as we cannot rely on the original string.
return OwnedStringView::from_string_literal(result);
return String::from_string_literal(result);
}
Result<OwnedStringView> PathParser::dirname()
Result<String> PathParser::dirname()
{
char* copy = strdup(m_original);
if (!copy) return err(ENOMEM);
@ -57,5 +57,5 @@ Result<OwnedStringView> PathParser::dirname()
char* result = ::dirname(copy);
// We must copy this as we cannot rely on the original string.
return OwnedStringView::from_string_literal(result);
return String::from_string_literal(result);
}

75
libluna/src/String.cpp Normal file
View File

@ -0,0 +1,75 @@
#include <luna/Alloc.h>
#include <luna/CString.h>
#include <luna/String.h>
String::String()
{
m_inline = true;
memset(m_inline_storage, 0, sizeof(m_inline_storage));
}
String::String(String&& other)
{
m_inline = other.m_inline;
m_string = other.m_string;
m_length = other.m_length;
if (m_inline) memcpy(m_inline_storage, other.m_inline_storage, sizeof(m_inline_storage));
other.m_string = nullptr;
}
String::String(char* c_str)
{
m_string = c_str;
m_inline = false;
if (m_string) { m_length = strlen(m_string); }
}
String::String(char* c_str, usize length)
{
m_string = c_str;
m_inline = false;
m_length = length;
}
String::~String()
{
if (!m_inline) free_impl(m_string);
}
Result<String> String::clone() const
{
return from_string_literal(chars());
}
Result<String> String::substring(usize begin, usize size) const
{
if (begin + size >= size) return err(EINVAL);
char* const dup = strndup(chars() + begin, size);
if (!dup) return err(ENOMEM);
return String { dup, size };
}
const char& String::operator[](usize index) const
{
expect(index < m_length, "index out of range");
return chars()[index];
}
Result<String> String::from_string_literal(const char* str)
{
if (strlen(str) < sizeof(m_inline_storage))
{
String result;
result.m_inline = true;
strncpy(result.m_inline_storage, str, sizeof(m_inline_storage));
return result;
}
char* const dup = strdup(str);
if (!dup) return err(ENOMEM);
return String { dup };
}

View File

@ -18,11 +18,11 @@ usize to_dynamic_unit_cstr(usize value, char* buffer, usize max)
return string_format(buffer, max, "%zu.%zu %ciB", value / 1024, (value % 1024) / 103, *unit_prefixes);
}
Result<OwnedStringView> to_dynamic_unit(usize value)
Result<String> to_dynamic_unit(usize value)
{
char* const buf = TRY(make_array<char>(64));
to_dynamic_unit_cstr(value, buf, 64);
return OwnedStringView { buf };
return String { buf };
}