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
bytestring.cpp
Go to the documentation of this file.
1// Copyright 2014 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/bytestring.h"
8
9#include <ctype.h>
10#include <stddef.h>
11
12#include <algorithm>
13#include <sstream>
14#include <string>
15#include <utility>
16
17#include "core/fxcrt/fx_codepage.h"
18#include "core/fxcrt/fx_extension.h"
19#include "core/fxcrt/fx_memcpy_wrappers.h"
20#include "core/fxcrt/fx_safe_types.h"
21#include "core/fxcrt/fx_system.h"
22#include "core/fxcrt/string_pool_template.h"
23#include "third_party/base/check.h"
24#include "third_party/base/check_op.h"
25#include "third_party/base/containers/span.h"
26
27template class fxcrt::StringDataTemplate<char>;
28template class fxcrt::StringViewTemplate<char>;
29template class fxcrt::StringPoolTemplate<ByteString>;
30template struct std::hash<ByteString>;
31
32namespace {
33
34constexpr char kTrimChars[] = "\x09\x0a\x0b\x0c\x0d\x20";
35
36const char* FX_strstr(const char* haystack,
37 size_t haystack_len,
38 const char* needle,
39 size_t needle_len) {
40 if (needle_len > haystack_len || needle_len == 0)
41 return nullptr;
42
43 const char* end_ptr = haystack + haystack_len - needle_len;
44 while (haystack <= end_ptr) {
45 size_t i = 0;
46 while (true) {
47 if (haystack[i] != needle[i])
48 break;
49
50 i++;
51 if (i == needle_len)
52 return haystack;
53 }
54 haystack++;
55 }
56 return nullptr;
57}
58
59} // namespace
60
61namespace fxcrt {
62
63static_assert(sizeof(ByteString) <= sizeof(char*),
64 "Strings must not require more space than pointers");
65
66// static
68 char buf[32];
69 FXSYS_snprintf(buf, sizeof(buf), "%d", i);
70 return ByteString(buf);
71}
72
73// static
75 char buf[32];
76 return ByteString(buf, FloatToString(f, buf));
77}
78
79// static
80ByteString ByteString::FormatV(const char* pFormat, va_list argList) {
81 va_list argListCopy;
82 va_copy(argListCopy, argList);
83 int nMaxLen = vsnprintf(nullptr, 0, pFormat, argListCopy);
84 va_end(argListCopy);
85
86 if (nMaxLen <= 0)
87 return ByteString();
88
89 ByteString ret;
90 {
91 // Span's lifetime must end before ReleaseBuffer() below.
92 pdfium::span<char> buf = ret.GetBuffer(nMaxLen);
93
94 // In the following two calls, there's always space in the buffer for
95 // a terminating NUL that's not included in nMaxLen.
96 memset(buf.data(), 0, nMaxLen + 1);
97 va_copy(argListCopy, argList);
98 vsnprintf(buf.data(), nMaxLen + 1, pFormat, argListCopy);
99 va_end(argListCopy);
100 }
101 ret.ReleaseBuffer(ret.GetStringLength());
102 return ret;
103}
104
105// static
106ByteString ByteString::Format(const char* pFormat, ...) {
107 va_list argList;
108 va_start(argList, pFormat);
109 ByteString ret = FormatV(pFormat, argList);
110 va_end(argList);
111
112 return ret;
113}
114
115ByteString::ByteString(const char* pStr, size_t nLen) {
116 if (nLen)
117 m_pData.Reset(StringData::Create(pStr, nLen));
118}
119
120ByteString::ByteString(const uint8_t* pStr, size_t nLen) {
121 if (nLen)
122 m_pData.Reset(
123 StringData::Create(reinterpret_cast<const char*>(pStr), nLen));
124}
125
126ByteString::ByteString() = default;
127
128ByteString::ByteString(const ByteString& other) = default;
129
130ByteString::ByteString(ByteString&& other) noexcept {
131 m_pData.Swap(other.m_pData);
132}
133
135 m_pData.Reset(StringData::Create(1));
136 m_pData->m_String[0] = ch;
137}
138
139ByteString::ByteString(const char* ptr)
140 : ByteString(ptr, ptr ? strlen(ptr) : 0) {}
141
142ByteString::ByteString(ByteStringView bstrc) {
143 if (!bstrc.IsEmpty()) {
144 m_pData.Reset(
145 StringData::Create(bstrc.unterminated_c_str(), bstrc.GetLength()));
146 }
147}
148
149ByteString::ByteString(ByteStringView str1, ByteStringView str2) {
150 FX_SAFE_SIZE_T nSafeLen = str1.GetLength();
151 nSafeLen += str2.GetLength();
152
153 size_t nNewLen = nSafeLen.ValueOrDie();
154 if (nNewLen == 0)
155 return;
156
157 m_pData.Reset(StringData::Create(nNewLen));
158 m_pData->CopyContents(str1.unterminated_c_str(), str1.GetLength());
159 m_pData->CopyContentsAt(str1.GetLength(), str2.unterminated_c_str(),
160 str2.GetLength());
161}
162
163ByteString::ByteString(const std::initializer_list<ByteStringView>& list) {
164 FX_SAFE_SIZE_T nSafeLen = 0;
165 for (const auto& item : list)
166 nSafeLen += item.GetLength();
167
168 size_t nNewLen = nSafeLen.ValueOrDie();
169 if (nNewLen == 0)
170 return;
171
172 m_pData.Reset(StringData::Create(nNewLen));
173
174 size_t nOffset = 0;
175 for (const auto& item : list) {
176 m_pData->CopyContentsAt(nOffset, item.unterminated_c_str(),
177 item.GetLength());
178 nOffset += item.GetLength();
179 }
180}
181
182ByteString::ByteString(const fxcrt::ostringstream& outStream) {
183 auto str = outStream.str();
184 if (!str.empty())
185 m_pData.Reset(StringData::Create(str.c_str(), str.size()));
186}
187
188ByteString::~ByteString() = default;
189
191 if (m_pData && m_pData->CanOperateInPlace(0)) {
192 m_pData->m_nDataLength = 0;
193 return;
194 }
195 m_pData.Reset();
196}
197
198ByteString& ByteString::operator=(const char* str) {
199 if (!str || !str[0])
200 clear();
201 else
202 AssignCopy(str, strlen(str));
203
204 return *this;
205}
206
207ByteString& ByteString::operator=(ByteStringView str) {
208 if (str.IsEmpty())
209 clear();
210 else
211 AssignCopy(str.unterminated_c_str(), str.GetLength());
212
213 return *this;
214}
215
217 if (m_pData != that.m_pData)
218 m_pData = that.m_pData;
219
220 return *this;
221}
222
224 if (m_pData != that.m_pData)
225 m_pData = std::move(that.m_pData);
226
227 return *this;
228}
229
230ByteString& ByteString::operator+=(const char* str) {
231 if (str)
232 Concat(str, strlen(str));
233
234 return *this;
235}
236
238 Concat(&ch, 1);
239 return *this;
240}
241
243 if (str.m_pData)
244 Concat(str.m_pData->m_String, str.m_pData->m_nDataLength);
245
246 return *this;
247}
248
249ByteString& ByteString::operator+=(ByteStringView str) {
250 if (!str.IsEmpty())
251 Concat(str.unterminated_c_str(), str.GetLength());
252
253 return *this;
254}
255
256bool ByteString::operator==(const char* ptr) const {
257 if (!m_pData)
258 return !ptr || !ptr[0];
259
260 if (!ptr)
261 return m_pData->m_nDataLength == 0;
262
263 return strlen(ptr) == m_pData->m_nDataLength &&
264 FXSYS_memcmp(ptr, m_pData->m_String, m_pData->m_nDataLength) == 0;
265}
266
267bool ByteString::operator==(ByteStringView str) const {
268 if (!m_pData)
269 return str.IsEmpty();
270
271 return m_pData->m_nDataLength == str.GetLength() &&
272 FXSYS_memcmp(m_pData->m_String, str.unterminated_c_str(),
273 str.GetLength()) == 0;
274}
275
276bool ByteString::operator==(const ByteString& other) const {
277 if (m_pData == other.m_pData)
278 return true;
279
280 if (IsEmpty())
281 return other.IsEmpty();
282
283 if (other.IsEmpty())
284 return false;
285
286 return other.m_pData->m_nDataLength == m_pData->m_nDataLength &&
287 memcmp(other.m_pData->m_String, m_pData->m_String,
288 m_pData->m_nDataLength) == 0;
289}
290
291bool ByteString::operator<(const char* ptr) const {
292 if (!m_pData && !ptr)
293 return false;
294 if (c_str() == ptr)
295 return false;
296
297 size_t len = GetLength();
298 size_t other_len = ptr ? strlen(ptr) : 0;
299 int result = FXSYS_memcmp(c_str(), ptr, std::min(len, other_len));
300 return result < 0 || (result == 0 && len < other_len);
301}
302
303bool ByteString::operator<(ByteStringView str) const {
304 return Compare(str) < 0;
305}
306
307bool ByteString::operator<(const ByteString& other) const {
308 if (m_pData == other.m_pData)
309 return false;
310
311 size_t len = GetLength();
312 size_t other_len = other.GetLength();
313 int result = FXSYS_memcmp(c_str(), other.c_str(), std::min(len, other_len));
314 return result < 0 || (result == 0 && len < other_len);
315}
316
317bool ByteString::EqualNoCase(ByteStringView str) const {
318 if (!m_pData)
319 return str.IsEmpty();
320
321 size_t len = str.GetLength();
322 if (m_pData->m_nDataLength != len)
323 return false;
324
325 const uint8_t* pThis = (const uint8_t*)m_pData->m_String;
326 const uint8_t* pThat = str.raw_str();
327 for (size_t i = 0; i < len; i++) {
328 if ((*pThis) != (*pThat)) {
329 uint8_t this_char = tolower(*pThis);
330 uint8_t that_char = tolower(*pThat);
331 if (this_char != that_char) {
332 return false;
333 }
334 }
335 pThis++;
336 pThat++;
337 }
338 return true;
339}
340
341void ByteString::AssignCopy(const char* pSrcData, size_t nSrcLen) {
342 AllocBeforeWrite(nSrcLen);
343 m_pData->CopyContents(pSrcData, nSrcLen);
344 m_pData->m_nDataLength = nSrcLen;
345}
346
347void ByteString::ReallocBeforeWrite(size_t nNewLength) {
348 if (m_pData && m_pData->CanOperateInPlace(nNewLength))
349 return;
350
351 if (nNewLength == 0) {
352 clear();
353 return;
354 }
355
356 RetainPtr<StringData> pNewData(StringData::Create(nNewLength));
357 if (m_pData) {
358 size_t nCopyLength = std::min(m_pData->m_nDataLength, nNewLength);
359 pNewData->CopyContents(m_pData->m_String, nCopyLength);
360 pNewData->m_nDataLength = nCopyLength;
361 } else {
362 pNewData->m_nDataLength = 0;
363 }
364 pNewData->m_String[pNewData->m_nDataLength] = 0;
365 m_pData.Swap(pNewData);
366}
367
368void ByteString::AllocBeforeWrite(size_t nNewLength) {
369 if (m_pData && m_pData->CanOperateInPlace(nNewLength))
370 return;
371
372 if (nNewLength == 0) {
373 clear();
374 return;
375 }
376
377 m_pData.Reset(StringData::Create(nNewLength));
378}
379
380void ByteString::ReleaseBuffer(size_t nNewLength) {
381 if (!m_pData)
382 return;
383
384 nNewLength = std::min(nNewLength, m_pData->m_nAllocLength);
385 if (nNewLength == 0) {
386 clear();
387 return;
388 }
389
390 DCHECK_EQ(m_pData->m_nRefs, 1);
391 m_pData->m_nDataLength = nNewLength;
392 m_pData->m_String[nNewLength] = 0;
393 if (m_pData->m_nAllocLength - nNewLength >= 32) {
394 // Over arbitrary threshold, so pay the price to relocate. Force copy to
395 // always occur by holding a second reference to the string.
396 ByteString preserve(*this);
397 ReallocBeforeWrite(nNewLength);
398 }
399}
400
401void ByteString::Reserve(size_t len) {
402 GetBuffer(len);
403}
404
405pdfium::span<char> ByteString::GetBuffer(size_t nMinBufLength) {
406 if (!m_pData) {
407 if (nMinBufLength == 0)
408 return pdfium::span<char>();
409
410 m_pData.Reset(StringData::Create(nMinBufLength));
411 m_pData->m_nDataLength = 0;
412 m_pData->m_String[0] = 0;
413 return pdfium::span<char>(m_pData->m_String, m_pData->m_nAllocLength);
414 }
415
416 if (m_pData->CanOperateInPlace(nMinBufLength))
417 return pdfium::span<char>(m_pData->m_String, m_pData->m_nAllocLength);
418
419 nMinBufLength = std::max(nMinBufLength, m_pData->m_nDataLength);
420 if (nMinBufLength == 0)
421 return pdfium::span<char>();
422
423 RetainPtr<StringData> pNewData(StringData::Create(nMinBufLength));
424 pNewData->CopyContents(*m_pData);
425 pNewData->m_nDataLength = m_pData->m_nDataLength;
426 m_pData.Swap(pNewData);
427 return pdfium::span<char>(m_pData->m_String, m_pData->m_nAllocLength);
428}
429
430size_t ByteString::Delete(size_t index, size_t count) {
431 if (!m_pData)
432 return 0;
433
434 size_t old_length = m_pData->m_nDataLength;
435 if (count == 0 || index != std::clamp<size_t>(index, 0, old_length)) {
436 return old_length;
437 }
438
439 size_t removal_length = index + count;
440 if (removal_length > old_length)
441 return old_length;
442
443 ReallocBeforeWrite(old_length);
444 size_t chars_to_copy = old_length - removal_length + 1;
445 FXSYS_memmove(m_pData->m_String + index, m_pData->m_String + removal_length,
446 chars_to_copy);
447 m_pData->m_nDataLength = old_length - count;
448 return m_pData->m_nDataLength;
449}
450
451void ByteString::Concat(const char* pSrcData, size_t nSrcLen) {
452 if (!pSrcData || nSrcLen == 0)
453 return;
454
455 if (!m_pData) {
456 m_pData.Reset(StringData::Create(pSrcData, nSrcLen));
457 return;
458 }
459
460 if (m_pData->CanOperateInPlace(m_pData->m_nDataLength + nSrcLen)) {
461 m_pData->CopyContentsAt(m_pData->m_nDataLength, pSrcData, nSrcLen);
462 m_pData->m_nDataLength += nSrcLen;
463 return;
464 }
465
466 size_t nConcatLen = std::max(m_pData->m_nDataLength / 2, nSrcLen);
467 RetainPtr<StringData> pNewData(
468 StringData::Create(m_pData->m_nDataLength + nConcatLen));
469 pNewData->CopyContents(*m_pData);
470 pNewData->CopyContentsAt(m_pData->m_nDataLength, pSrcData, nSrcLen);
471 pNewData->m_nDataLength = m_pData->m_nDataLength + nSrcLen;
472 m_pData.Swap(pNewData);
473}
474
476 return m_pData ? m_pData->m_nRefs : 0;
477}
478
479ByteString ByteString::Substr(size_t offset) const {
480 // Unsigned underflow is well-defined and out-of-range is handled by Substr().
481 return Substr(offset, GetLength() - offset);
482}
483
484ByteString ByteString::Substr(size_t first, size_t count) const {
485 if (!m_pData)
486 return ByteString();
487
488 if (!IsValidIndex(first))
489 return ByteString();
490
491 if (count == 0 || !IsValidLength(count))
492 return ByteString();
493
494 if (!IsValidIndex(first + count - 1))
495 return ByteString();
496
497 if (first == 0 && count == m_pData->m_nDataLength)
498 return *this;
499
500 ByteString dest;
501 AllocCopy(dest, count, first);
502 return dest;
503}
504
505ByteString ByteString::First(size_t count) const {
506 return Substr(0, count);
507}
508
509ByteString ByteString::Last(size_t count) const {
510 // Unsigned underflow is well-defined and out-of-range is handled by Substr().
511 return Substr(GetLength() - count, count);
512}
513
515 size_t nCopyLen,
516 size_t nCopyIndex) const {
517 if (nCopyLen == 0)
518 return;
519
520 RetainPtr<StringData> pNewData(
521 StringData::Create(m_pData->m_String + nCopyIndex, nCopyLen));
522 dest.m_pData.Swap(pNewData);
523}
524
525void ByteString::SetAt(size_t index, char c) {
526 DCHECK(IsValidIndex(index));
527 ReallocBeforeWrite(m_pData->m_nDataLength);
528 m_pData->m_String[index] = c;
529}
530
531size_t ByteString::Insert(size_t index, char ch) {
532 const size_t cur_length = GetLength();
533 if (!IsValidLength(index))
534 return cur_length;
535
536 const size_t new_length = cur_length + 1;
537 ReallocBeforeWrite(new_length);
538 FXSYS_memmove(m_pData->m_String + index + 1, m_pData->m_String + index,
539 new_length - index);
540 m_pData->m_String[index] = ch;
541 m_pData->m_nDataLength = new_length;
542 return new_length;
543}
544
545absl::optional<size_t> ByteString::Find(char ch, size_t start) const {
546 if (!m_pData)
547 return absl::nullopt;
548
549 if (!IsValidIndex(start))
550 return absl::nullopt;
551
552 const char* pStr = static_cast<const char*>(FXSYS_memchr(
553 m_pData->m_String + start, ch, m_pData->m_nDataLength - start));
554 return pStr ? absl::optional<size_t>(
555 static_cast<size_t>(pStr - m_pData->m_String))
556 : absl::nullopt;
557}
558
559absl::optional<size_t> ByteString::Find(ByteStringView subStr,
560 size_t start) const {
561 if (!m_pData)
562 return absl::nullopt;
563
564 if (!IsValidIndex(start))
565 return absl::nullopt;
566
567 const char* pStr =
568 FX_strstr(m_pData->m_String + start, m_pData->m_nDataLength - start,
569 subStr.unterminated_c_str(), subStr.GetLength());
570 return pStr ? absl::optional<size_t>(
571 static_cast<size_t>(pStr - m_pData->m_String))
572 : absl::nullopt;
573}
574
576 if (!m_pData)
577 return absl::nullopt;
578
579 size_t nLength = m_pData->m_nDataLength;
580 while (nLength--) {
581 if (m_pData->m_String[nLength] == ch)
582 return nLength;
583 }
584 return absl::nullopt;
585}
586
588 if (IsEmpty())
589 return;
590
591 ReallocBeforeWrite(m_pData->m_nDataLength);
592 FXSYS_strlwr(m_pData->m_String);
593}
594
596 if (IsEmpty())
597 return;
598
599 ReallocBeforeWrite(m_pData->m_nDataLength);
600 FXSYS_strupr(m_pData->m_String);
601}
602
603size_t ByteString::Remove(char chRemove) {
604 if (IsEmpty())
605 return 0;
606
607 char* pstrSource = m_pData->m_String;
608 char* pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
609 while (pstrSource < pstrEnd) {
610 if (*pstrSource == chRemove)
611 break;
612 pstrSource++;
613 }
614 if (pstrSource == pstrEnd)
615 return 0;
616
617 ptrdiff_t copied = pstrSource - m_pData->m_String;
618 ReallocBeforeWrite(m_pData->m_nDataLength);
619 pstrSource = m_pData->m_String + copied;
620 pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
621
622 char* pstrDest = pstrSource;
623 while (pstrSource < pstrEnd) {
624 if (*pstrSource != chRemove) {
625 *pstrDest = *pstrSource;
626 pstrDest++;
627 }
628 pstrSource++;
629 }
630
631 *pstrDest = 0;
632 size_t nCount = static_cast<size_t>(pstrSource - pstrDest);
633 m_pData->m_nDataLength -= nCount;
634 return nCount;
635}
636
637size_t ByteString::Replace(ByteStringView pOld, ByteStringView pNew) {
638 if (!m_pData || pOld.IsEmpty())
639 return 0;
640
641 size_t nSourceLen = pOld.GetLength();
642 size_t nReplacementLen = pNew.GetLength();
643 size_t nCount = 0;
644 const char* pStart = m_pData->m_String;
645 char* pEnd = m_pData->m_String + m_pData->m_nDataLength;
646 while (true) {
647 const char* pTarget = FX_strstr(pStart, static_cast<int>(pEnd - pStart),
648 pOld.unterminated_c_str(), nSourceLen);
649 if (!pTarget)
650 break;
651
652 nCount++;
653 pStart = pTarget + nSourceLen;
654 }
655 if (nCount == 0)
656 return 0;
657
658 size_t nNewLength =
659 m_pData->m_nDataLength + (nReplacementLen - nSourceLen) * nCount;
660
661 if (nNewLength == 0) {
662 clear();
663 return nCount;
664 }
665
666 RetainPtr<StringData> pNewData(StringData::Create(nNewLength));
667 pStart = m_pData->m_String;
668 char* pDest = pNewData->m_String;
669 for (size_t i = 0; i < nCount; i++) {
670 const char* pTarget = FX_strstr(pStart, static_cast<int>(pEnd - pStart),
671 pOld.unterminated_c_str(), nSourceLen);
672 FXSYS_memcpy(pDest, pStart, pTarget - pStart);
673 pDest += pTarget - pStart;
674 FXSYS_memcpy(pDest, pNew.unterminated_c_str(), pNew.GetLength());
675 pDest += pNew.GetLength();
676 pStart = pTarget + nSourceLen;
677 }
678 FXSYS_memcpy(pDest, pStart, pEnd - pStart);
679 m_pData.Swap(pNewData);
680 return nCount;
681}
682
683int ByteString::Compare(ByteStringView str) const {
684 if (!m_pData)
685 return str.IsEmpty() ? 0 : -1;
686
687 size_t this_len = m_pData->m_nDataLength;
688 size_t that_len = str.GetLength();
689 size_t min_len = std::min(this_len, that_len);
690 int result =
691 FXSYS_memcmp(m_pData->m_String, str.unterminated_c_str(), min_len);
692 if (result != 0)
693 return result;
694 if (this_len == that_len)
695 return 0;
696 return this_len < that_len ? -1 : 1;
697}
698
700 TrimRight(kTrimChars);
701 TrimLeft(kTrimChars);
702}
703
704void ByteString::Trim(char target) {
705 ByteStringView targets(target);
706 TrimRight(targets);
707 TrimLeft(targets);
708}
709
710void ByteString::Trim(ByteStringView targets) {
711 TrimRight(targets);
712 TrimLeft(targets);
713}
714
716 TrimLeft(kTrimChars);
717}
718
719void ByteString::TrimLeft(char target) {
720 TrimLeft(ByteStringView(target));
721}
722
723void ByteString::TrimLeft(ByteStringView targets) {
724 if (!m_pData || targets.IsEmpty())
725 return;
726
727 size_t len = GetLength();
728 if (len == 0)
729 return;
730
731 size_t pos = 0;
732 while (pos < len) {
733 size_t i = 0;
734 while (i < targets.GetLength() && targets[i] != m_pData->m_String[pos])
735 i++;
736 if (i == targets.GetLength())
737 break;
738 pos++;
739 }
740 if (pos) {
741 ReallocBeforeWrite(len);
742 size_t nDataLength = len - pos;
743 FXSYS_memmove(m_pData->m_String, m_pData->m_String + pos,
744 (nDataLength + 1) * sizeof(char));
745 m_pData->m_nDataLength = nDataLength;
746 }
747}
748
750 TrimRight(kTrimChars);
751}
752
753void ByteString::TrimRight(char target) {
754 TrimRight(ByteStringView(target));
755}
756
757void ByteString::TrimRight(ByteStringView targets) {
758 if (!m_pData || targets.IsEmpty())
759 return;
760
761 size_t pos = GetLength();
762 if (pos == 0)
763 return;
764
765 while (pos) {
766 size_t i = 0;
767 while (i < targets.GetLength() && targets[i] != m_pData->m_String[pos - 1])
768 i++;
769 if (i == targets.GetLength())
770 break;
771 pos--;
772 }
773 if (pos < m_pData->m_nDataLength) {
774 ReallocBeforeWrite(m_pData->m_nDataLength);
775 m_pData->m_String[pos] = 0;
776 m_pData->m_nDataLength = pos;
777 }
778}
779
780std::ostream& operator<<(std::ostream& os, const ByteString& str) {
781 return os.write(str.c_str(), str.GetLength());
782}
783
784std::ostream& operator<<(std::ostream& os, ByteStringView str) {
785 return os.write(str.unterminated_c_str(), str.GetLength());
786}
787
788} // namespace fxcrt
789
790uint32_t FX_HashCode_GetA(ByteStringView str) {
791 uint32_t dwHashCode = 0;
792 for (ByteStringView::UnsignedType c : str)
793 dwHashCode = 31 * dwHashCode + c;
794 return dwHashCode;
795}
796
797uint32_t FX_HashCode_GetLoweredA(ByteStringView str) {
798 uint32_t dwHashCode = 0;
799 for (ByteStringView::UnsignedType c : str)
800 dwHashCode = 31 * dwHashCode + tolower(c);
801 return dwHashCode;
802}
803
804uint32_t FX_HashCode_GetAsIfW(ByteStringView str) {
805 uint32_t dwHashCode = 0;
806 for (ByteStringView::UnsignedType c : str)
807 dwHashCode = 1313 * dwHashCode + c;
808 return dwHashCode;
809}
810
811uint32_t FX_HashCode_GetLoweredAsIfW(ByteStringView str) {
812 uint32_t dwHashCode = 0;
813 for (ByteStringView::UnsignedType c : str)
814 dwHashCode = 1313 * dwHashCode + FXSYS_towlower(c);
815 return dwHashCode;
816}
uint32_t FX_HashCode_GetLoweredAsIfW(ByteStringView str)
uint32_t FX_HashCode_GetLoweredA(ByteStringView str)
uint32_t FX_HashCode_GetAsIfW(ByteStringView str)
uint32_t FX_HashCode_GetA(ByteStringView str)
void TrimLeft(ByteStringView targets)
static ByteString FormatFloat(float f)
void Reserve(size_t len)
ByteString(const char *ptr)
bool EqualNoCase(ByteStringView str) const
static ByteString Format(const char *pFormat,...)
ByteString & operator+=(const ByteString &str)
ByteString Substr(size_t first, size_t count) const
bool operator==(ByteStringView str) const
void AllocCopy(ByteString &dest, size_t nCopyLen, size_t nCopyIndex) const
void AssignCopy(const char *pSrcData, size_t nSrcLen)
absl::optional< size_t > ReverseFind(char ch) const
intptr_t ReferenceCountForTesting() const
size_t Delete(size_t index, size_t count=1)
ByteString & operator+=(char ch)
void ReallocBeforeWrite(size_t nNewLen)
ByteString(ByteStringView bstrc)
static ByteString FormatInteger(int i)
pdfium::span< char > GetBuffer(size_t nMinBufLength)
void Trim(char target)
bool operator==(const ByteString &other) const
bool operator==(const char *ptr) const
ByteString(const ByteString &other)
size_t Remove(char ch)
ByteString(const char *pStr, size_t len)
bool operator<(ByteStringView str) const
ByteString & operator+=(const char *str)
ByteString & operator+=(ByteStringView str)
ByteString(const uint8_t *pStr, size_t len)
size_t Replace(ByteStringView pOld, ByteStringView pNew)
absl::optional< size_t > Find(ByteStringView subStr, size_t start=0) const
void SetAt(size_t index, char c)
ByteString & operator=(ByteStringView str)
ByteString(ByteStringView str1, ByteStringView str2)
void Trim(ByteStringView targets)
ByteString & operator=(const char *str)
static ByteString FormatV(const char *pFormat, va_list argList)
void TrimRight(char target)
const char * c_str() const
Definition bytestring.h:76
ByteString Substr(size_t offset) const
ByteString & operator=(const ByteString &that)
ByteString & operator=(ByteString &&that) noexcept
bool IsEmpty() const
Definition bytestring.h:119
void TrimRight(ByteStringView targets)
bool operator<(const ByteString &other) const
ByteString(const std::initializer_list< ByteStringView > &list)
int Compare(ByteStringView str) const
size_t Insert(size_t index, char ch)
void ReleaseBuffer(size_t nNewLength)
ByteString(const fxcrt::ostringstream &outStream)
void TrimLeft(char target)
ByteString First(size_t count) const
void AllocBeforeWrite(size_t nNewLen)
bool operator<(const char *ptr) const
void Concat(const char *pSrcData, size_t nSrcLen)
absl::optional< size_t > Find(char ch, size_t start=0) const
ByteString(ByteString &&other) noexcept
ByteString Last(size_t count) const
void * FXSYS_memcpy(void *ptr1, const void *ptr2, size_t len)
#define FXSYS_snprintf
Definition fx_system.h:48