Serenity Operating System
at master 131 lines 4.3 kB view raw
1/* 2 * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/Format.h> 10#include <AK/OwnPtr.h> 11 12namespace Kernel { 13 14class KString { 15 AK_MAKE_NONCOPYABLE(KString); 16 AK_MAKE_NONMOVABLE(KString); 17 18public: 19 [[nodiscard]] static ErrorOr<NonnullOwnPtr<KString>> try_create_uninitialized(size_t, char*&); 20 [[nodiscard]] static NonnullOwnPtr<KString> must_create_uninitialized(size_t, char*&); 21 [[nodiscard]] static ErrorOr<NonnullOwnPtr<KString>> try_create(StringView); 22 [[nodiscard]] static NonnullOwnPtr<KString> must_create(StringView); 23 24 [[nodiscard]] static ErrorOr<NonnullOwnPtr<KString>> vformatted(StringView fmtstr, AK::TypeErasedFormatParams&); 25 26 template<typename... Parameters> 27 [[nodiscard]] static ErrorOr<NonnullOwnPtr<KString>> formatted(CheckedFormatString<Parameters...>&& fmtstr, Parameters const&... parameters) 28 { 29 AK::VariadicFormatParams<AK::AllowDebugOnlyFormatters::No, Parameters...> variadic_format_parameters { parameters... }; 30 return vformatted(fmtstr.view(), variadic_format_parameters); 31 } 32 33 [[nodiscard]] static ErrorOr<NonnullOwnPtr<KString>> number(Arithmetic auto value) 34 { 35 return formatted("{}", value); 36 } 37 38 void operator delete(void*); 39 40 ErrorOr<NonnullOwnPtr<KString>> try_clone() const; 41 42 [[nodiscard]] bool is_empty() const { return m_length == 0; } 43 [[nodiscard]] size_t length() const { return m_length; } 44 [[nodiscard]] char const* characters() const { return m_characters; } 45 [[nodiscard]] StringView view() const { return { characters(), length() }; } 46 [[nodiscard]] ReadonlyBytes bytes() const { return { characters(), length() }; } 47 48private: 49 explicit KString(size_t length) 50 : m_length(length) 51 { 52 } 53 54 size_t m_length { 0 }; 55 char m_characters[0]; 56}; 57 58} 59 60namespace AK { 61 62template<> 63struct Formatter<Kernel::KString> : Formatter<StringView> { 64 ErrorOr<void> format(FormatBuilder& builder, Kernel::KString const& value) 65 { 66 return Formatter<StringView>::format(builder, value.view()); 67 } 68}; 69 70template<> 71struct Formatter<OwnPtr<Kernel::KString>> : Formatter<StringView> { 72 ErrorOr<void> format(FormatBuilder& builder, OwnPtr<Kernel::KString> const& value) 73 { 74 if (value) 75 return Formatter<StringView>::format(builder, value->view()); 76 return Formatter<StringView>::format(builder, "[out of memory]"sv); 77 } 78}; 79 80template<> 81struct Formatter<NonnullOwnPtr<Kernel::KString>> : Formatter<StringView> { 82 ErrorOr<void> format(FormatBuilder& builder, NonnullOwnPtr<Kernel::KString> const& value) 83 { 84 return Formatter<StringView>::format(builder, value->view()); 85 } 86}; 87 88template<> 89struct Traits<NonnullOwnPtr<Kernel::KString>> : public GenericTraits<NonnullOwnPtr<Kernel::KString>> { 90 using PeekType = Kernel::KString*; 91 using ConstPeekType = Kernel::KString const*; 92 static unsigned hash(NonnullOwnPtr<Kernel::KString> const& p) { return string_hash(p->characters(), p->length()); } 93 static bool equals(NonnullOwnPtr<Kernel::KString> const& a, NonnullOwnPtr<Kernel::KString> const& b) { return a->view() == b->view(); } 94 static bool equals(StringView a, NonnullOwnPtr<Kernel::KString> const& b) { return a == b->view(); } 95}; 96 97template<> 98struct Traits<OwnPtr<Kernel::KString>> : public GenericTraits<OwnPtr<Kernel::KString>> { 99 using PeekType = Kernel::KString*; 100 using ConstPeekType = Kernel::KString const*; 101 static unsigned hash(OwnPtr<Kernel::KString> const& p) 102 { 103 if (!p) 104 return ptr_hash(nullptr); 105 return string_hash(p->characters(), p->length()); 106 } 107 static bool equals(OwnPtr<Kernel::KString> const& a, OwnPtr<Kernel::KString> const& b) 108 { 109 if (!a || !b) 110 return a.ptr() == b.ptr(); 111 if (a == b) 112 return true; 113 114 return a->view() == b->view(); 115 } 116 static bool equals(StringView a, OwnPtr<Kernel::KString> const& b) 117 { 118 if (!b) 119 return a.is_null(); 120 return a == b->view(); 121 } 122}; 123 124namespace Detail { 125template<> 126inline constexpr bool IsHashCompatible<StringView, NonnullOwnPtr<Kernel::KString>> = true; 127template<> 128inline constexpr bool IsHashCompatible<StringView, OwnPtr<Kernel::KString>> = true; 129} 130 131}