Serenity Operating System
1/*
2 * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/Format.h>
8#include <AK/StringBuilder.h>
9#include <Kernel/KString.h>
10
11extern bool g_in_early_boot;
12
13namespace Kernel {
14
15ErrorOr<NonnullOwnPtr<KString>> KString::try_create(StringView string)
16{
17 char* characters = nullptr;
18 size_t length = string.length();
19 auto new_string = TRY(KString::try_create_uninitialized(length, characters));
20 if (!string.is_empty())
21 __builtin_memcpy(characters, string.characters_without_null_termination(), length);
22 characters[length] = '\0';
23 return new_string;
24}
25
26ErrorOr<NonnullOwnPtr<KString>> KString::vformatted(StringView fmtstr, AK::TypeErasedFormatParams& params)
27{
28 StringBuilder builder;
29 TRY(AK::vformat(builder, fmtstr, params));
30 return try_create(builder.string_view());
31}
32
33NonnullOwnPtr<KString> KString::must_create(StringView string)
34{
35 // We can only enforce success during early boot.
36 VERIFY(g_in_early_boot);
37 return KString::try_create(string).release_value();
38}
39
40ErrorOr<NonnullOwnPtr<KString>> KString::try_create_uninitialized(size_t length, char*& characters)
41{
42 size_t allocation_size = sizeof(KString) + (sizeof(char) * length) + sizeof(char);
43 auto* slot = kmalloc(allocation_size);
44 if (!slot)
45 return ENOMEM;
46 auto new_string = TRY(adopt_nonnull_own_or_enomem(new (slot) KString(length)));
47 characters = new_string->m_characters;
48 return new_string;
49}
50
51NonnullOwnPtr<KString> KString::must_create_uninitialized(size_t length, char*& characters)
52{
53 // We can only enforce success during early boot.
54 VERIFY(g_in_early_boot);
55 return KString::try_create_uninitialized(length, characters).release_value();
56}
57
58ErrorOr<NonnullOwnPtr<KString>> KString::try_clone() const
59{
60 return try_create(view());
61}
62
63void KString::operator delete(void* string)
64{
65 if (!string)
66 return;
67 size_t allocation_size = sizeof(KString) + (sizeof(char) * static_cast<KString*>(string)->m_length) + sizeof(char);
68 kfree_sized(string, allocation_size);
69}
70
71}