Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
string_view_template.h
Go to the documentation of this file.
1// Copyright 2016 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#ifndef CORE_FXCRT_STRING_VIEW_TEMPLATE_H_
8#define CORE_FXCRT_STRING_VIEW_TEMPLATE_H_
9
10#include <ctype.h>
11
12#include <algorithm>
13#include <iterator>
14#include <optional>
15#include <string>
16#include <type_traits>
17
18#include "core/fxcrt/compiler_specific.h"
19#include "core/fxcrt/fx_memcpy_wrappers.h"
20#include "core/fxcrt/fx_system.h"
21#include "core/fxcrt/span.h"
22#include "core/fxcrt/span_util.h"
23
24namespace fxcrt {
25
26// An immutable string with caller-provided storage which must outlive the
27// string itself. These are not necessarily nul-terminated, so that substring
28// extraction (via the Substr(), First(), and Last() methods) is copy-free.
29//
30// String view arguments should be passed by value, since they are small,
31// rather than const-ref, even if they are not modified.
32//
33// Front() and Back() tolerate empty strings and must return NUL in those
34// cases. Substr(), First(), and Last() tolerate out-of-range indices and
35// must return an empty string view in those cases. The aim here is allowing
36// callers to avoid range-checking first.
37template <typename T>
39 public:
40 using CharType = T;
41 using UnsignedType = typename std::make_unsigned<CharType>::type;
42 using const_iterator = const CharType*;
43 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
44
45 constexpr StringViewTemplate() noexcept = default;
46 constexpr StringViewTemplate(const StringViewTemplate& src) noexcept =
47 default;
48
49 // Deliberately implicit to avoid calling on every string literal.
50 // NOLINTNEXTLINE(runtime/explicit)
51 StringViewTemplate(const CharType* ptr) noexcept
52 // SAFETY: from length() function.
54 reinterpret_cast<const UnsignedType*>(ptr),
55 ptr ? std::char_traits<CharType>::length(ptr) : 0))) {}
56
57 explicit constexpr StringViewTemplate(
58 const pdfium::span<const CharType>& other) noexcept {
59 if (!other.empty()) {
60 m_Span = reinterpret_span<const UnsignedType>(other);
61 }
62 }
63
64 template <typename E = typename std::enable_if<
66 explicit constexpr StringViewTemplate(
67 const pdfium::span<const UnsignedType>& other) noexcept {
68 if (!other.empty()) {
69 m_Span = other;
70 }
71 }
72
73 // Deliberately implicit to avoid calling on every char literal.
74 // |ch| must be an lvalue that outlives the StringViewTemplate.
75 // NOLINTNEXTLINE(runtime/explicit)
76 constexpr StringViewTemplate(const CharType& ch) noexcept
77 : m_Span(
79
81 constexpr StringViewTemplate(const CharType* ptr, size_t size) noexcept
82 // SAFETY: propagated to caller via UNSAFE_BUFFER_USAGE.
84 pdfium::make_span(reinterpret_cast<const UnsignedType*>(ptr),
85 size))) {}
86
87 template <typename E = typename std::enable_if<
90 size_t size) noexcept
91 // SAFETY: propagated to caller via UNSAFE_BUFFER_USAGE.
93
95 // SAFETY: caller ensures `src` is nul-terminated so `length()` is correct.
96 m_Span = UNSAFE_BUFFERS(
97 pdfium::make_span(reinterpret_cast<const UnsignedType*>(src),
98 src ? std::char_traits<CharType>::length(src) : 0));
99 return *this;
100 }
101
103 m_Span = src.m_Span;
104 return *this;
105 }
106
108 return reinterpret_cast<const_iterator>(m_Span.begin());
109 }
111 return reinterpret_cast<const_iterator>(m_Span.end());
112 }
119
120 bool operator==(const StringViewTemplate& other) const {
121 return std::equal(m_Span.begin(), m_Span.end(), other.m_Span.begin(),
122 other.m_Span.end());
123 }
124 bool operator==(const CharType* ptr) const {
125 StringViewTemplate other(ptr);
126 return *this == other;
127 }
128 bool operator!=(const CharType* ptr) const { return !(*this == ptr); }
129 bool operator!=(const StringViewTemplate& other) const {
130 return !(*this == other);
131 }
132
133 bool IsASCII() const {
134 for (auto c : *this) {
135 if (c <= 0 || c > 127) // Questionable signedness of |c|.
136 return false;
137 }
138 return true;
139 }
140
141 bool EqualsASCII(const StringViewTemplate<char>& that) const {
142 size_t length = GetLength();
143 if (length != that.GetLength())
144 return false;
145
146 for (size_t i = 0; i < length; ++i) {
147 auto c = (*this)[i];
148 if (c <= 0 || c > 127 || c != that[i]) // Questionable signedness of |c|.
149 return false;
150 }
151 return true;
152 }
153
154 bool EqualsASCIINoCase(const StringViewTemplate<char>& that) const {
155 size_t length = GetLength();
156 if (length != that.GetLength())
157 return false;
158
159 for (size_t i = 0; i < length; ++i) {
160 auto c = (*this)[i];
161 if (c <= 0 || c > 127 || tolower(c) != tolower(that[i]))
162 return false;
163 }
164 return true;
165 }
166
167 uint32_t GetID() const {
168 if (m_Span.empty())
169 return 0;
170
171 uint32_t strid = 0;
172 size_t size = std::min(static_cast<size_t>(4), m_Span.size());
173 for (size_t i = 0; i < size; i++)
174 strid = strid * 256 + m_Span[i];
175
176 return strid << ((4 - size) * 8);
177 }
178
179 pdfium::span<const UnsignedType> unsigned_span() const { return m_Span; }
180 pdfium::span<const CharType> span() const {
181 return reinterpret_span<const CharType>(m_Span);
182 }
184 return m_Span.data();
185 }
187 return reinterpret_cast<const CharType*>(m_Span.data());
188 }
189
190 size_t GetLength() const { return m_Span.size(); }
191 bool IsEmpty() const { return m_Span.empty(); }
192 bool IsValidIndex(size_t index) const { return index < m_Span.size(); }
193 bool IsValidLength(size_t length) const { return length <= m_Span.size(); }
194
195 // CHECK() if index is out of range (via span's operator[]).
196 const UnsignedType& operator[](const size_t index) const {
197 return m_Span[index];
198 }
199
200 // CHECK() if index is out of range (via span's operator[]).
201 CharType CharAt(const size_t index) const {
202 return static_cast<CharType>(m_Span[index]);
203 }
204
205 // Unlike std::string_view::front(), this is always safe and returns a
206 // NUL char when the string is empty.
207 UnsignedType Front() const { return !m_Span.empty() ? m_Span.front() : 0; }
208
209 // Unlike std::string_view::back(), this is always safe and returns a
210 // NUL char when the string is empty.
211 UnsignedType Back() const { return !m_Span.empty() ? m_Span.back() : 0; }
212
214 const auto* found =
215 reinterpret_cast<const UnsignedType*>(std::char_traits<CharType>::find(
216 reinterpret_cast<const CharType*>(m_Span.data()), m_Span.size(),
217 ch));
218
219 return found ? std::optional<size_t>(found - m_Span.data()) : std::nullopt;
220 }
221
222 bool Contains(CharType ch) const { return Find(ch).has_value(); }
223
224 StringViewTemplate Substr(size_t offset) const {
225 // Unsigned underflow is well-defined and out-of-range is handled by
226 // Substr().
227 return Substr(offset, GetLength() - offset);
228 }
229
230 StringViewTemplate Substr(size_t first, size_t count) const {
231 if (!m_Span.data())
232 return StringViewTemplate();
233
234 if (!IsValidIndex(first))
235 return StringViewTemplate();
236
237 if (count == 0 || !IsValidLength(count))
238 return StringViewTemplate();
239
240 if (!IsValidIndex(first + count - 1))
241 return StringViewTemplate();
242
243 // SAFETY: performance-sensitive, checks above equivalent to subspan()'s.
244 return UNSAFE_BUFFERS(StringViewTemplate(m_Span.data() + first, count));
245 }
246
247 StringViewTemplate First(size_t count) const {
248 return Substr(0, count);
249 }
250
251 StringViewTemplate Last(size_t count) const {
252 // Unsigned underflow is well-defined and out-of-range is handled by
253 // Substr().
254 return Substr(GetLength() - count, count);
255 }
256
258 if (IsEmpty())
259 return StringViewTemplate();
260
261 size_t pos = GetLength();
262 while (pos && CharAt(pos - 1) == ch)
263 pos--;
264
265 if (pos == 0)
266 return StringViewTemplate();
267
268 // SAFETY: Loop above keeps `pos` at length of string or less.
269 return UNSAFE_BUFFERS(StringViewTemplate(m_Span.data(), pos));
270 }
271
272 bool operator<(const StringViewTemplate& that) const {
273 const size_t common_size = std::min(m_Span.size(), that.m_Span.size());
274 int result =
275 common_size ? std::char_traits<CharType>::compare(
276 reinterpret_cast<const CharType*>(m_Span.data()),
277 reinterpret_cast<const CharType*>(that.m_Span.data()),
278 common_size)
279 : 0;
280 return result < 0 || (result == 0 && m_Span.size() < that.m_Span.size());
281 }
282
283 bool operator>(const StringViewTemplate& that) const {
284 const size_t common_size = std::min(m_Span.size(), that.m_Span.size());
285 int result =
286 common_size ? std::char_traits<CharType>::compare(
287 reinterpret_cast<const CharType*>(m_Span.data()),
288 reinterpret_cast<const CharType*>(that.m_Span.data()),
289 common_size)
290 : 0;
291 return result > 0 || (result == 0 && m_Span.size() > that.m_Span.size());
292 }
293
294 protected:
295 // This is not a raw_span<> because StringViewTemplates must be passed by
296 // value without introducing BackupRefPtr churn. Also, repeated re-assignment
297 // of substrings of a StringViewTemplate to itself must avoid the same issue.
299
300 private:
301 void* operator new(size_t) throw() { return nullptr; }
302};
303
304template <typename T>
305inline bool operator==(const T* lhs, const StringViewTemplate<T>& rhs) {
306 return rhs == lhs;
307}
308template <typename T>
309inline bool operator!=(const T* lhs, const StringViewTemplate<T>& rhs) {
310 return rhs != lhs;
311}
312template <typename T>
313inline bool operator<(const T* lhs, const StringViewTemplate<T>& rhs) {
314 return rhs > lhs;
315}
316
317extern template class StringViewTemplate<char>;
318extern template class StringViewTemplate<wchar_t>;
319
322
323} // namespace fxcrt
324
327
328#endif // CORE_FXCRT_STRING_VIEW_TEMPLATE_H_
uint32_t FX_HashCode_GetLoweredAsIfW(ByteStringView str)
fxcrt::ByteString ByteString
Definition bytestring.h:180
uint32_t FX_HashCode_GetLoweredA(ByteStringView str)
uint32_t FX_HashCode_GetAsIfW(ByteStringView str)
uint32_t FX_HashCode_GetA(ByteStringView str)
uint32_t GetID() const
Definition bytestring.h:98
ByteString(const char *ptr)
bool EqualNoCase(ByteStringView str) const
static ByteString Format(const char *pFormat,...)
ByteString & operator+=(const ByteString &str)
bool operator!=(ByteStringView str) const
Definition bytestring.h:66
ByteString Substr(size_t first, size_t count) const
bool operator==(ByteStringView str) const
ByteString()=default
intptr_t ReferenceCountForTesting() const
ByteString & operator+=(char ch)
ByteString(ByteStringView bstrc)
static ByteString FormatInteger(int i)
bool operator==(const ByteString &other) const
bool operator==(const char *ptr) const
UNSAFE_BUFFER_USAGE ByteString(const char *pStr, size_t len)
bool operator<(ByteStringView str) const
ByteString(wchar_t)=delete
ByteString & operator+=(const char *str)
ByteString & operator+=(ByteStringView str)
~ByteString()=default
UNSAFE_BUFFER_USAGE ByteString(const uint8_t *pStr, size_t len)
bool operator!=(const ByteString &other) const
Definition bytestring.h:67
ByteString & operator=(ByteStringView str)
ByteString(ByteStringView str1, ByteStringView str2)
ByteString & operator=(const char *str)
static ByteString FormatV(const char *pFormat, va_list argList)
ByteString Substr(size_t offset) const
ByteString & operator=(const ByteString &that)
ByteString & operator=(ByteString &&that) noexcept
ByteString(ByteString &&other) noexcept=default
bool operator<(const ByteString &other) const
ByteString(const std::initializer_list< ByteStringView > &list)
bool operator!=(const char *ptr) const
Definition bytestring.h:65
int Compare(ByteStringView str) const
ByteString(const ByteString &other)=default
ByteString(const fxcrt::ostringstream &outStream)
ByteString First(size_t count) const
bool operator<(const char *ptr) const
ByteString Last(size_t count) const
U * AsRaw() const
Definition retain_ptr.h:106
RetainPtr & operator=(const RetainPtr< U > &that)
Definition retain_ptr.h:88
operator bool() const
Definition retain_ptr.h:147
void Unleak(T *ptr)
Definition retain_ptr.h:128
RetainPtr(std::nullptr_t ptr)
Definition retain_ptr.h:34
void Reset(T *obj=nullptr)
Definition retain_ptr.h:115
bool operator!=(const RetainPtr &that) const
Definition retain_ptr.h:131
void Swap(RetainPtr &that)
Definition retain_ptr.h:124
RetainPtr() noexcept=default
RetainPtr(RetainPtr &&that) noexcept
Definition retain_ptr.h:47
bool operator!=(const U &that) const
Definition retain_ptr.h:139
RetainPtr & operator=(const RetainPtr &that)
Definition retain_ptr.h:71
bool operator==(const RetainPtr &that) const
Definition retain_ptr.h:130
T & operator*() const
Definition retain_ptr.h:148
bool operator==(const U &that) const
Definition retain_ptr.h:134
RetainPtr & operator=(RetainPtr &&that) noexcept
Definition retain_ptr.h:79
T * operator->() const
Definition retain_ptr.h:149
RetainPtr & operator=(RetainPtr< U > &&that) noexcept
Definition retain_ptr.h:98
RetainPtr(const RetainPtr< U > &that)
Definition retain_ptr.h:53
T * Get() const noexcept
Definition retain_ptr.h:122
~RetainPtr()=default
bool operator<(const RetainPtr &that) const
Definition retain_ptr.h:143
RetainPtr(const RetainPtr &that) noexcept
Definition retain_ptr.h:43
operator T*() const noexcept
Definition retain_ptr.h:121
RetainPtr & operator=(std::nullptr_t) noexcept
Definition retain_ptr.h:64
RetainPtr(RetainPtr< U > &&that) noexcept
Definition retain_ptr.h:59
RetainPtr< U > As() const
Definition retain_ptr.h:111
RetainPtr(T *pObj) noexcept
Definition retain_ptr.h:36
bool HasOneRef() const
Definition retain_ptr.h:160
Retainable()=default
virtual ~Retainable()=default
pdfium::span< CharType > alloc_span()
pdfium::span< CharType > span()
pdfium::span< const CharType > span_with_terminator() const
pdfium::span< const CharType > span() const
pdfium::span< CharType > capacity_span()
void CopyContents(const StringDataTemplate &other)
static RetainPtr< StringDataTemplate > Create(size_t nLen)
void CopyContentsAt(size_t offset, pdfium::span< const CharType > str)
void CopyContents(pdfium::span< const CharType > str)
bool CanOperateInPlace(size_t nTotalLen) const
pdfium::span< const CharType > capacity_span() const
pdfium::span< const CharType > alloc_span() const
pdfium::span< T > GetBuffer(size_t nMinBufLength)
size_t Delete(size_t index, size_t count=1)
const_iterator begin() const
void AllocBeforeWrite(size_t nNewLen)
pdfium::span< const UnsignedType > unsigned_span_with_terminator() const
size_t Replace(StringView oldstr, StringView newstr)
StringTemplate(const StringTemplate &other)=default
pdfium::span< const CharType > span_with_terminator() const
StringView AsStringView() const
void ReleaseBuffer(size_t nNewLength)
void Reserve(size_t len)
CharType operator[](const size_t index) const
CharType Front() const
pdfium::span< const UnsignedType > unsigned_span() const
StringDataTemplate< T > StringData
std::optional< size_t > ReverseFind(T ch) const
StringViewTemplate< T > StringView
void AssignCopy(const T *pSrcData, size_t nSrcLen)
RetainPtr< StringData > m_pData
std::optional< size_t > Find(StringView str, size_t start=0) const
void SetAt(size_t index, T ch)
const_reverse_iterator rbegin() const
const_iterator end() const
bool IsValidIndex(size_t index) const
bool Contains(T ch, size_t start=0) const
typename std::make_unsigned< CharType >::type UnsignedType
void TrimBack(StringView targets)
void Trim(StringView targets)
StringTemplate(StringTemplate &&other) noexcept=default
std::reverse_iterator< const_iterator > const_reverse_iterator
bool Contains(StringView str, size_t start=0) const
void Concat(const T *pSrcData, size_t nSrcLen)
CharType Back() const
std::optional< size_t > Find(T ch, size_t start=0) const
size_t GetLength() const
pdfium::span< const CharType > span() const
const UnsignedType * unsigned_str() const
bool IsValidLength(size_t length) const
size_t GetStringLength() const
void ReallocBeforeWrite(size_t nNewLen)
void TrimFront(StringView targets)
size_t Insert(size_t index, T ch)
const_reverse_iterator rend() const
const CharType * c_str() const
bool operator>(const StringViewTemplate &that) const
StringViewTemplate(const CharType *ptr) noexcept
bool operator<(const StringViewTemplate &that) const
bool IsValidLength(size_t length) const
bool operator!=(const CharType *ptr) const
typename std::make_unsigned< CharType >::type UnsignedType
StringViewTemplate TrimmedRight(CharType ch) const
pdfium::span< const UnsignedType > m_Span
bool EqualsASCII(const StringViewTemplate< char > &that) const
std::optional< size_t > Find(CharType ch) const
const CharType * unterminated_c_str() const
bool operator==(const CharType *ptr) const
bool Contains(CharType ch) const
bool EqualsASCIINoCase(const StringViewTemplate< char > &that) const
StringViewTemplate Substr(size_t first, size_t count) const
std::reverse_iterator< const_iterator > const_reverse_iterator
UNSAFE_BUFFER_USAGE constexpr StringViewTemplate(const CharType *ptr, size_t size) noexcept
bool operator==(const StringViewTemplate &other) const
const UnsignedType & operator[](const size_t index) const
StringViewTemplate Last(size_t count) const
const UnsignedType * unterminated_unsigned_str() const
CharType CharAt(const size_t index) const
bool operator!=(const StringViewTemplate &other) const
StringViewTemplate First(size_t count) const
constexpr StringViewTemplate(const pdfium::span< const CharType > &other) noexcept
constexpr StringViewTemplate(const StringViewTemplate &src) noexcept=default
const_iterator begin() const
StringViewTemplate & operator=(const StringViewTemplate &src)
const_reverse_iterator rend() const
StringViewTemplate & operator=(const CharType *src)
StringViewTemplate Substr(size_t offset) const
constexpr StringViewTemplate() noexcept=default
constexpr StringViewTemplate(const CharType &ch) noexcept
UNSAFE_BUFFER_USAGE constexpr StringViewTemplate(const UnsignedType *ptr, size_t size) noexcept
pdfium::span< const CharType > span() const
const_reverse_iterator rbegin() const
bool IsValidIndex(size_t index) const
constexpr StringViewTemplate(const pdfium::span< const UnsignedType > &other) noexcept
pdfium::span< const UnsignedType > unsigned_span() const
#define UNSAFE_BUFFERS(...)
#define TRIVIAL_ABI
#define UNSAFE_BUFFER_USAGE
CRYPT_md5_context CRYPT_MD5Start()
Definition fx_crypt.cpp:164
TEST(FXCRYPT, CryptToBase16)
TEST(FXCRYPT, MD5GenerateEmtpyData)
std::string CryptToBase16(const uint8_t *digest)
Definition hash.cpp:9
bool operator==(const char *lhs, const ByteString &rhs)
Definition bytestring.h:109
bool operator<(const ByteStringView &lhs, const char *rhs)
Definition bytestring.h:127
ByteString operator+(const ByteString &str1, const ByteString &str2)
Definition bytestring.h:146
ByteString operator+(ByteStringView str1, const char *str2)
Definition bytestring.h:134
bool operator<(const ByteStringView &lhs, const ByteString &rhs)
Definition bytestring.h:124
StringViewTemplate< wchar_t > WideStringView
bool operator==(const T *lhs, const StringViewTemplate< T > &rhs)
bool operator<(const T *lhs, const StringViewTemplate< T > &rhs)
ByteString operator+(const ByteString &str1, char ch)
Definition bytestring.h:149
ByteString operator+(const ByteString &str1, const char *str2)
Definition bytestring.h:155
void PrintTo(const ByteString &str, std::ostream *os)
bool operator!=(const T *lhs, const StringViewTemplate< T > &rhs)
ByteString operator+(char ch, const ByteString &str2)
Definition bytestring.h:152
ByteString operator+(const ByteString &str1, ByteStringView str2)
Definition bytestring.h:161
ByteString operator+(const char *str1, const ByteString &str2)
Definition bytestring.h:158
constexpr const wchar_t * EmptyString(wchar_t *)
StringViewTemplate< char > ByteStringView
bool operator!=(ByteStringView lhs, const ByteString &rhs)
Definition bytestring.h:118
bool operator!=(const char *lhs, const ByteString &rhs)
Definition bytestring.h:115
ByteString operator+(ByteStringView str1, ByteStringView str2)
Definition bytestring.h:131
ByteString operator+(ByteStringView str1, char ch)
Definition bytestring.h:140
constexpr const char * EmptyString(char *)
bool operator<(const char *lhs, const ByteString &rhs)
Definition bytestring.h:121
ByteString operator+(char ch, ByteStringView str2)
Definition bytestring.h:143
ByteString operator+(ByteStringView str1, const ByteString &str2)
Definition bytestring.h:164
ByteString operator+(const char *str1, ByteStringView str2)
Definition bytestring.h:137
bool operator==(ByteStringView lhs, const ByteString &rhs)
Definition bytestring.h:112
RetainPtr< T > MakeRetain(Args &&... args)
Definition retain_ptr.h:207
RetainPtr< T > WrapRetain(T *that)
Definition retain_ptr.h:214
#define CHECK(cvref)
fxcrt::ByteStringView ByteStringView
fxcrt::WideStringView WideStringView
void operator()(T *ptr) const
Definition retain_ptr.h:23
size_t operator()(const ByteString &str) const
Definition bytestring.h:191