1 // Copyright 2017 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 #ifndef CORE_FXCRT_WIDESTRING_H_ 8 #define CORE_FXCRT_WIDESTRING_H_ 9 10 #include <stdarg.h> 11 #include <stddef.h> 12 #include <stdint.h> 13 14 #include <iosfwd> 15 #include <utility> 16 17 #include "core/fxcrt/compiler_specific.h" 18 #include "core/fxcrt/span.h" 19 #include "core/fxcrt/string_template.h" 20 21 namespace fxcrt { 22 23 class ByteString; 24 25 // A mutable string with shared buffers using copy-on-write semantics that 26 // avoids the cost of std::string's iterator stability guarantees. 27 // TODO(crbug.com/pdfium/2031): Consider switching to `char16_t` instead. 28 class WideString : public StringTemplate<wchar_t> { 29 public: 30 [[nodiscard]] static WideString FormatInteger(int i); 31 [[nodiscard]] static WideString Format(const wchar_t* pFormat, ...); 32 [[nodiscard]] static WideString FormatV(const wchar_t* lpszFormat, 33 va_list argList); 34 35 WideString() = default; 36 WideString(const WideString& other) = default; 37 38 // Move-construct a WideString. After construction, |other| is empty. 39 WideString(WideString&& other) noexcept = default; 40 41 ~WideString() = default; 42 43 UNSAFE_BUFFER_USAGE WideString(const wchar_t* pStr, size_t len); 44 45 // Make a one-character string from one wide char. 46 explicit WideString(wchar_t ch); 47 48 // Deliberately implicit to avoid calling on every string literal. 49 // NOLINTNEXTLINE(runtime/explicit) 50 WideString(const wchar_t* ptr); 51 52 // No implicit conversions from byte strings. 53 // NOLINTNEXTLINE(runtime/explicit) 54 WideString(char) = delete; 55 56 explicit WideString(WideStringView str); 57 WideString(WideStringView str1, WideStringView str2); 58 WideString(const std::initializer_list<WideStringView>& list); 59 60 [[nodiscard]] static WideString FromASCII(ByteStringView str); 61 [[nodiscard]] static WideString FromLatin1(ByteStringView str); 62 [[nodiscard]] static WideString FromDefANSI(ByteStringView str); 63 [[nodiscard]] static WideString FromUTF8(ByteStringView str); 64 [[nodiscard]] static WideString FromUTF16LE(pdfium::span<const uint8_t> data); 65 [[nodiscard]] static WideString FromUTF16BE(pdfium::span<const uint8_t> data); 66 67 WideString& operator=(const wchar_t* str); 68 WideString& operator=(WideStringView str); 69 WideString& operator=(const WideString& that); 70 71 // Move-assign a WideString. After assignment, |that| is empty. 72 WideString& operator=(WideString&& that) noexcept; 73 74 WideString& operator+=(const wchar_t* str); 75 WideString& operator+=(wchar_t ch); 76 WideString& operator+=(const WideString& str); 77 WideString& operator+=(WideStringView str); 78 79 bool operator==(const wchar_t* ptr) const; 80 bool operator==(WideStringView str) const; 81 bool operator==(const WideString& other) const; 82 83 bool operator!=(const wchar_t* ptr) const { return !(*this == ptr); } 84 bool operator!=(WideStringView str) const { return !(*this == str); } 85 bool operator!=(const WideString& other) const { return !(*this == other); } 86 87 bool operator<(const wchar_t* ptr) const; 88 bool operator<(WideStringView str) const; 89 bool operator<(const WideString& other) const; 90 91 int Compare(const wchar_t* str) const; 92 int Compare(const WideString& str) const; 93 int CompareNoCase(const wchar_t* str) const; 94 95 WideString Substr(size_t offset) const; 96 WideString Substr(size_t first, size_t count) const; 97 WideString First(size_t count) const; 98 WideString Last(size_t count) const; 99 100 void MakeLower(); 101 void MakeUpper(); 102 103 // Trim a canonical set of characters from the widestring. 104 void TrimWhitespace(); 105 void TrimWhitespaceFront(); 106 void TrimWhitespaceBack(); 107 108 int GetInteger() const; 109 IsASCII()110 bool IsASCII() const { return AsStringView().IsASCII(); } EqualsASCII(ByteStringView that)111 bool EqualsASCII(ByteStringView that) const { 112 return AsStringView().EqualsASCII(that); 113 } EqualsASCIINoCase(ByteStringView that)114 bool EqualsASCIINoCase(ByteStringView that) const { 115 return AsStringView().EqualsASCIINoCase(that); 116 } 117 118 ByteString ToASCII() const; 119 ByteString ToLatin1() const; 120 ByteString ToDefANSI() const; 121 ByteString ToUTF8() const; 122 123 // These methods will add \0\0 to the end of the string to represent the 124 // two-byte terminator. These values are part of the string itself, so 125 // GetLength() will include them. 126 ByteString ToUTF16LE() const; 127 ByteString ToUCS2LE() const; 128 129 // Replace the characters &<>'" with HTML entities. 130 WideString EncodeEntities() const; 131 132 protected: 133 intptr_t ReferenceCountForTesting() const; 134 135 friend class WideString_Assign_Test; 136 friend class WideString_ConcatInPlace_Test; 137 friend class WideString_Construct_Test; 138 friend class StringPool_WideString_Test; 139 }; 140 141 inline WideString operator+(WideStringView str1, WideStringView str2) { 142 return WideString(str1, str2); 143 } 144 inline WideString operator+(WideStringView str1, const wchar_t* str2) { 145 return WideString(str1, str2); 146 } 147 inline WideString operator+(const wchar_t* str1, WideStringView str2) { 148 return WideString(str1, str2); 149 } 150 inline WideString operator+(WideStringView str1, wchar_t ch) { 151 return WideString(str1, WideStringView(ch)); 152 } 153 inline WideString operator+(wchar_t ch, WideStringView str2) { 154 return WideString(WideStringView(ch), str2); 155 } 156 inline WideString operator+(const WideString& str1, const WideString& str2) { 157 return WideString(str1.AsStringView(), str2.AsStringView()); 158 } 159 inline WideString operator+(const WideString& str1, wchar_t ch) { 160 return WideString(str1.AsStringView(), WideStringView(ch)); 161 } 162 inline WideString operator+(wchar_t ch, const WideString& str2) { 163 return WideString(WideStringView(ch), str2.AsStringView()); 164 } 165 inline WideString operator+(const WideString& str1, const wchar_t* str2) { 166 return WideString(str1.AsStringView(), str2); 167 } 168 inline WideString operator+(const wchar_t* str1, const WideString& str2) { 169 return WideString(str1, str2.AsStringView()); 170 } 171 inline WideString operator+(const WideString& str1, WideStringView str2) { 172 return WideString(str1.AsStringView(), str2); 173 } 174 inline WideString operator+(WideStringView str1, const WideString& str2) { 175 return WideString(str1, str2.AsStringView()); 176 } 177 inline bool operator==(const wchar_t* lhs, const WideString& rhs) { 178 return rhs == lhs; 179 } 180 inline bool operator==(WideStringView lhs, const WideString& rhs) { 181 return rhs == lhs; 182 } 183 inline bool operator!=(const wchar_t* lhs, const WideString& rhs) { 184 return rhs != lhs; 185 } 186 inline bool operator!=(WideStringView lhs, const WideString& rhs) { 187 return rhs != lhs; 188 } 189 inline bool operator<(const wchar_t* lhs, const WideString& rhs) { 190 return rhs.Compare(lhs) > 0; 191 } 192 193 std::wostream& operator<<(std::wostream& os, const WideString& str); 194 std::ostream& operator<<(std::ostream& os, const WideString& str); 195 std::wostream& operator<<(std::wostream& os, WideStringView str); 196 std::ostream& operator<<(std::ostream& os, WideStringView str); 197 198 // This is declared here for use in gtest-based tests but is defined in a test 199 // support target. This should not be used in production code. Just use 200 // operator<< from above instead. 201 // In some cases, gtest will automatically use operator<< as well, but in this 202 // case, it needs PrintTo() because WideString looks like a container to gtest. 203 void PrintTo(const WideString& str, std::ostream* os); 204 205 } // namespace fxcrt 206 207 using WideString = fxcrt::WideString; 208 209 uint32_t FX_HashCode_GetW(WideStringView str); 210 uint32_t FX_HashCode_GetLoweredW(WideStringView str); 211 212 namespace std { 213 214 template <> 215 struct hash<WideString> { 216 size_t operator()(const WideString& str) const { 217 return FX_HashCode_GetW(str.AsStringView()); 218 } 219 }; 220 221 } // namespace std 222 223 extern template struct std::hash<WideString>; 224 225 #endif // CORE_FXCRT_WIDESTRING_H_ 226