KString.cpp 2.1 KB

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