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
qstringalgorithms_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 Intel Corporation.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:data-parser
4
5#ifndef QSTRINGALGORITHMS_P_H
6#define QSTRINGALGORITHMS_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists for the convenience
13// of internal files. This header file may change from version to version
14// without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include "qspan.h"
20#include "qstring.h"
21#include "qlocale_p.h" // for ascii_isspace
22
24
25template <typename StringType> struct QStringAlgorithms
26{
27 typedef typename StringType::value_type Char;
28 typedef typename StringType::size_type size_type;
29 typedef typename std::remove_cv<StringType>::type NakedStringType;
30 using ViewType =
31 std::conditional_t<std::is_same_v<StringType, QString>, QStringView, QByteArrayView>;
32 using ViewChar = typename ViewType::storage_type;
33 static const bool isConst = std::is_const<StringType>::value;
34
35 static inline bool isSpace(char ch) { return ascii_isspace(ch); }
36 static inline bool isSpace(QChar ch) { return ch.isSpace(); }
37
38 // Surrogate pairs are not handled in either of the functions below. That is
39 // not a problem because there are no space characters (Zs, Zl, Zp) outside the
40 // Basic Multilingual Plane.
41
42 static inline StringType trimmed_helper_inplace(NakedStringType &str, const Char *begin, const Char *end)
43 {
44 // in-place trimming:
45 Char *data = const_cast<Char *>(str.cbegin());
46 if (begin != data)
47 memmove(data, begin, (end - begin) * sizeof(Char));
48 str.resize(end - begin);
49 return std::move(str);
50 }
51
52 static inline StringType trimmed_helper_inplace(const NakedStringType &, const Char *, const Char *)
53 {
54 // can't happen
55 Q_UNREACHABLE_RETURN(StringType());
56 }
57
58 struct TrimPositions {
59 const Char *begin;
60 const Char *end;
61 };
62 // Returns {begin, end} where:
63 // - "begin" refers to the first non-space character
64 // - if there is a sequence of one or more space chacaters at the end,
65 // "end" refers to the first character in that sequence, otherwise
66 // "end" is str.cend()
67 [[nodiscard]] static TrimPositions trimmed_helper_positions(const StringType &str)
68 {
69 const Char *begin = str.cbegin();
70 const Char *end = str.cend();
71 // skip white space from end
72 while (begin < end && isSpace(end[-1]))
73 --end;
74 // skip white space from start
75 while (begin < end && isSpace(*begin))
76 begin++;
77 return {begin, end};
78 }
79
80 static inline StringType trimmed_helper(StringType &str)
81 {
82 const auto [begin, end] = trimmed_helper_positions(str);
83 if (begin == str.cbegin() && end == str.cend())
84 return str;
85 if (!isConst && str.isDetached())
86 return trimmed_helper_inplace(str, begin, end);
87 return StringType(begin, end - begin);
88 }
89
90 static inline StringType simplified_helper(StringType &str)
91 {
92 if (str.isEmpty())
93 return str;
94 const Char *src = str.cbegin();
95 const Char *end = str.cend();
96 NakedStringType result = isConst || !str.isDetached() ?
97 StringType(str.size(), Qt::Uninitialized) :
98 std::move(str);
99
100 Char *dst = const_cast<Char *>(result.cbegin());
101 Char *ptr = dst;
102 bool unmodified = true;
103 while (true) {
104 while (src != end && isSpace(*src))
105 ++src;
106 while (src != end && !isSpace(*src))
107 *ptr++ = *src++;
108 if (src == end)
109 break;
110 if (*src != QChar::Space)
111 unmodified = false;
112 *ptr++ = QChar::Space;
113 }
114 if (ptr != dst && ptr[-1] == QChar::Space)
115 --ptr;
116
117 qsizetype newlen = ptr - dst;
118 if (isConst && newlen == str.size() && unmodified) {
119 // nothing happened, return the original
120 return str;
121 }
122 result.resize(newlen);
123 return result;
124 }
125
126 static inline bool needsReallocate(const StringType &str, qsizetype newSize) noexcept
127 {
128 const auto capacityAtEnd = str.capacity() - str.data_ptr().freeSpaceAtBegin();
129 return newSize > capacityAtEnd;
130 }
131
132 static inline const ViewChar *asUnicodeChar(ViewType v)
133 {
134 if constexpr (sizeof(ViewChar) == sizeof(QChar))
135 return v.utf16();
136 else
137 return v.data();
138 }
139
140 static inline qsizetype newSize(StringType &src, qsizetype bsize,
141 ViewType after, QSpan<const qsizetype> indices)
142 {
143 if (bsize == after.size())
144 return src.size();
145 else if (bsize > after.size()) // shrink
146 return src.size() - indices.size() * (bsize - after.size());
147
148 // bsize < after.size()
149 const qsizetype adjust = indices.size() * (after.size() - bsize);
150 return src.size() + adjust;
151 }
152
153 // {QString,QByteArray}::resize() but without the extra checks
154 static inline void setSize(StringType &src, qsizetype newSize)
155 {
156 Q_ASSERT(src.isDetached());
157 Q_ASSERT(newSize <= src.capacity());
158
159 auto &d = src.data_ptr();
160 d.size = newSize;
161 d.data()[newSize] = '\0';
162 }
163
164 // Instead of detaching, i.e. copying the whole data array then performing the
165 // replacement, create a new buffer, copy `src` and `after` to it and swap it
166 // with `src`.
167 static inline void replace_into_copy(StringType &src, qsizetype bsize,
168 ViewType after, QSpan<const qsizetype> indices,
169 qsizetype newlen)
170 {
171 StringType tmp{newlen, Qt::Uninitialized};
172 auto *to = tmp.data_ptr().data();
173 const auto *a = asUnicodeChar(after);
174 auto *const begin = src.data_ptr().data();
175 auto *first = begin;
176
177 for (auto i : indices) {
178 to = std::copy(first, begin + i, to);
179 to = std::copy(a, a + after.size(), to);
180 first = begin + i + bsize;
181 }
182 std::copy(first, src.data_ptr().end(), to); // remainder
183 src.swap(tmp);
184 }
185
186 static inline void replace_equal_len(StringType &src, [[maybe_unused]] qsizetype bsize,
187 ViewType after, QSpan<const qsizetype> indices)
188 {
189 Q_ASSERT(bsize == after.size());
190 Q_ASSERT(!src.data_ptr().needsDetach());
191
192 const auto *a = asUnicodeChar(after);
193 auto *const begin = src.data_ptr().data();
194 // before and after have the same length, so no reallocation
195 for (auto i : indices)
196 std::copy(a, a + after.size(), begin + i);
197 }
198
199 static inline void replace_shrink(StringType &src, qsizetype bsize, ViewType after,
200 QSpan<const qsizetype> indices)
201 {
202 Q_ASSERT(bsize > after.size());
203 Q_ASSERT(!src.data_ptr().needsDetach());
204
205 const auto *a = asUnicodeChar(after);
206 auto *const begin = src.data_ptr().data(); // data(), without the detach() check
207 auto *const end = begin + src.size();
208 Q_ASSERT(!indices.isEmpty());
209 auto *to = std::copy(a, a + after.size(), begin + indices.front());
210 auto *first = begin + indices.front() + bsize;
211 for (qsizetype i = 1; i < indices.size(); ++i) {
212 auto *last = begin + indices[i];
213 to = std::copy(first, last, to);
214 qsizetype adjust = i * (bsize - after.size());
215 to = std::copy(a, a + after.size(), last - adjust);
216 first = begin + indices[i] + bsize;
217 }
218 to = std::copy(first, end, to);
219 setSize(src,to - begin);
220 }
221
222 static inline void replace_grow(StringType &src, qsizetype bsize, ViewType after,
223 QSpan<const qsizetype> indices, qsizetype newlen)
224 {
225 Q_ASSERT(after.size() > bsize);
226 Q_ASSERT(!src.data_ptr().needsDetach());
227
228 // replace in-place, after is longer than before, so replace from the back
229 const qsizetype oldlen = src.size();
230 const auto *a = asUnicodeChar(after);
231 setSize(src, newlen);
232 auto *const begin = src.data_ptr().data(); // data(), without the detach() check
233 auto *last = begin + oldlen;
234 auto *to = src.data_ptr().end();
235 for (auto i = indices.size() - 1; i >= 0; --i) {
236 auto *first = begin + indices[i] + bsize;
237 to = std::copy_backward(first, last, to);
238 to = std::copy_backward(a, a + after.size(), to);
239 last = begin + indices[i];
240 }
241 }
242
243 static inline void replace_helper(StringType &src, qsizetype bsize, ViewType after,
244 QSpan<const qsizetype> indices)
245 {
246 if (indices.isEmpty())
247 return;
248
249 const qsizetype newlen = newSize(src, bsize, after, indices);
250 if (src.data_ptr().needsDetach()
251 || (bsize < after.size() && needsReallocate(src, newlen))) {
252 // Instead of detaching (which would copy the whole data array) then
253 // performing the replacement, allocate a new string and copy the data
254 // over from `src` and `after` as needed.
255 replace_into_copy(src, bsize, after, indices, newlen);
256 return;
257 }
258
259 // No detaching or reallocation -> change in-place
260 if (bsize == after.size())
261 replace_equal_len(src, bsize, after, indices);
262 else if (bsize > after.size())
263 replace_shrink(src, bsize, after, indices);
264 else // bsize < after.size()
265 replace_grow(src, bsize, after, indices, newlen);
266 }
267};
268
269QT_END_NAMESPACE
270
271#endif // QSTRINGALGORITHMS_P_H
\inmodule QtCore
QDataStream & operator>>(QDataStream &in, QByteArray &ba)
Reads a byte array into ba from the stream in and returns a reference to the stream.
quint16 qChecksum(QByteArrayView data, Qt::ChecksumType standard)
Definition qlist.h:80
static QLatin1StringView scriptToCode(QLocale::Script script)
Definition qlocale.cpp:259
QString toUpper(const QString &str, bool *ok) const
static const QLocalePrivate * get(const QLocale &l)
Definition qlocale_p.h:601
QString toLower(const QString &str, bool *ok) const
quint16 languageId() const
Definition qlocale_p.h:586
static QLocale::Language codeToLanguage(QStringView code, QLocale::LanguageCodeTypes codeTypes=QLocale::AnyLanguageCode) noexcept
Definition qlocale.cpp:109
const QLocaleData *const m_data
Definition qlocale_p.h:619
QLatin1StringView scriptCode() const
Definition qlocale_p.h:596
QLocale::MeasurementSystem measurementSystem() const
Definition qlocale.cpp:3549
quint16 territoryId() const
Definition qlocale_p.h:587
static QLatin1StringView territoryToCode(QLocale::Territory territory)
Definition qlocale.cpp:267
qsizetype m_index
Definition qlocale_p.h:621
static QLocale::Territory codeToTerritory(QStringView code) noexcept
Definition qlocale.cpp:215
static std::array< char, 4 > languageToCode(QLocale::Language language, QLocale::LanguageCodeTypes codeTypes=QLocale::AnyLanguageCode)
Definition qlocale.cpp:234
static QLocale::Script codeToScript(QStringView code) noexcept
Definition qlocale.cpp:209
QLocale::NumberOptions m_numberOptions
Definition qlocale_p.h:622
QLatin1StringView territoryCode() const
Definition qlocale_p.h:598
constexpr QLocalePrivate(const QLocaleData *data, qsizetype index, QLocale::NumberOptions numberOptions=QLocale::DefaultNumberOptions, int refs=0)
Definition qlocale_p.h:580
std::array< char, 4 > languageCode(QLocale::LanguageCodeTypes codeTypes=QLocale::AnyLanguageCode) const
Definition qlocale_p.h:592
static QBasicAtomicInt s_generation
Definition qlocale_p.h:624
QByteArray bcp47Name(char separator='-') const
Definition qlocale.cpp:494
QBasicAtomicInt ref
Definition qlocale_p.h:620
qsizetype fallbackLocaleIndex() const
Definition qlocale_p.h:628
@ StringToAlternateQuotation
Definition qlocale_p.h:181
@ DateTimeToStringShort
Definition qlocale_p.h:169
@ StandaloneMonthNameLong
Definition qlocale_p.h:187
@ ListToSeparatedString
Definition qlocale_p.h:183
@ StandaloneDayNameNarrow
Definition qlocale_p.h:192
@ StandaloneMonthNameNarrow
Definition qlocale_p.h:189
@ StringToStandardQuotation
Definition qlocale_p.h:180
@ StandaloneDayNameShort
Definition qlocale_p.h:191
@ StandaloneDayNameLong
Definition qlocale_p.h:190
@ StandaloneMonthNameShort
Definition qlocale_p.h:188
virtual QLocale fallbackLocale() const
virtual QVariant query(QueryType type, QVariant &&in=QVariant()) const
constexpr char ascii_space_chars[]
Definition qlocale_p.h:91
constexpr auto makeCharacterSetMatch() noexcept
Definition qlocale_p.h:100
static constexpr bool isLowerCaseAscii(char c)
static const quint16 crc_tbl[16]
QByteArray qCompress(const uchar *data, qsizetype nbytes, int compressionLevel)
ZLibOp
@ Decompression
static Q_DECL_COLD_FUNCTION const char * zlibOpAsString(ZLibOp op)
static QByteArray toCase_template(T &input, uchar(*lookup)(uchar))
static void q_fromPercentEncoding(QByteArray *ba, char percent)
int qstrnicmp(const char *str1, qsizetype len1, const char *str2, qsizetype len2)
static qsizetype lastIndexOfHelper(const char *haystack, qsizetype l, const char *needle, qsizetype ol, qsizetype from)
static constexpr bool isUpperCaseAscii(char c)
static QByteArray xxflate(ZLibOp op, QArrayDataPointer< char > out, QByteArrayView input, qxp::function_ref< int(z_stream *) const > init, qxp::function_ref< int(z_stream *, size_t) const > processChunk, qxp::function_ref< void(z_stream *) const > deinit)
static constexpr uchar asciiLower(uchar c)
static qsizetype countCharHelper(QByteArrayView haystack, char needle) noexcept
static constexpr uchar asciiUpper(uchar c)
Q_CORE_EXPORT char * qstrncpy(char *dst, const char *src, size_t len)
Q_CORE_EXPORT int qstrnicmp(const char *, const char *, size_t len)
Q_CORE_EXPORT int qstricmp(const char *, const char *)
Q_CORE_EXPORT char * qstrdup(const char *)
Q_CORE_EXPORT char * qstrcpy(char *dst, const char *src)
Q_DECL_PURE_FUNCTION Q_CORE_EXPORT const void * qmemrchr(const void *s, int needle, size_t n) noexcept
Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2)
#define __has_include(x)
#define __has_feature(x)
bool qt_splitLocaleName(QStringView name, QStringView *lang=nullptr, QStringView *script=nullptr, QStringView *cntry=nullptr) noexcept
Definition qlocale.cpp:662
Q_DECLARE_TYPEINFO(QLocaleData::GroupSizes, Q_PRIMITIVE_TYPE)
Q_DECLARE_TYPEINFO(QLocaleId, Q_PRIMITIVE_TYPE)
qsizetype qt_repeatCount(QStringView s) noexcept
Definition qlocale.cpp:775
constexpr bool ascii_isspace(uchar c) noexcept
Definition qlocale_p.h:647
#define ForEachQLocaleRange(X)
Definition qlocale_p.h:531
QString qt_readEscapedFormatString(QStringView format, qsizetype *idx)
Definition qlocale.cpp:725
StrayCharacterMode
@ TrailingJunkAllowed
@ TrailingJunkProhibited
Q_CORE_EXPORT double qstrntod(const char *s00, qsizetype len, char const **se, bool *ok)
double qstrtod(const char *s00, char const **se, bool *ok)
QSimpleParsedNumber< double > qt_asciiToDouble(const char *num, qsizetype numLen, StrayCharacterMode strayCharMode=TrailingJunkProhibited)
QByteArray qdtoAscii(double d, QLocaleData::DoubleForm form, int precision, bool uppercase)
char * qulltoa2(char *p, qulonglong n, int base)
int wholePartSpace(double d)
QString qdtoBasicLatin(double d, QLocaleData::DoubleForm form, int precision, bool uppercase)
UcsInt unicodeForDigit(uint digit, UcsInt zero)
QString qulltoa(qulonglong l, int base, const QStringView zero)
QSimpleParsedNumber< qulonglong > qstrntoull(const char *nptr, qsizetype size, int base)
void qt_doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, char *buf, qsizetype bufSize, bool &sign, int &length, int &decpt)
QString qulltoBasicLatin(qulonglong l, int base, bool negative)
constexpr size_t qHash(const QSize &s, size_t seed=0) noexcept
Definition qsize.h:191
qregisteruint mask[Extent]
Definition qlocale_p.h:52
static constexpr int WordBits
Definition qlocale_p.h:50
static constexpr int MaxRange
Definition qlocale_p.h:51
constexpr auto maskLocation(uchar c) const noexcept
Definition qlocale_p.h:78
constexpr QCharacterSetMatch(std::string_view set) noexcept
Definition qlocale_p.h:54
constexpr bool matches(uchar c) const noexcept
Definition qlocale_p.h:63
QStringView viewListEntry(const char16_t *table, qsizetype index) const
Definition qlocale_p.h:489
char32_t ucsFirst(const char16_t *table) const
Definition qlocale_p.h:493
QString getData(const char16_t *table) const
Definition qlocale_p.h:475
QString getListEntry(const char16_t *table, qsizetype index) const
Definition qlocale_p.h:485
QStringView viewData(const char16_t *table) const
Definition qlocale_p.h:481
void setZero(QStringView zero)
Definition qlocale_p.h:377
bool fractionalIsGroup() const
Definition qlocale_p.h:439
const GroupSizes & groupSizes() const
Definition qlocale_p.h:403
bool isValid(NumberMode mode) const
Definition qlocale_p.h:405
const GroupSizes grouping
Definition qlocale_p.h:371
qint8 digitValue(char32_t digit) const
Definition qlocale_p.h:418
QString positiveSign() const
Definition qlocale.cpp:1120
static float convertDoubleToFloat(double d, bool *ok)
Definition qlocale_p.h:339
QString groupSeparator() const
Definition qlocale.cpp:1079
QSimpleParsedNumber< qint64 > stringToLongLong(QStringView str, int base, QLocale::NumberOptions options) const
Definition qlocale.cpp:4904
Q_AUTOTEST_EXPORT char32_t zeroUcs() const
Definition qlocale.cpp:1099
quint8 m_grouping_least
Definition qlocale_p.h:572
QString zeroDigit() const
Definition qlocale.cpp:1094
bool numberToCLocale(QStringView s, QLocale::NumberOptions number_options, NumberMode mode, CharBuff *result) const
Definition qlocale.cpp:4630
quint8 m_grouping_higher
Definition qlocale_p.h:571
QString decimalPoint() const
Definition qlocale.cpp:1074
QString doubleToString(double d, int precision=-1, DoubleForm form=DFSignificantDigits, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:4058
static Q_AUTOTEST_EXPORT bool allLocaleDataRows(bool(*check)(qsizetype, const QLocaleData &))
Definition qlocale.cpp:524
quint8 m_weekend_start
Definition qlocale_p.h:568
quint8 m_currency_digits
Definition qlocale_p.h:565
QLocaleId id() const
Definition qlocale_p.h:456
QString listSeparator() const
Definition qlocale.cpp:1089
static QSimpleParsedNumber< quint64 > bytearrayToUnsLongLong(QByteArrayView num, int base)
Definition qlocale.cpp:4951
QString percentSign() const
Definition qlocale.cpp:1084
@ BlankBeforePositive
Definition qlocale_p.h:270
@ AddTrailingZeroes
Definition qlocale_p.h:267
double stringToDouble(QStringView str, bool *ok, QLocale::NumberOptions options) const
Definition qlocale.cpp:4888
QString longLongToString(qint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:4301
@ DoubleScientificMode
Definition qlocale_p.h:281
@ DoubleStandardMode
Definition qlocale_p.h:281
@ DFSignificantDigits
Definition qlocale_p.h:261
quint8 m_first_day_of_week
Definition qlocale_p.h:567
quint8 m_weekend_end
Definition qlocale_p.h:569
quint8 m_currency_rounding
Definition qlocale_p.h:566
QString exponentSeparator() const
Definition qlocale.cpp:1125
QString negativeSign() const
Definition qlocale.cpp:1115
QSimpleParsedNumber< quint64 > stringToUnsLongLong(QStringView str, int base, QLocale::NumberOptions options) const
Definition qlocale.cpp:4915
QString unsLongLongToString(quint64 l, int precision=-1, int base=10, int width=-1, unsigned flags=NoFlags) const
Definition qlocale.cpp:4316
quint8 m_grouping_first
Definition qlocale_p.h:570
QLocaleId withLikelySubtagsAdded() const noexcept
Fill in blank fields of a locale ID.
Definition qlocale.cpp:326
QLocaleId withLikelySubtagsRemoved() const noexcept
Definition qlocale.cpp:415
ushort script_id
Definition qlocale_p.h:242
bool operator==(QLocaleId other) const noexcept
Definition qlocale_p.h:211
bool matchesAll() const noexcept
Definition qlocale_p.h:220
bool isValid() const noexcept
Definition qlocale_p.h:215
bool operator!=(QLocaleId other) const noexcept
Definition qlocale_p.h:213
bool acceptScriptTerritory(QLocaleId other) const noexcept
Definition qlocale_p.h:231
ushort territory_id
Definition qlocale_p.h:242
bool acceptLanguage(quint16 lang) const noexcept
Definition qlocale_p.h:225
ushort language_id
Definition qlocale_p.h:242
CurrencyToStringArgument(const QVariant &v, const QString &s)
Definition qlocale_p.h:138