/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 | 591M | { |
16 | 591M | return { storage, byte_count() }; |
17 | 591M | } |
18 | | |
19 | | size_t ShortString::byte_count() const |
20 | 591M | { |
21 | 591M | return byte_count_and_short_string_flag >> 1; |
22 | 591M | } |
23 | | |
24 | | StringBase::StringBase(NonnullRefPtr<Detail::StringData const> data) |
25 | 4.02k | : m_data(&data.leak_ref()) |
26 | 4.02k | { |
27 | 4.02k | } |
28 | | |
29 | | StringBase::StringBase(StringBase const& other) |
30 | 146M | : m_data(other.m_data) |
31 | 146M | { |
32 | 146M | if (!is_short_string()) |
33 | 4.13M | m_data->ref(); |
34 | 146M | } |
35 | | |
36 | | StringBase& StringBase::operator=(StringBase&& other) |
37 | 96.3M | { |
38 | 96.3M | if (!is_short_string()) |
39 | 17.7k | m_data->unref(); |
40 | | |
41 | 96.3M | m_data = exchange(other.m_data, nullptr); |
42 | 96.3M | other.m_short_string.byte_count_and_short_string_flag = SHORT_STRING_FLAG; |
43 | 96.3M | return *this; |
44 | 96.3M | } |
45 | | |
46 | | StringBase& StringBase::operator=(StringBase const& other) |
47 | 39.6M | { |
48 | 39.6M | if (&other != this) { |
49 | 39.6M | if (!is_short_string()) |
50 | 308k | m_data->unref(); |
51 | | |
52 | 39.6M | m_data = other.m_data; |
53 | 39.6M | if (!is_short_string()) |
54 | 1.72M | m_data->ref(); |
55 | 39.6M | } |
56 | 39.6M | return *this; |
57 | 39.6M | } |
58 | | |
59 | | ReadonlyBytes StringBase::bytes() const |
60 | 608M | { |
61 | 608M | if (is_short_string()) |
62 | 591M | return m_short_string.bytes(); |
63 | 17.3M | return m_data->bytes(); |
64 | 608M | } |
65 | | |
66 | | u32 StringBase::hash() const |
67 | 530k | { |
68 | 530k | if (is_short_string()) { |
69 | 497k | auto bytes = this->bytes(); |
70 | 497k | return string_hash(reinterpret_cast<char const*>(bytes.data()), bytes.size()); |
71 | 497k | } |
72 | 33.2k | return m_data->hash(); |
73 | 530k | } |
74 | | |
75 | | size_t StringBase::byte_count() const |
76 | 461k | { |
77 | 461k | if (is_short_string()) |
78 | 451k | return m_short_string.byte_count_and_short_string_flag >> 1; |
79 | 9.76k | return m_data->byte_count(); |
80 | 461k | } |
81 | | |
82 | | bool StringBase::operator==(StringBase const& other) const |
83 | 631k | { |
84 | 631k | if (is_short_string()) |
85 | 598k | return m_data == other.m_data; |
86 | 32.7k | if (other.is_short_string()) |
87 | 7.72k | return false; |
88 | 25.0k | if (m_data->is_fly_string() && other.m_data->is_fly_string()) |
89 | 0 | return m_data == other.m_data; |
90 | 25.0k | return bytes() == other.bytes(); |
91 | 25.0k | } |
92 | | |
93 | | ErrorOr<Bytes> StringBase::replace_with_uninitialized_buffer(size_t byte_count) |
94 | 54.1M | { |
95 | 54.1M | if (byte_count <= MAX_SHORT_STRING_BYTE_COUNT) |
96 | 44.7M | return replace_with_uninitialized_short_string(byte_count); |
97 | | |
98 | 9.42M | u8* buffer = nullptr; |
99 | 9.42M | destroy_string(); |
100 | 9.42M | m_data = &TRY(StringData::create_uninitialized(byte_count, buffer)).leak_ref(); |
101 | 9.42M | return Bytes { buffer, byte_count }; |
102 | 9.42M | } |
103 | | |
104 | | ErrorOr<StringBase> StringBase::substring_from_byte_offset_with_shared_superstring(size_t start, size_t length) const |
105 | 461k | { |
106 | 461k | VERIFY(start + length <= byte_count()); |
107 | | |
108 | 461k | if (length == 0) |
109 | 208k | return StringBase {}; |
110 | 253k | if (length <= MAX_SHORT_STRING_BYTE_COUNT) { |
111 | 249k | StringBase result; |
112 | 249k | bytes().slice(start, length).copy_to(result.replace_with_uninitialized_short_string(length)); |
113 | 249k | return result; |
114 | 249k | } |
115 | 4.02k | return StringBase { TRY(Detail::StringData::create_substring(*m_data, start, length)) }; |
116 | 4.02k | } |
117 | | |
118 | | void StringBase::destroy_string() |
119 | 2.07G | { |
120 | 2.07G | if (!is_short_string()) |
121 | 14.9M | m_data->unref(); |
122 | 2.07G | } |
123 | | |
124 | | } |