/src/serenity/AK/StringBase.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <AK/Badge.h> |
8 | | #include <AK/FlyString.h> |
9 | | #include <AK/StringBase.h> |
10 | | #include <AK/StringData.h> |
11 | | |
12 | | namespace AK::Detail { |
13 | | |
14 | | ReadonlyBytes ShortString::bytes() const |
15 | 582M | { |
16 | 582M | return { storage, byte_count() }; |
17 | 582M | } |
18 | | |
19 | | size_t ShortString::byte_count() const |
20 | 582M | { |
21 | 582M | return byte_count_and_short_string_flag >> 1; |
22 | 582M | } |
23 | | |
24 | | StringBase::StringBase(NonnullRefPtr<Detail::StringData const> data) |
25 | 2.97k | : m_data(&data.leak_ref()) |
26 | 2.97k | { |
27 | 2.97k | } |
28 | | |
29 | | StringBase::StringBase(StringBase const& other) |
30 | 1.07G | : m_data(other.m_data) |
31 | 1.07G | { |
32 | 1.07G | if (!is_short_string()) |
33 | 1.78M | m_data->ref(); |
34 | 1.07G | } |
35 | | |
36 | | StringBase& StringBase::operator=(StringBase&& other) |
37 | 81.7M | { |
38 | 81.7M | if (!is_short_string()) |
39 | 15.8k | m_data->unref(); |
40 | | |
41 | 81.7M | m_data = exchange(other.m_data, nullptr); |
42 | 81.7M | other.m_short_string.byte_count_and_short_string_flag = SHORT_STRING_FLAG; |
43 | 81.7M | return *this; |
44 | 81.7M | } |
45 | | |
46 | | StringBase& StringBase::operator=(StringBase const& other) |
47 | 33.6M | { |
48 | 33.6M | if (&other != this) { |
49 | 33.6M | if (!is_short_string()) |
50 | 230k | m_data->unref(); |
51 | | |
52 | 33.6M | m_data = other.m_data; |
53 | 33.6M | if (!is_short_string()) |
54 | 1.57M | m_data->ref(); |
55 | 33.6M | } |
56 | 33.6M | return *this; |
57 | 33.6M | } |
58 | | |
59 | | ReadonlyBytes StringBase::bytes() const |
60 | 597M | { |
61 | 597M | if (is_short_string()) |
62 | 582M | return m_short_string.bytes(); |
63 | 15.7M | return m_data->bytes(); |
64 | 597M | } |
65 | | |
66 | | u32 StringBase::hash() const |
67 | 955k | { |
68 | 955k | if (is_short_string()) { |
69 | 930k | auto bytes = this->bytes(); |
70 | 930k | return string_hash(reinterpret_cast<char const*>(bytes.data()), bytes.size()); |
71 | 930k | } |
72 | 24.4k | return m_data->hash(); |
73 | 955k | } |
74 | | |
75 | | size_t StringBase::byte_count() const |
76 | 363k | { |
77 | 363k | if (is_short_string()) |
78 | 357k | return m_short_string.byte_count_and_short_string_flag >> 1; |
79 | 6.49k | return m_data->byte_count(); |
80 | 363k | } |
81 | | |
82 | | bool StringBase::operator==(StringBase const& other) const |
83 | 1.24M | { |
84 | 1.24M | if (is_short_string()) |
85 | 1.22M | return m_data == other.m_data; |
86 | 22.0k | if (other.is_short_string()) |
87 | 3.95k | return false; |
88 | 18.0k | if (m_data->is_fly_string() && other.m_data->is_fly_string()) |
89 | 0 | return m_data == other.m_data; |
90 | 18.0k | return bytes() == other.bytes(); |
91 | 18.0k | } |
92 | | |
93 | | ErrorOr<Bytes> StringBase::replace_with_uninitialized_buffer(size_t byte_count) |
94 | 44.5M | { |
95 | 44.5M | if (byte_count <= MAX_SHORT_STRING_BYTE_COUNT) |
96 | 39.1M | return replace_with_uninitialized_short_string(byte_count); |
97 | | |
98 | 5.38M | u8* buffer = nullptr; |
99 | 5.38M | destroy_string(); |
100 | 5.38M | m_data = &TRY(StringData::create_uninitialized(byte_count, buffer)).leak_ref(); |
101 | 5.38M | return Bytes { buffer, byte_count }; |
102 | 5.38M | } |
103 | | |
104 | | ErrorOr<StringBase> StringBase::substring_from_byte_offset_with_shared_superstring(size_t start, size_t length) const |
105 | 363k | { |
106 | 363k | VERIFY(start + length <= byte_count()); |
107 | | |
108 | 363k | if (length == 0) |
109 | 173k | return StringBase {}; |
110 | 190k | if (length <= MAX_SHORT_STRING_BYTE_COUNT) { |
111 | 187k | StringBase result; |
112 | 187k | bytes().slice(start, length).copy_to(result.replace_with_uninitialized_short_string(length)); |
113 | 187k | return result; |
114 | 187k | } |
115 | 2.97k | return StringBase { TRY(Detail::StringData::create_substring(*m_data, start, length)) }; |
116 | 2.97k | } |
117 | | |
118 | | void StringBase::destroy_string() |
119 | 2.64G | { |
120 | 2.64G | if (!is_short_string()) |
121 | 8.51M | m_data->unref(); |
122 | 2.64G | } |
123 | | |
124 | | } |