Coverage Report

Created: 2025-12-18 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/AK/DeprecatedFlyString.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#include <AK/ByteString.h>
8
#include <AK/DeprecatedFlyString.h>
9
#include <AK/HashTable.h>
10
#include <AK/Optional.h>
11
#include <AK/Singleton.h>
12
#include <AK/StringUtils.h>
13
#include <AK/StringView.h>
14
15
namespace AK {
16
17
struct DeprecatedFlyStringImplTraits : public Traits<StringImpl const*> {
18
3.00k
    static unsigned hash(StringImpl const* s) { return s->hash(); }
19
    static bool equals(StringImpl const* a, StringImpl const* b)
20
3.46k
    {
21
3.46k
        return *a == *b;
22
3.46k
    }
23
};
24
25
static Singleton<HashTable<StringImpl const*, DeprecatedFlyStringImplTraits>> s_table;
26
27
static HashTable<StringImpl const*, DeprecatedFlyStringImplTraits>& fly_impls()
28
2.82k
{
29
2.82k
    return *s_table;
30
2.82k
}
31
32
void DeprecatedFlyString::did_destroy_impl(Badge<StringImpl>, StringImpl& impl)
33
269
{
34
269
    fly_impls().remove(&impl);
35
269
}
36
37
DeprecatedFlyString::DeprecatedFlyString(ByteString const& string)
38
876
    : m_impl(string.impl())
39
876
{
40
876
    if (string.impl()->is_fly())
41
0
        return;
42
43
876
    auto it = fly_impls().find(string.impl());
44
876
    if (it == fly_impls().end()) {
45
801
        fly_impls().set(string.impl());
46
801
        string.impl()->set_fly({}, true);
47
801
        m_impl = string.impl();
48
801
    } else {
49
75
        VERIFY((*it)->is_fly());
50
75
        m_impl = **it;
51
75
    }
52
876
}
53
54
DeprecatedFlyString::DeprecatedFlyString(StringView string)
55
0
    : m_impl(StringImpl::the_empty_stringimpl())
56
0
{
57
0
    if (string.is_null())
58
0
        return;
59
0
    auto it = fly_impls().find(string.hash(), [&](auto& candidate) {
60
0
        return string == *candidate;
61
0
    });
62
0
    if (it == fly_impls().end()) {
63
0
        auto new_string = string.to_byte_string();
64
0
        fly_impls().set(new_string.impl());
65
0
        new_string.impl()->set_fly({}, true);
66
0
        m_impl = new_string.impl();
67
0
    } else {
68
0
        VERIFY((*it)->is_fly());
69
0
        m_impl = **it;
70
0
    }
71
0
}
72
73
bool DeprecatedFlyString::equals_ignoring_ascii_case(StringView other) const
74
0
{
75
0
    return StringUtils::equals_ignoring_ascii_case(view(), other);
76
0
}
77
78
bool DeprecatedFlyString::starts_with(StringView str, CaseSensitivity case_sensitivity) const
79
0
{
80
0
    return StringUtils::starts_with(view(), str, case_sensitivity);
81
0
}
82
83
bool DeprecatedFlyString::ends_with(StringView str, CaseSensitivity case_sensitivity) const
84
0
{
85
0
    return StringUtils::ends_with(view(), str, case_sensitivity);
86
0
}
87
88
DeprecatedFlyString DeprecatedFlyString::to_lowercase() const
89
0
{
90
0
    return ByteString(*m_impl).to_lowercase();
91
0
}
92
93
bool DeprecatedFlyString::operator==(ByteString const& other) const
94
0
{
95
0
    return m_impl == other.impl() || view() == other.view();
96
0
}
97
98
bool DeprecatedFlyString::operator==(StringView string) const
99
0
{
100
0
    return view() == string;
101
0
}
102
103
bool DeprecatedFlyString::operator==(char const* string) const
104
0
{
105
0
    return view() == string;
106
0
}
107
108
}