Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
string_template.cpp
Go to the documentation of this file.
1
// Copyright 2024 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
#
include
"core/fxcrt/string_template.h"
8
9
#
include
<
algorithm
>
10
#
include
<
utility
>
11
12
#
include
"core/fxcrt/check.h"
13
#
include
"core/fxcrt/check_op.h"
14
#
include
"core/fxcrt/compiler_specific.h"
15
#
include
"core/fxcrt/span.h"
16
#
include
"core/fxcrt/span_util.h"
17
18
namespace
fxcrt
{
19
20
template
<
typename
T>
21
pdfium
::
span
<
T
>
StringTemplate
<T>::
GetBuffer
(size_t nMinBufLength) {
22
if
(!
m_pData
) {
23
if
(nMinBufLength == 0) {
24
return
pdfium::span<T>();
25
}
26
m_pData
=
StringData
::Create(nMinBufLength);
27
m_pData
->m_nDataLength = 0;
28
m_pData
->m_String[0] = 0;
29
return
m_pData
->alloc_span();
30
}
31
if
(
m_pData
->CanOperateInPlace(nMinBufLength)) {
32
return
m_pData
->alloc_span();
33
}
34
nMinBufLength =
std
::max(nMinBufLength,
m_pData
->m_nDataLength);
35
if
(nMinBufLength == 0) {
36
return
pdfium::span<T>();
37
}
38
RetainPtr
<
StringData
> pNewData =
StringData
::Create(nMinBufLength);
39
pNewData->CopyContents(*
m_pData
);
40
pNewData->m_nDataLength =
m_pData
->m_nDataLength;
41
m_pData
=
std
::move(pNewData);
42
return
m_pData
->alloc_span();
43
}
44
45
template
<
typename
T>
46
void
StringTemplate
<T>::
ReleaseBuffer
(size_t nNewLength) {
47
if
(!
m_pData
) {
48
return
;
49
}
50
nNewLength =
std
::min(nNewLength,
m_pData
->m_nAllocLength);
51
if
(nNewLength == 0) {
52
clear
(
)
;
53
return
;
54
}
55
DCHECK_EQ
(
m_pData
->m_nRefs, 1);
56
m_pData
->m_nDataLength = nNewLength;
57
m_pData
->capacity_span()[nNewLength] = 0;
58
if
(
m_pData
->m_nAllocLength - nNewLength >= 32) {
59
// Over arbitrary threshold, so pay the price to relocate. Force copy to
60
// always occur by holding a second reference to the string.
61
StringTemplate
preserve(*
this
);
62
ReallocBeforeWrite(nNewLength);
63
}
64
}
65
66
template
<
typename
T>
67
size_t
StringTemplate
<T>::
Remove
(T chRemove) {
68
size_t count =
std
::count(span().begin(), span().end(), chRemove);
69
if
(count == 0) {
70
return
0;
71
}
72
ReallocBeforeWrite(m_pData->m_nDataLength);
73
auto
src_span =
m_pData
->span();
74
auto
dst_span =
m_pData
->span();
75
// Perform self-intersecting copy in forwards order.
76
while
(!src_span.empty()) {
77
if
(src_span[0] != chRemove) {
78
dst_span[0] = src_span[0];
79
dst_span = dst_span.subspan(1);
80
}
81
src_span = src_span.subspan(1);
82
}
83
m_pData
->m_nDataLength -= count;
84
m_pData
->capacity_span()[
m_pData
->m_nDataLength] = 0;
85
return
count;
86
}
87
88
template
<
typename
T>
89
size_t
StringTemplate
<T>::
Insert
(size_t index, T ch) {
90
const
size_t cur_length = GetLength();
91
if
(!IsValidLength(index)) {
92
return
cur_length;
93
}
94
const
size_t new_length = cur_length + 1;
95
ReallocBeforeWrite(new_length);
96
fxcrt
::spanmove(
m_pData
->capacity_span().subspan(index + 1),
97
m_pData
->capacity_span().subspan(index, new_length - index));
98
m_pData
->capacity_span()[index] = ch;
99
m_pData
->m_nDataLength = new_length;
100
return
new_length;
101
}
102
103
template
<
typename
T>
104
size_t
StringTemplate
<T>::
Delete
(size_t index, size_t count) {
105
if
(!
m_pData
) {
106
return
0;
107
}
108
size_t old_length =
m_pData
->m_nDataLength;
109
if
(count == 0 || index != std::clamp<size_t>(index, 0, old_length)) {
110
return
old_length;
111
}
112
size_t removal_length = index + count;
113
if
(removal_length > old_length) {
114
return
old_length;
115
}
116
ReallocBeforeWrite(old_length);
117
// Include the NUL char not accounted for in lengths.
118
size_t chars_to_copy = old_length - removal_length + 1;
119
fxcrt
::spanmove(
120
m_pData
->capacity_span().subspan(index),
121
m_pData
->capacity_span().subspan(removal_length, chars_to_copy));
122
m_pData
->m_nDataLength = old_length - count;
123
return
m_pData
->m_nDataLength;
124
}
125
126
template
<
typename
T>
127
void
StringTemplate
<T>::
SetAt
(size_t index, T ch) {
128
DCHECK
(IsValidIndex(index));
129
ReallocBeforeWrite(m_pData->m_nDataLength);
130
m_pData
->span()[index] = ch;
131
}
132
133
template
<
typename
T>
134
std
::
optional
<
size_t
>
StringTemplate
<T>::
Find
(T ch, size_t start)
const
{
135
return
Find(StringView(ch), start);
136
}
137
138
template
<
typename
T>
139
std
::
optional
<
size_t
>
StringTemplate
<T>::
Find
(
StringView
str,
140
size_t start)
const
{
141
if
(!
m_pData
) {
142
return
std
::nullopt;
143
}
144
if
(!IsValidIndex(start)) {
145
return
std
::nullopt;
146
}
147
std::optional<size_t> result =
148
spanpos(
m_pData
->span().subspan(start), str.span());
149
if
(!result.has_value()) {
150
return
std
::nullopt;
151
}
152
return
start + result.value();
153
}
154
155
template
<
typename
T>
156
std
::
optional
<
size_t
>
StringTemplate
<T>::
ReverseFind
(T ch)
const
{
157
if
(!
m_pData
) {
158
return
std
::nullopt;
159
}
160
size_t nLength =
m_pData
->m_nDataLength;
161
while
(nLength--) {
162
if
(
m_pData
->span()[nLength] == ch) {
163
return
nLength;
164
}
165
}
166
return
std
::nullopt;
167
}
168
169
template
<
typename
T>
170
size_t
StringTemplate
<T>::
Replace
(
StringView
oldstr,
StringView
newstr) {
171
if
(!
m_pData
|| oldstr.IsEmpty()) {
172
return
0;
173
}
174
size_t count = 0;
175
{
176
// Limit span lifetime.
177
pdfium::span<
const
T> search_span =
m_pData
->span();
178
while
(
true
) {
179
std::optional<size_t> found = spanpos(search_span, oldstr.span());
180
if
(!found.has_value()) {
181
break
;
182
}
183
++count;
184
search_span = search_span.subspan(found.value() + oldstr.GetLength());
185
}
186
}
187
if
(count == 0) {
188
return
0;
189
}
190
size_t nNewLength =
m_pData
->m_nDataLength +
191
count * (newstr.GetLength() - oldstr.GetLength());
192
if
(nNewLength == 0) {
193
clear
(
)
;
194
return
count;
195
}
196
RetainPtr
<
StringData
> newstr_data =
StringData
::Create(nNewLength);
197
{
198
// Spans can't outlive StringData buffers.
199
pdfium::span<
const
T> search_span =
m_pData
->span();
200
pdfium::span<T> dest_span = newstr_data->span();
201
for
(size_t i = 0; i < count; i++) {
202
size_t found = spanpos(search_span, oldstr.span()).value();
203
dest_span = spancpy(dest_span, search_span.first(found));
204
dest_span = spancpy(dest_span, newstr.span());
205
search_span = search_span.subspan(found + oldstr.GetLength());
206
}
207
dest_span = spancpy(dest_span, search_span);
208
CHECK
(dest_span.empty());
209
}
210
m_pData
=
std
::move(newstr_data);
211
return
count;
212
}
213
214
template
<
typename
T>
215
void
StringTemplate
<T>::
Trim
(T ch) {
216
TrimFront(ch);
217
TrimBack(ch);
218
}
219
220
template
<
typename
T>
221
void
StringTemplate
<T>::
TrimFront
(T ch) {
222
TrimFront(
StringView
(ch));
223
}
224
225
template
<
typename
T>
226
void
StringTemplate
<T>::
TrimBack
(T ch) {
227
TrimBack(
StringView
(ch));
228
}
229
230
template
<
typename
T>
231
void
StringTemplate
<T>::
Trim
(
StringView
targets) {
232
TrimFront(targets);
233
TrimBack(targets);
234
}
235
236
template
<
typename
T>
237
void
StringTemplate
<T>::
TrimFront
(
StringView
targets) {
238
if
(!
m_pData
|| targets.IsEmpty()) {
239
return
;
240
}
241
242
size_t len = GetLength();
243
if
(len == 0) {
244
return
;
245
}
246
247
size_t pos = 0;
248
while
(pos < len) {
249
size_t i = 0;
250
while
(i < targets.GetLength() &&
251
targets.CharAt(i) !=
m_pData
->span()[pos]) {
252
i++;
253
}
254
if
(i == targets.GetLength()) {
255
break
;
256
}
257
pos++;
258
}
259
if
(!pos) {
260
return
;
261
}
262
263
ReallocBeforeWrite(len);
264
size_t nDataLength = len - pos;
265
// Move the terminating NUL as well.
266
fxcrt
::spanmove(
m_pData
->capacity_span(),
267
m_pData
->capacity_span().subspan(pos, nDataLength + 1));
268
m_pData
->m_nDataLength = nDataLength;
269
}
270
271
template
<
typename
T>
272
void
StringTemplate
<T>::
TrimBack
(
StringView
targets) {
273
if
(!
m_pData
|| targets.IsEmpty()) {
274
return
;
275
}
276
277
size_t pos = GetLength();
278
if
(pos == 0) {
279
return
;
280
}
281
282
while
(pos) {
283
size_t i = 0;
284
while
(i < targets.GetLength() &&
285
targets.CharAt(i) !=
m_pData
->span()[pos - 1]) {
286
i++;
287
}
288
if
(i == targets.GetLength()) {
289
break
;
290
}
291
pos--;
292
}
293
if
(pos <
m_pData
->m_nDataLength) {
294
ReallocBeforeWrite(m_pData->m_nDataLength);
295
m_pData
->m_nDataLength = pos;
296
m_pData
->capacity_span()[
m_pData
->m_nDataLength] = 0;
297
}
298
}
299
300
template
<
typename
T>
301
void
StringTemplate
<T>::
ReallocBeforeWrite
(size_t nNewLength) {
302
if
(
m_pData
&&
m_pData
->CanOperateInPlace(nNewLength)) {
303
return
;
304
}
305
if
(nNewLength == 0) {
306
clear
(
)
;
307
return
;
308
}
309
RetainPtr
<
StringData
> pNewData =
StringData
::Create(nNewLength);
310
if
(
m_pData
) {
311
size_t nCopyLength =
std
::min(
m_pData
->m_nDataLength, nNewLength);
312
// SAFETY: copy of no more than m_nDataLength bytes.
313
pNewData->CopyContents(
314
UNSAFE_BUFFERS
(
pdfium
::make_span(
m_pData
->m_String, nCopyLength)));
315
pNewData->m_nDataLength = nCopyLength;
316
}
else
{
317
pNewData->m_nDataLength = 0;
318
}
319
pNewData->capacity_span()[pNewData->m_nDataLength] = 0;
320
m_pData
=
std
::move(pNewData);
321
}
322
323
template
<
typename
T>
324
void
StringTemplate
<T>::
AllocBeforeWrite
(size_t nNewLength) {
325
if
(
m_pData
&&
m_pData
->CanOperateInPlace(nNewLength)) {
326
return
;
327
}
328
if
(nNewLength == 0) {
329
clear
(
)
;
330
return
;
331
}
332
m_pData
=
StringData
::Create(nNewLength);
333
}
334
335
template
<
typename
T>
336
void
StringTemplate
<T>::
AssignCopy
(
const
T* pSrcData, size_t nSrcLen) {
337
AllocBeforeWrite(nSrcLen);
338
// SAFETY: AllocBeforeWrite() ensures `nSrcLen` bytes available.
339
m_pData
->CopyContents(
UNSAFE_BUFFERS
(
pdfium
::make_span(pSrcData, nSrcLen)));
340
m_pData
->m_nDataLength = nSrcLen;
341
}
342
343
template
<
typename
T>
344
void
StringTemplate
<T>::
Concat
(
const
T* pSrcData, size_t nSrcLen) {
345
if
(!pSrcData || nSrcLen == 0) {
346
return
;
347
}
348
// SAFETY: required from caller.
349
// TODO(tsepez): should be UNSAFE_BUFFER_USAGE or pass span.
350
auto
src_span =
UNSAFE_BUFFERS
(
pdfium
::make_span(pSrcData, nSrcLen));
351
if
(!
m_pData
) {
352
m_pData
=
StringData
::Create(src_span);
353
return
;
354
}
355
if
(
m_pData
->CanOperateInPlace(
m_pData
->m_nDataLength + nSrcLen)) {
356
m_pData
->CopyContentsAt(
m_pData
->m_nDataLength, src_span);
357
m_pData
->m_nDataLength += nSrcLen;
358
return
;
359
}
360
// Increase size by at least 50% to amortize repeated concatenations.
361
size_t nGrowLen =
std
::max(
m_pData
->m_nDataLength / 2, nSrcLen);
362
RetainPtr
<
StringData
> pNewData =
363
StringData
::Create(
m_pData
->m_nDataLength + nGrowLen);
364
pNewData->CopyContents(*
m_pData
);
365
pNewData->CopyContentsAt(
m_pData
->m_nDataLength, src_span);
366
pNewData->m_nDataLength =
m_pData
->m_nDataLength + nSrcLen;
367
m_pData
=
std
::move(pNewData);
368
}
369
370
template
<
typename
T>
371
void
StringTemplate
<T>::
clear
() {
372
if
(
m_pData
&&
m_pData
->CanOperateInPlace(0)) {
373
m_pData
->m_nDataLength = 0;
374
return
;
375
}
376
m_pData
.Reset();
377
}
378
379
// Instantiate.
380
template
class
StringTemplate<
char
>;
381
template
class
StringTemplate<
wchar_t
>;
382
383
}
// namespace fxcrt
DCHECK
#define DCHECK
Definition
check.h:33
DCHECK_EQ
#define DCHECK_EQ(x, y)
Definition
check_op.h:17
fxcrt::RetainPtr
Definition
retain_ptr.h:28
fxcrt::StringTemplate
Definition
string_template.h:32
fxcrt::StringTemplate::GetBuffer
pdfium::span< T > GetBuffer(size_t nMinBufLength)
Definition
string_template.cpp:21
fxcrt::StringTemplate::Delete
size_t Delete(size_t index, size_t count=1)
Definition
string_template.cpp:104
fxcrt::StringTemplate::AllocBeforeWrite
void AllocBeforeWrite(size_t nNewLen)
Definition
string_template.cpp:324
fxcrt::StringTemplate::Replace
size_t Replace(StringView oldstr, StringView newstr)
Definition
string_template.cpp:170
fxcrt::StringTemplate::ReleaseBuffer
void ReleaseBuffer(size_t nNewLength)
Definition
string_template.cpp:46
fxcrt::StringTemplate::clear
void clear()
Definition
string_template.cpp:371
fxcrt::StringTemplate::StringData
StringDataTemplate< T > StringData
Definition
string_template.h:189
fxcrt::StringTemplate::ReverseFind
std::optional< size_t > ReverseFind(T ch) const
Definition
string_template.cpp:156
fxcrt::StringTemplate::StringView
StringViewTemplate< T > StringView
Definition
string_template.h:36
fxcrt::StringTemplate::AssignCopy
void AssignCopy(const T *pSrcData, size_t nSrcLen)
Definition
string_template.cpp:336
fxcrt::StringTemplate::m_pData
RetainPtr< StringData > m_pData
Definition
string_template.h:204
fxcrt::StringTemplate::Find
std::optional< size_t > Find(StringView str, size_t start=0) const
Definition
string_template.cpp:139
fxcrt::StringTemplate::SetAt
void SetAt(size_t index, T ch)
Definition
string_template.cpp:127
fxcrt::StringTemplate::Trim
void Trim(T ch)
Definition
string_template.cpp:215
fxcrt::StringTemplate::TrimBack
void TrimBack(T ch)
Definition
string_template.cpp:226
fxcrt::StringTemplate::TrimBack
void TrimBack(StringView targets)
Definition
string_template.cpp:272
fxcrt::StringTemplate::Trim
void Trim(StringView targets)
Definition
string_template.cpp:231
fxcrt::StringTemplate::Concat
void Concat(const T *pSrcData, size_t nSrcLen)
Definition
string_template.cpp:344
fxcrt::StringTemplate::Find
std::optional< size_t > Find(T ch, size_t start=0) const
Definition
string_template.cpp:134
fxcrt::StringTemplate::ReallocBeforeWrite
void ReallocBeforeWrite(size_t nNewLen)
Definition
string_template.cpp:301
fxcrt::StringTemplate::TrimFront
void TrimFront(StringView targets)
Definition
string_template.cpp:237
fxcrt::StringTemplate::TrimFront
void TrimFront(T ch)
Definition
string_template.cpp:221
fxcrt::StringTemplate::Remove
size_t Remove(T ch)
Definition
string_template.cpp:67
fxcrt::StringTemplate::Insert
size_t Insert(size_t index, T ch)
Definition
string_template.cpp:89
pdfium::CFDETextOutLargeBitmapTest
Definition
cfde_textout_unittest.cpp:117
UNSAFE_BUFFERS
#define UNSAFE_BUFFERS(...)
Definition
compiler_specific.h:95
fxcrt
Definition
stl_util.h:17
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
CHECK
#define CHECK(cvref)
Definition
q23utility.cpp:15
qtwebengine
src
3rdparty
chromium
third_party
pdfium
core
fxcrt
string_template.cpp
Generated on
for Qt by
1.18.0