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/utilities/StringView.h"
21 #include "pedigree/kernel/Log.h"
22 #include "pedigree/kernel/utilities/String.h"
23 #include "pedigree/kernel/utilities/assert.h"
24 #include "pedigree/kernel/utilities/utility.h"
25 
26 StringView::StringView() : m_String(nullptr), m_Length(0), m_HashingEnabled(HASH_STRINGVIEWS_BY_DEFAULT)
27 {
28  m_Hash = 0;
29 }
30 
31 StringView::StringView(const char *s)
32  : m_String(s), m_Length(StringLength(s)), m_Hash(0), m_HashingEnabled(HASH_STRINGVIEWS_BY_DEFAULT)
33 {
34  setHashingEnable(m_HashingEnabled);
35 }
36 
37 StringView::StringView(const char *s, size_t length)
38  : m_String(s), m_Length(length), m_Hash(0), m_HashingEnabled(HASH_STRINGVIEWS_BY_DEFAULT)
39 {
40  setHashingEnable(m_HashingEnabled);
41 }
42 
43 StringView::StringView(const char *s, size_t length, uint32_t hash, bool hashingEnabled)
44  : m_String(s), m_Length(length), m_Hash(hash), m_HashingEnabled(hashingEnabled)
45 {
46 }
47 
48 StringView::StringView(const StringView &other)
49  : m_String(other.m_String), m_Length(other.m_Length), m_Hash(other.m_Hash),
50  m_HashingEnabled(other.m_HashingEnabled)
51 {
52 }
53 
54 StringView::StringView(const String &other) : StringView(other.view())
55 {
56 }
57 
58 StringView::~StringView() = default;
59 
60 StringView &StringView::operator=(const StringView &s)
61 {
62  m_String = s.m_String;
63  m_Length = s.m_Length;
64  m_Hash = s.m_Hash;
65  m_HashingEnabled = s.m_HashingEnabled;
66  return *this;
67 }
68 
69 bool StringView::operator==(const char *s) const
70 {
71  return compare(s, StringLength(s));
72 }
73 
74 bool StringView::operator==(const String &s) const
75 {
76  if (m_Length != s.length())
77  {
78  return false;
79  }
80  else if (!compareHash(s))
81  {
82  return false;
83  }
84 
85  return compare(static_cast<const char *>(s), s.length());
86 }
87 
88 bool StringView::operator==(const StringView &s) const
89 {
90  if (m_Length != s.m_Length)
91  {
92  return false;
93  }
94  else if (!(m_Length && s.m_Length))
95  {
96  return false;
97  }
98  else if (!compareHash(s))
99  {
100  return false;
101  }
102 
103  return !StringMatchN(m_String, s.m_String, m_Length);
104 }
105 
106 bool StringView::compare(const char *s, size_t length) const
107 {
108  if (UNLIKELY(!m_Length))
109  {
110  if (!*s)
111  {
112  // empty strings match
113  return true;
114  }
115  return false;
116  }
117 
118  if (length != m_Length)
119  {
120  return false;
121  }
122 
123  return !StringMatchN(s, m_String, m_Length);
124 }
125 
126 size_t StringView::length() const
127 {
128  return m_Length;
129 }
130 
131 StringView StringView::substring(size_t start, size_t end, bool hashed) const
132 {
133  if (start == 0 && end == m_Length)
134  {
135  return StringView(m_String, m_Length, m_Hash, m_HashingEnabled);
136  }
137 
138  if (end > m_Length)
139  {
140  end = m_Length;
141  }
142 
143  if ((start > m_Length) || (start >= end))
144  {
145  return StringView();
146  }
147 
148  return StringView(m_String + start, end - start);
149 }
150 
151 String StringView::toString() const
152 {
153  return String(m_String, m_Length);
154 }
155 
156 char StringView::operator[](size_t index) const
157 {
158 #ifdef ADDITIONAL_CHECKS
159  if (UNLIKELY(index >= m_Length))
160  {
161  ERROR("operator[] - index " << index << " exceeds length " << m_Length);
162  assert(index < m_Length);
163  }
164 #endif
165  return m_String[index];
166 }
167 
168 size_t StringView::nextCharacter(size_t c) const
169 {
170  return ::nextCharacter(m_String, c);
171 }
172 
173 size_t StringView::prevCharacter(size_t c) const
174 {
175  return ::prevCharacter(m_String, c);
176 }
177 
178 uint32_t StringView::hash() const
179 {
180  if (m_Hash)
181  {
182  return m_Hash;
183  }
184  else
185  {
186  return computeHash();
187  }
188 }
189 
190 uint32_t StringView::hash()
191 {
192  // Just-in-time hashing (something clearly needs it).
193  if (!m_HashingEnabled)
194  {
195  setHashingEnable(true);
196  }
197  return m_Hash;
198 }
199 
200 const char *StringView::str() const
201 {
202  return m_String;
203 }
204 
206 {
207  m_HashingEnabled = enabled;
208 
209  if (!enabled)
210  {
211  m_Hash = 0;
212  }
213  else if (!m_Hash)
214  {
215  m_Hash = computeHash();
216  }
217 }
218 
219 bool StringView::compareHash(const StringView &other) const
220 {
221  if (!(m_HashingEnabled && other.m_HashingEnabled))
222  {
223  return true;
224  }
225  else
226  {
227  return hash() == other.hash();
228  }
229 }
230 
231 bool StringView::compareHash(const String &other) const
232 {
233  if (!m_HashingEnabled)
234  {
235  return true;
236  }
237  else
238  {
239  return hash() == other.hash();
240  }
241 }
242 
243 uint32_t StringView::computeHash() const
244 {
245  if (!m_Length)
246  {
247  return 0;
248  }
249  else
250  {
251  return spookyHash(m_String, m_Length);
252  }
253 }
254 
255 bool StringView::defaultHashingEnabled() const
256 {
257  return HASH_STRINGVIEWS_BY_DEFAULT;
258 }
259 
260 HashedStringView::HashedStringView(const char *s) : StringView(s)
261 {
262  setHashingEnable(true);
263 }
264 
265 HashedStringView::HashedStringView(const char *s, size_t length) : StringView(s, length)
266 {
267  setHashingEnable(true);
268 }
269 
270 HashedStringView::HashedStringView(const StringView &other) : StringView(other)
271 {
272  setHashingEnable(true);
273 }
274 
275 HashedStringView::HashedStringView(const HashedStringView &other) : StringView(other)
276 {
277  setHashingEnable(true);
278 }
279 
280 HashedStringView::HashedStringView(const String &other) : HashedStringView(other.view())
281 {
282  setHashingEnable(true);
283 }
284 
285 bool HashedStringView::defaultHashingEnabled() const
286 {
287  return true;
288 }
StringView substring(size_t start, size_t end, bool hashed=HASH_STRINGVIEWS_BY_DEFAULT) const
Definition: StringView.cc:131
uint32_t hash() const
Definition: String.cc:218
Definition: String.h:49
StringView view() const
Definition: String.cc:880
size_t m_Length
Definition: String.h:208
#define assert(x)
Definition: assert.h:37
uint32_t m_Hash
Definition: String.h:219
String()
Definition: String.cc:27
void computeHash()
Definition: String.cc:849
void setHashingEnable(bool enabled)
Definition: StringView.cc:205
bool compare(const char *s, size_t length) const
Definition: StringView.cc:106
#define ERROR(text)
Definition: Log.h:82