From b6c35124d6c2f5677d9e8a249b2be788cf44b8fb Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 29 Mar 2023 17:28:22 +0200 Subject: [PATCH] libluna: OwnedStringView -> String Also with inline storage! --- kernel/src/memory/MemoryManager.cpp | 4 +- kernel/src/memory/MemoryManager.h | 4 +- kernel/src/sys/exec.cpp | 6 +-- libluna/CMakeLists.txt | 2 +- libluna/include/luna/OwnedStringView.h | 35 ------------ libluna/include/luna/PathParser.h | 6 +-- libluna/include/luna/String.h | 44 +++++++++++++++ libluna/include/luna/Units.h | 4 +- libluna/src/OwnedStringView.cpp | 59 -------------------- libluna/src/PathParser.cpp | 8 +-- libluna/src/String.cpp | 75 ++++++++++++++++++++++++++ libluna/src/Units.cpp | 4 +- 12 files changed, 138 insertions(+), 113 deletions(-) delete mode 100644 libluna/include/luna/OwnedStringView.h create mode 100644 libluna/include/luna/String.h delete mode 100644 libluna/src/OwnedStringView.cpp create mode 100644 libluna/src/String.cpp diff --git a/kernel/src/memory/MemoryManager.cpp b/kernel/src/memory/MemoryManager.cpp index 4d4d2d20..5043597b 100644 --- a/kernel/src/memory/MemoryManager.cpp +++ b/kernel/src/memory/MemoryManager.cpp @@ -433,7 +433,7 @@ namespace MemoryManager } // FIXME: Make this more efficient. - Result strdup_from_user(u64 address) + Result 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) diff --git a/kernel/src/memory/MemoryManager.h b/kernel/src/memory/MemoryManager.h index 98e16267..c22f0c2e 100644 --- a/kernel/src/memory/MemoryManager.h +++ b/kernel/src/memory/MemoryManager.h @@ -1,6 +1,6 @@ #pragma once -#include #include +#include #include namespace MemoryManager @@ -26,7 +26,7 @@ namespace MemoryManager bool validate_user_writable_page(u64 address); bool validate_userspace_string(u64 address); - Result strdup_from_user(u64 address); + Result strdup_from_user(u64 address); bool validate_user_write(void* user, usize size); bool validate_user_read(const void* user, usize size); diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp index f747a687..1a766570 100644 --- a/kernel/src/sys/exec.cpp +++ b/kernel/src/sys/exec.cpp @@ -11,9 +11,9 @@ #include #include -static Result> copy_string_vector_from_userspace(u64 address) +static Result> copy_string_vector_from_userspace(u64 address) { - Vector result; + Vector result; const u64* user_vector = (const u64*)address; @@ -31,7 +31,7 @@ static Result> copy_string_vector_from_userspace(u64 add return result; } -static Result copy_string_vector_to_userspace(const Vector& vec, ThreadImage& image) +static Result copy_string_vector_to_userspace(const Vector& vec, ThreadImage& image) { Vector user_vec; for (const auto& item : vec) diff --git a/libluna/CMakeLists.txt b/libluna/CMakeLists.txt index 9ff201e9..eb99bd36 100644 --- a/libluna/CMakeLists.txt +++ b/libluna/CMakeLists.txt @@ -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 diff --git a/libluna/include/luna/OwnedStringView.h b/libluna/include/luna/OwnedStringView.h deleted file mode 100644 index 09454b0f..00000000 --- a/libluna/include/luna/OwnedStringView.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include - -class OwnedStringView -{ - public: - OwnedStringView(char* c_str); - OwnedStringView(char* c_str, usize length); - OwnedStringView(); - OwnedStringView(OwnedStringView&&); - OwnedStringView(const OwnedStringView&) = delete; - ~OwnedStringView(); - - Result clone() const; - - Result substring(usize begin, usize size) const; - - static Result 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 }; -}; diff --git a/libluna/include/luna/PathParser.h b/libluna/include/luna/PathParser.h index 33588ed7..44e9fbb9 100644 --- a/libluna/include/luna/PathParser.h +++ b/libluna/include/luna/PathParser.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include +#include class PathParser { @@ -18,8 +18,8 @@ class PathParser return *m_original == '/'; } - Result basename(); - Result dirname(); + Result basename(); + Result dirname(); Option next(); diff --git a/libluna/include/luna/String.h b/libluna/include/luna/String.h new file mode 100644 index 00000000..9ef00ad3 --- /dev/null +++ b/libluna/include/luna/String.h @@ -0,0 +1,44 @@ +#pragma once +#include + +class String +{ + public: + String(char* c_str); + String(char* c_str, usize length); + + String(); + + String(String&&); + String(const String&) = delete; + + ~String(); + + Result clone() const; + + Result substring(usize begin, usize size) const; + + static Result 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 }; +}; diff --git a/libluna/include/luna/Units.h b/libluna/include/luna/Units.h index edc22635..3872c7ac 100644 --- a/libluna/include/luna/Units.h +++ b/libluna/include/luna/Units.h @@ -1,6 +1,6 @@ #pragma once -#include #include +#include usize to_dynamic_unit_cstr(usize value, char* buffer, usize max); -Result to_dynamic_unit(usize value); +Result to_dynamic_unit(usize value); diff --git a/libluna/src/OwnedStringView.cpp b/libluna/src/OwnedStringView.cpp deleted file mode 100644 index 10637a23..00000000 --- a/libluna/src/OwnedStringView.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include - -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::clone() const -{ - return from_string_literal(m_string); -} - -Result 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::from_string_literal(const char* str) -{ - char* const dup = strdup(str); - if (!dup) return err(ENOMEM); - return OwnedStringView { dup }; -} diff --git a/libluna/src/PathParser.cpp b/libluna/src/PathParser.cpp index 47cdb94e..d159e86b 100644 --- a/libluna/src/PathParser.cpp +++ b/libluna/src/PathParser.cpp @@ -34,7 +34,7 @@ Option PathParser::next() return result; } -Result PathParser::basename() +Result PathParser::basename() { char* copy = strdup(m_original); if (!copy) return err(ENOMEM); @@ -44,10 +44,10 @@ Result 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 PathParser::dirname() +Result PathParser::dirname() { char* copy = strdup(m_original); if (!copy) return err(ENOMEM); @@ -57,5 +57,5 @@ Result 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); } diff --git a/libluna/src/String.cpp b/libluna/src/String.cpp new file mode 100644 index 00000000..656f8f8d --- /dev/null +++ b/libluna/src/String.cpp @@ -0,0 +1,75 @@ +#include +#include +#include + +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::clone() const +{ + return from_string_literal(chars()); +} + +Result 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::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 }; +} diff --git a/libluna/src/Units.cpp b/libluna/src/Units.cpp index 5ab2d572..19e79847 100644 --- a/libluna/src/Units.cpp +++ b/libluna/src/Units.cpp @@ -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 to_dynamic_unit(usize value) +Result to_dynamic_unit(usize value) { char* const buf = TRY(make_array(64)); to_dynamic_unit_cstr(value, buf, 64); - return OwnedStringView { buf }; + return String { buf }; }