libluna: OwnedStringView -> String
Also with inline storage!
This commit is contained in:
parent
7b0b3dabc4
commit
b6c35124d6
@ -433,7 +433,7 @@ namespace MemoryManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Make this more efficient.
|
// 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);
|
if (!validate_user_readable_page(address)) return err(EFAULT);
|
||||||
|
|
||||||
@ -451,7 +451,7 @@ namespace MemoryManager
|
|||||||
|
|
||||||
TRY(result.try_append(0)); // null terminator
|
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)
|
bool validate_user_write(void* user, usize size)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <luna/OwnedStringView.h>
|
|
||||||
#include <luna/Result.h>
|
#include <luna/Result.h>
|
||||||
|
#include <luna/String.h>
|
||||||
#include <luna/Types.h>
|
#include <luna/Types.h>
|
||||||
|
|
||||||
namespace MemoryManager
|
namespace MemoryManager
|
||||||
@ -26,7 +26,7 @@ namespace MemoryManager
|
|||||||
bool validate_user_writable_page(u64 address);
|
bool validate_user_writable_page(u64 address);
|
||||||
|
|
||||||
bool validate_userspace_string(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_write(void* user, usize size);
|
||||||
bool validate_user_read(const void* user, usize size);
|
bool validate_user_read(const void* user, usize size);
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
#include <luna/ScopeGuard.h>
|
#include <luna/ScopeGuard.h>
|
||||||
#include <luna/Vector.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;
|
const u64* user_vector = (const u64*)address;
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ static Result<Vector<OwnedStringView>> copy_string_vector_from_userspace(u64 add
|
|||||||
return result;
|
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;
|
Vector<u64> user_vec;
|
||||||
for (const auto& item : vec)
|
for (const auto& item : vec)
|
||||||
|
@ -13,7 +13,7 @@ set(FREESTANDING_SOURCES
|
|||||||
src/Bitmap.cpp
|
src/Bitmap.cpp
|
||||||
src/Buffer.cpp
|
src/Buffer.cpp
|
||||||
src/Stack.cpp
|
src/Stack.cpp
|
||||||
src/OwnedStringView.cpp
|
src/String.cpp
|
||||||
src/Utf8.cpp
|
src/Utf8.cpp
|
||||||
src/TarStream.cpp
|
src/TarStream.cpp
|
||||||
src/DebugLog.cpp
|
src/DebugLog.cpp
|
||||||
|
@ -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 };
|
|
||||||
};
|
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <luna/CString.h>
|
#include <luna/CString.h>
|
||||||
#include <luna/Heap.h>
|
#include <luna/Heap.h>
|
||||||
#include <luna/OwnedStringView.h>
|
#include <luna/String.h>
|
||||||
|
|
||||||
class PathParser
|
class PathParser
|
||||||
{
|
{
|
||||||
@ -18,8 +18,8 @@ class PathParser
|
|||||||
return *m_original == '/';
|
return *m_original == '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<OwnedStringView> basename();
|
Result<String> basename();
|
||||||
Result<OwnedStringView> dirname();
|
Result<String> dirname();
|
||||||
|
|
||||||
Option<const char*> next();
|
Option<const char*> next();
|
||||||
|
|
||||||
|
44
libluna/include/luna/String.h
Normal file
44
libluna/include/luna/String.h
Normal 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 };
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <luna/OwnedStringView.h>
|
|
||||||
#include <luna/Result.h>
|
#include <luna/Result.h>
|
||||||
|
#include <luna/String.h>
|
||||||
|
|
||||||
usize to_dynamic_unit_cstr(usize value, char* buffer, usize max);
|
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);
|
||||||
|
@ -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 };
|
|
||||||
}
|
|
@ -34,7 +34,7 @@ Option<const char*> PathParser::next()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<OwnedStringView> PathParser::basename()
|
Result<String> PathParser::basename()
|
||||||
{
|
{
|
||||||
char* copy = strdup(m_original);
|
char* copy = strdup(m_original);
|
||||||
if (!copy) return err(ENOMEM);
|
if (!copy) return err(ENOMEM);
|
||||||
@ -44,10 +44,10 @@ Result<OwnedStringView> PathParser::basename()
|
|||||||
char* result = ::basename(copy);
|
char* result = ::basename(copy);
|
||||||
|
|
||||||
// We must copy this as we cannot rely on the original string.
|
// 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);
|
char* copy = strdup(m_original);
|
||||||
if (!copy) return err(ENOMEM);
|
if (!copy) return err(ENOMEM);
|
||||||
@ -57,5 +57,5 @@ Result<OwnedStringView> PathParser::dirname()
|
|||||||
char* result = ::dirname(copy);
|
char* result = ::dirname(copy);
|
||||||
|
|
||||||
// We must copy this as we cannot rely on the original string.
|
// 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
75
libluna/src/String.cpp
Normal 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 };
|
||||||
|
}
|
@ -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);
|
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));
|
char* const buf = TRY(make_array<char>(64));
|
||||||
|
|
||||||
to_dynamic_unit_cstr(value, buf, 64);
|
to_dynamic_unit_cstr(value, buf, 64);
|
||||||
|
|
||||||
return OwnedStringView { buf };
|
return String { buf };
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user