• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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