7#include "core/fxcrt/string_template.h"
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"
23 if (nMinBufLength == 0) {
24 return pdfium::span<T>();
31 if (
m_pData->CanOperateInPlace(nMinBufLength)) {
34 nMinBufLength =
std::max(nMinBufLength,
m_pData->m_nDataLength);
35 if (nMinBufLength == 0) {
36 return pdfium::span<T>();
39 pNewData->CopyContents(*
m_pData);
40 pNewData->m_nDataLength =
m_pData->m_nDataLength;
50 nNewLength =
std::min(nNewLength,
m_pData->m_nAllocLength);
51 if (nNewLength == 0) {
56 m_pData->m_nDataLength = nNewLength;
57 m_pData->capacity_span()[nNewLength] = 0;
58 if (
m_pData->m_nAllocLength - nNewLength >= 32) {
62 ReallocBeforeWrite(nNewLength);
68 size_t count = std::count(span().begin(), span().end(), chRemove);
72 ReallocBeforeWrite(m_pData->m_nDataLength);
73 auto src_span =
m_pData->span();
74 auto dst_span =
m_pData->span();
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);
81 src_span = src_span.subspan(1);
83 m_pData->m_nDataLength -= count;
90 const size_t cur_length = GetLength();
91 if (!IsValidLength(index)) {
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;
108 size_t old_length =
m_pData->m_nDataLength;
109 if (count == 0 || index != std::clamp<size_t>(index, 0, old_length)) {
112 size_t removal_length = index + count;
113 if (removal_length > old_length) {
116 ReallocBeforeWrite(old_length);
118 size_t chars_to_copy = old_length - removal_length + 1;
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;
128 DCHECK(IsValidIndex(index));
129 ReallocBeforeWrite(m_pData->m_nDataLength);
135 return Find(StringView(ch), start);
140 size_t start)
const {
144 if (!IsValidIndex(start)) {
147 std::optional<size_t> result =
148 spanpos(
m_pData->span().subspan(start), str.span());
149 if (!result.has_value()) {
152 return start + result.value();
160 size_t nLength =
m_pData->m_nDataLength;
162 if (
m_pData->span()[nLength] == ch) {
177 pdfium::span<
const T> search_span =
m_pData->span();
179 std::optional<size_t> found = spanpos(search_span, oldstr.span());
180 if (!found.has_value()) {
184 search_span = search_span.subspan(found.value() + oldstr.GetLength());
190 size_t nNewLength =
m_pData->m_nDataLength +
191 count * (newstr.GetLength() - oldstr.GetLength());
192 if (nNewLength == 0) {
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());
207 dest_span = spancpy(dest_span, search_span);
208 CHECK(dest_span.empty());
238 if (!
m_pData || targets.IsEmpty()) {
242 size_t len = GetLength();
250 while (i < targets.GetLength() &&
251 targets.CharAt(i) !=
m_pData->span()[pos]) {
254 if (i == targets.GetLength()) {
263 ReallocBeforeWrite(len);
264 size_t nDataLength = len - pos;
267 m_pData->capacity_span().subspan(pos, nDataLength + 1));
268 m_pData->m_nDataLength = nDataLength;
273 if (!
m_pData || targets.IsEmpty()) {
277 size_t pos = GetLength();
284 while (i < targets.GetLength() &&
285 targets.CharAt(i) !=
m_pData->span()[pos - 1]) {
288 if (i == targets.GetLength()) {
293 if (pos <
m_pData->m_nDataLength) {
294 ReallocBeforeWrite(m_pData->m_nDataLength);
305 if (nNewLength == 0) {
311 size_t nCopyLength =
std::min(
m_pData->m_nDataLength, nNewLength);
313 pNewData->CopyContents(
315 pNewData->m_nDataLength = nCopyLength;
317 pNewData->m_nDataLength = 0;
319 pNewData->capacity_span()[pNewData->m_nDataLength] = 0;
328 if (nNewLength == 0) {
337 AllocBeforeWrite(nSrcLen);
340 m_pData->m_nDataLength = nSrcLen;
345 if (!pSrcData || nSrcLen == 0) {
355 if (
m_pData->CanOperateInPlace(
m_pData->m_nDataLength + nSrcLen)) {
357 m_pData->m_nDataLength += nSrcLen;
361 size_t nGrowLen =
std::max(
m_pData->m_nDataLength / 2, nSrcLen);
364 pNewData->CopyContents(*
m_pData);
365 pNewData->CopyContentsAt(
m_pData->m_nDataLength, src_span);
366 pNewData->m_nDataLength =
m_pData->m_nDataLength + nSrcLen;
380template class StringTemplate<
char>;
381template class StringTemplate<
wchar_t>;
pdfium::span< T > GetBuffer(size_t nMinBufLength)
size_t Delete(size_t index, size_t count=1)
void AllocBeforeWrite(size_t nNewLen)
size_t Replace(StringView oldstr, StringView newstr)
void ReleaseBuffer(size_t nNewLength)
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)
void TrimBack(StringView targets)
void Trim(StringView targets)
void Concat(const T *pSrcData, size_t nSrcLen)
std::optional< size_t > Find(T ch, size_t start=0) const
void ReallocBeforeWrite(size_t nNewLen)
void TrimFront(StringView targets)
size_t Insert(size_t index, T ch)
#define UNSAFE_BUFFERS(...)