7#include "core/fxcrt/bytestring.h"
17#include "core/fxcrt/check.h"
18#include "core/fxcrt/check_op.h"
19#include "core/fxcrt/fx_codepage.h"
20#include "core/fxcrt/fx_extension.h"
21#include "core/fxcrt/fx_memcpy_wrappers.h"
22#include "core/fxcrt/fx_safe_types.h"
23#include "core/fxcrt/fx_system.h"
24#include "core/fxcrt/span.h"
25#include "core/fxcrt/span_util.h"
26#include "core/fxcrt/string_pool_template.h"
29template class fxcrt::StringViewTemplate<
char>;
30template class fxcrt::StringPoolTemplate<
ByteString>;
35constexpr char kTrimChars[] =
"\x09\x0a\x0b\x0c\x0d\x20";
41static_assert(
sizeof(
ByteString) <=
sizeof(
char*),
42 "Strings must not require more space than pointers");
54 va_copy(argListCopy, argList);
55 int nMaxLen = vsnprintf(
nullptr, 0, pFormat, argListCopy);
64 pdfium::span<
char> buf = ret.GetBuffer(nMaxLen);
70 va_copy(argListCopy, argList);
71 vsnprintf(buf.data(), nMaxLen + 1, pFormat, argListCopy);
74 ret.ReleaseBuffer(ret.GetStringLength());
81 va_start(argList, pFormat);
91 m_pData = StringData::Create(
UNSAFE_BUFFERS(pdfium::make_span(pStr, nLen)));
96 :
ByteString(
reinterpret_cast<
const char*>(pStr), nLen) {}
99 m_pData = StringData::Create(1);
100 m_pData->m_String[0] = ch;
107 if (!bstrc.IsEmpty()) {
108 m_pData = StringData::Create(bstrc.span());
113 FX_SAFE_SIZE_T nSafeLen = str1.GetLength();
114 nSafeLen += str2.GetLength();
116 size_t nNewLen = nSafeLen.ValueOrDie();
120 m_pData = StringData::Create(nNewLen);
121 m_pData->CopyContents(str1.span());
122 m_pData->CopyContentsAt(str1.GetLength(), str2.span());
126 FX_SAFE_SIZE_T nSafeLen = 0;
127 for (
const auto& item : list)
128 nSafeLen += item.GetLength();
130 size_t nNewLen = nSafeLen.ValueOrDie();
134 m_pData = StringData::Create(nNewLen);
137 for (
const auto& item : list) {
138 m_pData->CopyContentsAt(nOffset, item.span());
139 nOffset += item.GetLength();
144 auto str = outStream.str();
146 m_pData = StringData::Create(pdfium::make_span(str));
154 AssignCopy(str, strlen(str));
163 AssignCopy(str.unterminated_c_str(), str.GetLength());
169 if (m_pData != that.m_pData)
170 m_pData = that.m_pData;
176 if (m_pData != that.m_pData)
177 m_pData = std::move(that.m_pData);
184 Concat(str, strlen(str));
196 Concat(str.m_pData->m_String, str.m_pData->m_nDataLength);
203 Concat(str.unterminated_c_str(), str.GetLength());
210 return !ptr || !ptr[0];
213 return m_pData->m_nDataLength == 0;
217 return strlen(ptr) == m_pData->m_nDataLength &&
219 FXSYS_memcmp(ptr, m_pData->m_String, m_pData->m_nDataLength)) == 0;
224 return str.IsEmpty();
228 return m_pData->m_nDataLength == str.GetLength() &&
230 m_pData->m_String, str.unterminated_c_str(), str.GetLength())) ==
235 if (m_pData == other.m_pData)
239 return other.IsEmpty();
244 return other.m_pData->m_nDataLength == m_pData->m_nDataLength &&
245 memcmp(other.m_pData->m_String, m_pData->m_String,
246 m_pData->m_nDataLength) == 0;
250 if (!m_pData && !ptr)
255 size_t len = GetLength();
256 size_t other_len = ptr ? strlen(ptr) : 0;
260 UNSAFE_BUFFERS(FXSYS_memcmp(c_str(), ptr, std::min(len, other_len)));
261 return result < 0 || (result == 0 && len < other_len);
269 if (m_pData == other.m_pData)
272 size_t len = GetLength();
273 size_t other_len = other.GetLength();
277 FXSYS_memcmp(c_str(), other.c_str(), std::min(len, other_len)));
278 return result < 0 || (result == 0 && len < other_len);
283 return str.IsEmpty();
285 if (m_pData->m_nDataLength != str.GetLength()) {
288 pdfium::span<
const uint8_t> this_span = pdfium::as_bytes(m_pData->span());
289 pdfium::span<
const uint8_t> that_span = str.unsigned_span();
290 while (!this_span.empty()) {
291 uint8_t this_char = this_span.front();
292 uint8_t that_char = that_span.front();
293 if (this_char != that_char && tolower(this_char) != tolower(that_char)) {
296 this_span = this_span.subspan(1);
297 that_span = that_span.subspan(1);
303 return m_pData ? m_pData->m_nRefs : 0;
308 return Substr(offset, GetLength() - offset);
315 if (first == 0 && count == m_pData->m_nDataLength) {
318 return ByteString(AsStringView().Substr(first, count));
322 return Substr(0, count);
327 return Substr(GetLength() - count, count);
334 ReallocBeforeWrite(m_pData->m_nDataLength);
335 FXSYS_strlwr(m_pData->m_String);
342 ReallocBeforeWrite(m_pData->m_nDataLength);
343 FXSYS_strupr(m_pData->m_String);
348 return str.IsEmpty() ? 0 : -1;
350 size_t this_len = m_pData->m_nDataLength;
351 size_t that_len = str.GetLength();
352 size_t min_len =
std::min(this_len, that_len);
356 FXSYS_memcmp(m_pData->m_String, str.unterminated_c_str(), min_len));
359 if (this_len == that_len)
361 return this_len < that_len ? -1 : 1;
370 TrimFront(kTrimChars);
374 TrimBack(kTrimChars);
378 return os.write(str.c_str(), str.GetLength());
382 return os.write(str.unterminated_c_str(), str.GetLength());
388 uint32_t dwHashCode = 0;
389 for (ByteStringView::UnsignedType c : str)
390 dwHashCode = 31 * dwHashCode + c;
395 uint32_t dwHashCode = 0;
396 for (ByteStringView::UnsignedType c : str)
397 dwHashCode = 31 * dwHashCode + tolower(c);
402 uint32_t dwHashCode = 0;
403 for (ByteStringView::UnsignedType c : str)
404 dwHashCode = 1313 * dwHashCode + c;
409 uint32_t dwHashCode = 0;
410 for (ByteStringView::UnsignedType c : str)
411 dwHashCode = 1313 * dwHashCode + FXSYS_towlower(c);
uint32_t FX_HashCode_GetLoweredAsIfW(ByteStringView str)
fxcrt::ByteString ByteString
uint32_t FX_HashCode_GetLoweredA(ByteStringView str)
uint32_t FX_HashCode_GetAsIfW(ByteStringView str)
uint32_t FX_HashCode_GetA(ByteStringView str)
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
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 & operator+=(const char *str)
ByteString & operator+=(ByteStringView str)
UNSAFE_BUFFER_USAGE ByteString(const uint8_t *pStr, size_t len)
ByteString & operator=(ByteStringView str)
ByteString(ByteStringView str1, ByteStringView str2)
ByteString & operator=(const char *str)
void TrimWhitespaceFront()
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
bool operator<(const ByteString &other) const
ByteString(const std::initializer_list< ByteStringView > &list)
int Compare(ByteStringView str) const
ByteString(const fxcrt::ostringstream &outStream)
ByteString First(size_t count) const
void TrimWhitespaceBack()
bool operator<(const char *ptr) const
ByteString Last(size_t count) const
#define UNSAFE_BUFFERS(...)
StringViewTemplate< char > ByteStringView
fxcrt::ByteStringView ByteStringView