Serenity Operating System
at master 145 lines 4.2 kB view raw
1/* 2 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/DeprecatedFlyString.h> 8#include <AK/DeprecatedString.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 15namespace AK { 16 17struct DeprecatedFlyStringImplTraits : public Traits<StringImpl*> { 18 static unsigned hash(StringImpl const* s) { return s ? s->hash() : 0; } 19 static bool equals(StringImpl const* a, StringImpl const* b) 20 { 21 VERIFY(a); 22 VERIFY(b); 23 return *a == *b; 24 } 25}; 26 27static Singleton<HashTable<StringImpl const*, DeprecatedFlyStringImplTraits>> s_table; 28 29static HashTable<StringImpl const*, DeprecatedFlyStringImplTraits>& fly_impls() 30{ 31 return *s_table; 32} 33 34void DeprecatedFlyString::did_destroy_impl(Badge<StringImpl>, StringImpl& impl) 35{ 36 fly_impls().remove(&impl); 37} 38 39DeprecatedFlyString::DeprecatedFlyString(DeprecatedString const& string) 40{ 41 if (string.is_null()) 42 return; 43 if (string.impl()->is_fly()) { 44 m_impl = string.impl(); 45 return; 46 } 47 auto it = fly_impls().find(const_cast<StringImpl*>(string.impl())); 48 if (it == fly_impls().end()) { 49 fly_impls().set(const_cast<StringImpl*>(string.impl())); 50 string.impl()->set_fly({}, true); 51 m_impl = string.impl(); 52 } else { 53 VERIFY((*it)->is_fly()); 54 m_impl = *it; 55 } 56} 57 58DeprecatedFlyString::DeprecatedFlyString(StringView string) 59{ 60 if (string.is_null()) 61 return; 62 auto it = fly_impls().find(string.hash(), [&](auto& candidate) { 63 return string == candidate; 64 }); 65 if (it == fly_impls().end()) { 66 auto new_string = string.to_deprecated_string(); 67 fly_impls().set(new_string.impl()); 68 new_string.impl()->set_fly({}, true); 69 m_impl = new_string.impl(); 70 } else { 71 VERIFY((*it)->is_fly()); 72 m_impl = *it; 73 } 74} 75 76template<typename T> 77Optional<T> DeprecatedFlyString::to_int(TrimWhitespace trim_whitespace) const 78{ 79 return StringUtils::convert_to_int<T>(view(), trim_whitespace); 80} 81 82template Optional<i8> DeprecatedFlyString::to_int(TrimWhitespace) const; 83template Optional<i16> DeprecatedFlyString::to_int(TrimWhitespace) const; 84template Optional<i32> DeprecatedFlyString::to_int(TrimWhitespace) const; 85template Optional<i64> DeprecatedFlyString::to_int(TrimWhitespace) const; 86 87template<typename T> 88Optional<T> DeprecatedFlyString::to_uint(TrimWhitespace trim_whitespace) const 89{ 90 return StringUtils::convert_to_uint<T>(view(), trim_whitespace); 91} 92 93template Optional<u8> DeprecatedFlyString::to_uint(TrimWhitespace) const; 94template Optional<u16> DeprecatedFlyString::to_uint(TrimWhitespace) const; 95template Optional<u32> DeprecatedFlyString::to_uint(TrimWhitespace) const; 96template Optional<u64> DeprecatedFlyString::to_uint(TrimWhitespace) const; 97 98#ifndef KERNEL 99Optional<double> DeprecatedFlyString::to_double(TrimWhitespace trim_whitespace) const 100{ 101 return StringUtils::convert_to_floating_point<double>(view(), trim_whitespace); 102} 103 104Optional<float> DeprecatedFlyString::to_float(TrimWhitespace trim_whitespace) const 105{ 106 return StringUtils::convert_to_floating_point<float>(view(), trim_whitespace); 107} 108#endif 109 110bool DeprecatedFlyString::equals_ignoring_ascii_case(StringView other) const 111{ 112 return StringUtils::equals_ignoring_ascii_case(view(), other); 113} 114 115bool DeprecatedFlyString::starts_with(StringView str, CaseSensitivity case_sensitivity) const 116{ 117 return StringUtils::starts_with(view(), str, case_sensitivity); 118} 119 120bool DeprecatedFlyString::ends_with(StringView str, CaseSensitivity case_sensitivity) const 121{ 122 return StringUtils::ends_with(view(), str, case_sensitivity); 123} 124 125DeprecatedFlyString DeprecatedFlyString::to_lowercase() const 126{ 127 return DeprecatedString(*m_impl).to_lowercase(); 128} 129 130bool DeprecatedFlyString::operator==(DeprecatedString const& other) const 131{ 132 return m_impl == other.impl() || view() == other.view(); 133} 134 135bool DeprecatedFlyString::operator==(StringView string) const 136{ 137 return view() == string; 138} 139 140bool DeprecatedFlyString::operator==(char const* string) const 141{ 142 return view() == string; 143} 144 145}