Move even more code still into StringTemplate.
Put most accessors in the type-agnostic file, along with Remove().
Most of the remaining methods have dependencies on specific functions
that have not been generalized against character types.
Change-Id: I82d4af59add3959760f209feaf28c13f56f55032
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/116431
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
diff --git a/core/fxcrt/bytestring.cpp b/core/fxcrt/bytestring.cpp
index 2dae0d0..f1c5dec 100644
--- a/core/fxcrt/bytestring.cpp
+++ b/core/fxcrt/bytestring.cpp
@@ -99,12 +99,6 @@
ByteString::ByteString(const uint8_t* pStr, size_t nLen)
: ByteString(reinterpret_cast<const char*>(pStr), nLen) {}
-ByteString::ByteString() = default;
-
-ByteString::ByteString(const ByteString& other) = default;
-
-ByteString::ByteString(ByteString&& other) noexcept = default;
-
ByteString::ByteString(char ch) {
m_pData = StringData::Create(1);
m_pData->m_String[0] = ch;
@@ -157,8 +151,6 @@
}
}
-ByteString::~ByteString() = default;
-
ByteString& ByteString::operator=(const char* str) {
if (!str || !str[0])
clear();
@@ -433,40 +425,6 @@
FXSYS_strupr(m_pData->m_String);
}
-size_t ByteString::Remove(char chRemove) {
- if (IsEmpty())
- return 0;
-
- char* pstrSource = m_pData->m_String;
- char* pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
- while (pstrSource < pstrEnd) {
- if (*pstrSource == chRemove)
- break;
- pstrSource++;
- }
- if (pstrSource == pstrEnd)
- return 0;
-
- ptrdiff_t copied = pstrSource - m_pData->m_String;
- ReallocBeforeWrite(m_pData->m_nDataLength);
- pstrSource = m_pData->m_String + copied;
- pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
-
- char* pstrDest = pstrSource;
- while (pstrSource < pstrEnd) {
- if (*pstrSource != chRemove) {
- *pstrDest = *pstrSource;
- pstrDest++;
- }
- pstrSource++;
- }
-
- *pstrDest = 0;
- size_t nCount = static_cast<size_t>(pstrSource - pstrDest);
- m_pData->m_nDataLength -= nCount;
- return nCount;
-}
-
size_t ByteString::Replace(ByteStringView pOld, ByteStringView pNew) {
if (!m_pData || pOld.IsEmpty())
return 0;
diff --git a/core/fxcrt/bytestring.h b/core/fxcrt/bytestring.h
index e698773..1269010 100644
--- a/core/fxcrt/bytestring.h
+++ b/core/fxcrt/bytestring.h
@@ -37,11 +37,13 @@
[[nodiscard]] static ByteString Format(const char* pFormat, ...);
[[nodiscard]] static ByteString FormatV(const char* pFormat, va_list argList);
- ByteString();
- ByteString(const ByteString& other);
+ ByteString() = default;
+ ByteString(const ByteString& other) = default;
// Move-construct a ByteString. After construction, |other| is empty.
- ByteString(ByteString&& other) noexcept;
+ ByteString(ByteString&& other) noexcept = default;
+
+ ~ByteString() = default;
// Make a one-character string from a char.
explicit ByteString(char ch);
@@ -62,59 +64,14 @@
ByteString(const std::initializer_list<ByteStringView>& list);
explicit ByteString(const fxcrt::ostringstream& outStream);
- ~ByteString();
-
// Explicit conversion to C-style string. The result is never nullptr,
// and is always NUL terminated.
// Note: Any subsequent modification of |this| will invalidate the result.
const char* c_str() const { return m_pData ? m_pData->m_String : ""; }
- // Explicit conversion to uint8_t*. May return nullptr.
- // Note: Any subsequent modification of |this| will invalidate the result.
- const uint8_t* raw_str() const {
- return m_pData ? reinterpret_cast<const uint8_t*>(m_pData->m_String)
- : nullptr;
- }
-
- // Explicit conversion to ByteStringView.
- // Note: Any subsequent modification of |this| will invalidate the result.
- ByteStringView AsStringView() const {
- return ByteStringView(raw_str(), GetLength());
- }
-
- // Explicit conversion to span.
- // Note: Any subsequent modification of |this| will invalidate the result.
- pdfium::span<const char> span() const {
- return pdfium::make_span(m_pData ? m_pData->m_String : nullptr,
- GetLength());
- }
- pdfium::span<const uint8_t> raw_span() const {
- return pdfium::make_span(raw_str(), GetLength());
- }
-
- // Note: Any subsequent modification of |this| will invalidate iterators.
- const_iterator begin() const {
- return m_pData ? m_pData->span().begin() : nullptr;
- }
- const_iterator end() const {
- return m_pData ? m_pData->span().end() : nullptr;
- }
-
- // Note: Any subsequent modification of |this| will invalidate iterators.
- const_reverse_iterator rbegin() const {
- return const_reverse_iterator(end());
- }
- const_reverse_iterator rend() const {
- return const_reverse_iterator(begin());
- }
-
- size_t GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; }
size_t GetStringLength() const {
return m_pData ? strlen(m_pData->m_String) : 0;
}
- bool IsEmpty() const { return !GetLength(); }
- bool IsValidIndex(size_t index) const { return index < GetLength(); }
- bool IsValidLength(size_t length) const { return length <= GetLength(); }
int Compare(ByteStringView str) const;
bool EqualNoCase(ByteStringView str) const;
@@ -143,20 +100,6 @@
ByteString& operator+=(const ByteString& str);
ByteString& operator+=(ByteStringView str);
- // CHECK() if index is out of range (via span's operator[]).
- CharType operator[](const size_t index) const {
- CHECK(m_pData);
- return m_pData->span()[index];
- }
-
- // Unlike std::string::front(), this is always safe and returns a
- // NUL char when the string is empty.
- CharType Front() const { return m_pData ? m_pData->Front() : 0; }
-
- // Unlike std::string::back(), this is always safe and returns a
- // NUL char when the string is empty.
- CharType Back() const { return m_pData ? m_pData->Back() : 0; }
-
void SetAt(size_t index, char c);
size_t Insert(size_t index, char ch);
@@ -199,7 +142,6 @@
void TrimRight(ByteStringView targets);
size_t Replace(ByteStringView pOld, ByteStringView pNew);
- size_t Remove(char ch);
uint32_t GetID() const { return AsStringView().GetID(); }
diff --git a/core/fxcrt/string_template.cpp b/core/fxcrt/string_template.cpp
index ec77706..0fb8b3b 100644
--- a/core/fxcrt/string_template.cpp
+++ b/core/fxcrt/string_template.cpp
@@ -63,6 +63,44 @@
}
template <typename T>
+size_t StringTemplate<T>::Remove(T chRemove) {
+ if (IsEmpty()) {
+ return 0;
+ }
+
+ T* pstrSource = m_pData->m_String;
+ T* pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
+ while (pstrSource < pstrEnd) {
+ if (*pstrSource == chRemove) {
+ break;
+ }
+ pstrSource++;
+ }
+ if (pstrSource == pstrEnd) {
+ return 0;
+ }
+
+ ptrdiff_t copied = pstrSource - m_pData->m_String;
+ ReallocBeforeWrite(m_pData->m_nDataLength);
+ pstrSource = m_pData->m_String + copied;
+ pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
+
+ T* pstrDest = pstrSource;
+ while (pstrSource < pstrEnd) {
+ if (*pstrSource != chRemove) {
+ *pstrDest = *pstrSource;
+ pstrDest++;
+ }
+ pstrSource++;
+ }
+
+ *pstrDest = 0;
+ size_t nCount = static_cast<size_t>(pstrSource - pstrDest);
+ m_pData->m_nDataLength -= nCount;
+ return nCount;
+}
+
+template <typename T>
void StringTemplate<T>::ReallocBeforeWrite(size_t nNewLength) {
if (m_pData && m_pData->CanOperateInPlace(nNewLength)) {
return;
diff --git a/core/fxcrt/string_template.h b/core/fxcrt/string_template.h
index c479332..137b0ff 100644
--- a/core/fxcrt/string_template.h
+++ b/core/fxcrt/string_template.h
@@ -9,6 +9,8 @@
#include <stddef.h>
+#include <type_traits>
+
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/string_data_template.h"
#include "core/fxcrt/string_view_template.h"
@@ -21,9 +23,72 @@
class StringTemplate {
public:
using CharType = T;
+ using UnsignedType = typename std::make_unsigned<CharType>::type;
using const_iterator = T*;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+ bool IsEmpty() const { return !GetLength(); }
+ size_t GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; }
+
+ // Explicit conversion to UnsignedType*. May return nullptr.
+ // Note: Any subsequent modification of |this| will invalidate the result.
+ const UnsignedType* raw_str() const {
+ return m_pData ? reinterpret_cast<const UnsignedType*>(m_pData->m_String)
+ : nullptr;
+ }
+
+ // Explicit conversion to ByteStringView.
+ // Note: Any subsequent modification of |this| will invalidate the result.
+ StringViewTemplate<CharType> AsStringView() const {
+ return StringViewTemplate<CharType>(raw_str(), GetLength());
+ }
+
+ // Explicit conversion to span.
+ // Note: Any subsequent modification of |this| will invalidate the result.
+ pdfium::span<const CharType> span() const {
+ return pdfium::make_span(m_pData ? m_pData->m_String : nullptr,
+ GetLength());
+ }
+
+ // Explicit conversion to spans of unsigned types.
+ // Note: Any subsequent modification of |this| will invalidate the result.
+ pdfium::span<const UnsignedType> raw_span() const {
+ return pdfium::make_span(raw_str(), GetLength());
+ }
+
+ // Note: Any subsequent modification of |this| will invalidate iterators.
+ const_iterator begin() const {
+ return m_pData ? m_pData->span().begin() : nullptr;
+ }
+ const_iterator end() const {
+ return m_pData ? m_pData->span().end() : nullptr;
+ }
+
+ // Note: Any subsequent modification of |this| will invalidate iterators.
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+
+ bool IsValidIndex(size_t index) const { return index < GetLength(); }
+ bool IsValidLength(size_t length) const { return length <= GetLength(); }
+
+ // CHECK() if index is out of range (via span's operator[]).
+ CharType operator[](const size_t index) const {
+ CHECK(m_pData);
+ return m_pData->span()[index];
+ }
+
+ // Unlike std::wstring::front(), this is always safe and returns a
+ // NUL char when the string is empty.
+ CharType Front() const { return m_pData ? m_pData->Front() : 0; }
+
+ // Unlike std::wstring::back(), this is always safe and returns a
+ // NUL char when the string is empty.
+ CharType Back() const { return m_pData ? m_pData->Back() : 0; }
+
// Holds on to buffer if possible for later re-use. Use assignment
// to force immediate release if desired.
void clear();
@@ -39,10 +104,20 @@
// to GetBuffer(), to indicate how much of the buffer was actually used.
void ReleaseBuffer(size_t nNewLength);
+ size_t Remove(T ch);
+
protected:
using StringView = StringViewTemplate<T>;
using StringData = StringDataTemplate<T>;
+ StringTemplate() = default;
+ StringTemplate(const StringTemplate& other) = default;
+
+ // Move-construct a StringTemplate. After construction, |other| is empty.
+ StringTemplate(StringTemplate&& other) noexcept = default;
+
+ ~StringTemplate() = default;
+
void ReallocBeforeWrite(size_t nNewLen);
void AllocBeforeWrite(size_t nNewLen);
void AssignCopy(const T* pSrcData, size_t nSrcLen);
diff --git a/core/fxcrt/widestring.cpp b/core/fxcrt/widestring.cpp
index 314c10e..46ad6cb 100644
--- a/core/fxcrt/widestring.cpp
+++ b/core/fxcrt/widestring.cpp
@@ -384,12 +384,6 @@
return ret;
}
-WideString::WideString() = default;
-
-WideString::WideString(const WideString& other) = default;
-
-WideString::WideString(WideString&& other) noexcept = default;
-
WideString::WideString(const wchar_t* pStr, size_t nLen) {
if (nLen) {
m_pData = StringData::Create({pStr, nLen});
@@ -441,8 +435,6 @@
}
}
-WideString::~WideString() = default;
-
WideString& WideString::operator=(const wchar_t* str) {
if (!str || !str[0])
clear();
@@ -748,40 +740,6 @@
FXSYS_wcsupr(m_pData->m_String);
}
-size_t WideString::Remove(wchar_t chRemove) {
- if (IsEmpty())
- return 0;
-
- wchar_t* pstrSource = m_pData->m_String;
- wchar_t* pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
- while (pstrSource < pstrEnd) {
- if (*pstrSource == chRemove)
- break;
- pstrSource++;
- }
- if (pstrSource == pstrEnd)
- return 0;
-
- ptrdiff_t copied = pstrSource - m_pData->m_String;
- ReallocBeforeWrite(m_pData->m_nDataLength);
- pstrSource = m_pData->m_String + copied;
- pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
-
- wchar_t* pstrDest = pstrSource;
- while (pstrSource < pstrEnd) {
- if (*pstrSource != chRemove) {
- *pstrDest = *pstrSource;
- pstrDest++;
- }
- pstrSource++;
- }
-
- *pstrDest = 0;
- size_t count = static_cast<size_t>(pstrSource - pstrDest);
- m_pData->m_nDataLength -= count;
- return count;
-}
-
size_t WideString::Replace(WideStringView pOld, WideStringView pNew) {
if (!m_pData || pOld.IsEmpty())
return 0;
diff --git a/core/fxcrt/widestring.h b/core/fxcrt/widestring.h
index 8cdb69d..eac1d50 100644
--- a/core/fxcrt/widestring.h
+++ b/core/fxcrt/widestring.h
@@ -39,11 +39,13 @@
[[nodiscard]] static WideString FormatV(const wchar_t* lpszFormat,
va_list argList);
- WideString();
- WideString(const WideString& other);
+ WideString() = default;
+ WideString(const WideString& other) = default;
// Move-construct a WideString. After construction, |other| is empty.
- WideString(WideString&& other) noexcept;
+ WideString(WideString&& other) noexcept = default;
+
+ ~WideString() = default;
// Make a one-character string from one wide char.
explicit WideString(wchar_t ch);
@@ -62,8 +64,6 @@
WideString(WideStringView str1, WideStringView str2);
WideString(const std::initializer_list<WideStringView>& list);
- ~WideString();
-
[[nodiscard]] static WideString FromASCII(ByteStringView str);
[[nodiscard]] static WideString FromLatin1(ByteStringView str);
[[nodiscard]] static WideString FromDefANSI(ByteStringView str);
@@ -76,42 +76,10 @@
// Note: Any subsequent modification of |this| will invalidate the result.
const wchar_t* c_str() const { return m_pData ? m_pData->m_String : L""; }
- // Explicit conversion to WideStringView.
- // Note: Any subsequent modification of |this| will invalidate the result.
- WideStringView AsStringView() const {
- return WideStringView(c_str(), GetLength());
- }
- // Explicit conversion to span.
- // Note: Any subsequent modification of |this| will invalidate the result.
- pdfium::span<const wchar_t> span() const {
- return pdfium::make_span(m_pData ? m_pData->m_String : nullptr,
- GetLength());
- }
-
- // Note: Any subsequent modification of |this| will invalidate iterators.
- const_iterator begin() const {
- return m_pData ? m_pData->span().begin() : nullptr;
- }
- const_iterator end() const {
- return m_pData ? m_pData->span().end() : nullptr;
- }
-
- // Note: Any subsequent modification of |this| will invalidate iterators.
- const_reverse_iterator rbegin() const {
- return const_reverse_iterator(end());
- }
- const_reverse_iterator rend() const {
- return const_reverse_iterator(begin());
- }
-
- size_t GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; }
size_t GetStringLength() const {
return m_pData ? wcslen(m_pData->m_String) : 0;
}
- bool IsEmpty() const { return !GetLength(); }
- bool IsValidIndex(size_t index) const { return index < GetLength(); }
- bool IsValidLength(size_t length) const { return length <= GetLength(); }
WideString& operator=(const wchar_t* str);
WideString& operator=(WideStringView str);
@@ -137,20 +105,6 @@
bool operator<(WideStringView str) const;
bool operator<(const WideString& other) const;
- // / CHECK() if index is out of range (via span's operator[]).
- CharType operator[](const size_t index) const {
- CHECK(m_pData);
- return m_pData->span()[index];
- }
-
- // Unlike std::wstring::front(), this is always safe and returns a
- // NUL char when the string is empty.
- CharType Front() const { return m_pData ? m_pData->Front() : 0; }
-
- // Unlike std::wstring::back(), this is always safe and returns a
- // NUL char when the string is empty.
- CharType Back() const { return m_pData ? m_pData->Back() : 0; }
-
void SetAt(size_t index, wchar_t c);
int Compare(const wchar_t* str) const;
@@ -199,7 +153,6 @@
}
size_t Replace(WideStringView pOld, WideStringView pNew);
- size_t Remove(wchar_t ch);
bool IsASCII() const { return AsStringView().IsASCII(); }
bool EqualsASCII(ByteStringView that) const {