The Pedigree Project 0.1
StringView.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "pedigree/kernel/Log.h"
21#include "pedigree/kernel/utilities/String.h"
22#include "pedigree/kernel/utilities/StringView.h"
23#include "pedigree/kernel/utilities/assert.h"
24#include "pedigree/kernel/utilities/utility.h"
25
26StringView::StringView()
27 : m_String(nullptr), m_Length(0), m_HashingEnabled(HASH_STRINGVIEWS_BY_DEFAULT) {
28 m_Hash = 0;
29}
30
31StringView::StringView(const char* s)
32 : m_String(s),
33 m_Length(StringLength(s)),
34 m_Hash(0),
35 m_HashingEnabled(HASH_STRINGVIEWS_BY_DEFAULT) {
36 setHashingEnable(m_HashingEnabled);
37}
38
39StringView::StringView(const char* s, size_t length)
40 : m_String(s), m_Length(length), m_Hash(0), m_HashingEnabled(HASH_STRINGVIEWS_BY_DEFAULT) {
41 setHashingEnable(m_HashingEnabled);
42}
43
44StringView::StringView(const char* s, size_t length, uint32_t hash, bool hashingEnabled)
45 : m_String(s), m_Length(length), m_Hash(hash), m_HashingEnabled(hashingEnabled) {}
46
47StringView::StringView(const StringView& other)
48 : m_String(other.m_String),
49 m_Length(other.m_Length),
50 m_Hash(other.m_Hash),
51 m_HashingEnabled(other.m_HashingEnabled) {}
52
53StringView::StringView(const String& other) : StringView(other.view()) {}
54
55StringView::~StringView() = default;
56
57StringView& StringView::operator=(const StringView& s) {
58 m_String = s.m_String;
59 m_Length = s.m_Length;
60 m_Hash = s.m_Hash;
61 m_HashingEnabled = s.m_HashingEnabled;
62 return *this;
63}
64
65bool StringView::operator==(const char* s) const {
66 return compare(s, StringLength(s));
67}
68
69bool StringView::operator==(const String& s) const {
70 if (m_Length != s.length()) {
71 return false;
72 } else if (!compareHash(s)) {
73 return false;
74 }
75
76 return compare(static_cast<const char*>(s), s.length());
77}
78
79bool StringView::operator==(const StringView& s) const {
80 if (m_Length != s.m_Length) {
81 return false;
82 } else if (!(m_Length && s.m_Length)) {
83 return true;
84 } else if (!compareHash(s)) {
85 return false;
86 }
87
88 return !StringMatchN(m_String, s.m_String, m_Length);
89}
90
91bool StringView::compare(const char* s, size_t length) const {
92 if (UNLIKELY(!m_Length)) {
93 if (!s || !*s) {
94 // empty strings match
95 return true;
96 }
97 return false;
98 }
99
100 if (length != m_Length) {
101 return false;
102 } else if (!s) {
103 return false;
104 }
105
106 return !StringMatchN(s, m_String, m_Length);
107}
108
109size_t StringView::length() const {
110 return m_Length;
111}
112
113StringView StringView::substring(size_t start, size_t end, bool hashed) const {
114 if (start == 0 && end == m_Length) {
115 return StringView(m_String, m_Length, hashed ? hash() : 0, hashed);
116 }
117
118 if (end > m_Length) {
119 end = m_Length;
120 }
121
122 if ((start > m_Length) || (start >= end)) {
123 return StringView();
124 }
125
126 StringView result(m_String + start, end - start);
127 result.setHashingEnable(hashed);
128 return result;
129}
130
131String StringView::toString() const {
132 return String(m_String, m_Length, true);
133}
134
135char StringView::operator[](size_t index) const {
136#if ADDITIONAL_CHECKS
137 if (UNLIKELY(index >= m_Length)) {
138 ERROR("operator[] - index " << index << " exceeds length " << m_Length);
139 assert(index < m_Length);
140 }
141#endif
142 return m_String[index];
143}
144
145size_t StringView::nextCharacter(size_t c) const {
146 return ::nextCharacter(m_String, c);
147}
148
149size_t StringView::prevCharacter(size_t c) const {
150 return ::prevCharacter(m_String, c);
151}
152
153uint32_t StringView::hash() const {
154 if (m_Hash) {
155 return m_Hash;
156 } else {
157 return computeHash();
158 }
159}
160
161uint32_t StringView::hash() {
162 // Just-in-time hashing (something clearly needs it).
163 if (!m_HashingEnabled) {
164 setHashingEnable(true);
165 }
166 return m_Hash;
167}
168
169const char* StringView::str() const {
170 return m_String;
171}
172
174 m_HashingEnabled = enabled;
175
176 if (!enabled) {
177 m_Hash = 0;
178 } else if (!m_Hash) {
179 m_Hash = computeHash();
180 }
181}
182
183bool StringView::compareHash(const StringView& other) const {
184 if (!(m_HashingEnabled && other.m_HashingEnabled)) {
185 return true;
186 } else {
187 return hash() == other.hash();
188 }
189}
190
191bool StringView::compareHash(const String& other) const {
192 if (!m_HashingEnabled) {
193 return true;
194 } else {
195 return hash() == other.hash();
196 }
197}
198
199uint32_t StringView::computeHash() const {
200 if (!m_Length) {
201 return 0;
202 } else {
203 return spookyHash(m_String, m_Length);
204 }
205}
206
207bool StringView::defaultHashingEnabled() const {
208 return HASH_STRINGVIEWS_BY_DEFAULT;
209}
210
211HashedStringView::HashedStringView(const char* s) : StringView(s) {
212 setHashingEnable(true);
213}
214
215HashedStringView::HashedStringView(const char* s, size_t length) : StringView(s, length) {
216 setHashingEnable(true);
217}
218
219HashedStringView::HashedStringView(const StringView& other) : StringView(other) {
220 setHashingEnable(true);
221}
222
223HashedStringView::HashedStringView(const HashedStringView& other) : StringView(other) {
224 setHashingEnable(true);
225}
226
227HashedStringView::HashedStringView(const String& other) : HashedStringView(other.view()) {
228 setHashingEnable(true);
229}
230
231bool HashedStringView::defaultHashingEnabled() const {
232 return true;
233}
void setHashingEnable(bool enabled)
bool compare(const char *s, size_t length) const
Definition StringView.cc:91
StringView substring(size_t start, size_t end, bool hashed=HASH_STRINGVIEWS_BY_DEFAULT) const