• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 PDFium Authors. All rights reserved.
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_BYTESTRING_H_
8 #define CORE_FXCRT_BYTESTRING_H_
9 
10 #include <functional>
11 #include <iterator>
12 #include <sstream>
13 #include <utility>
14 
15 #include "core/fxcrt/fx_system.h"
16 #include "core/fxcrt/retain_ptr.h"
17 #include "core/fxcrt/string_data_template.h"
18 #include "core/fxcrt/string_view_template.h"
19 #include "third_party/base/optional.h"
20 
21 namespace fxcrt {
22 
23 class ByteString_Concat_Test;
24 class StringPool_ByteString_Test;
25 class WideString;
26 
27 // A mutable string with shared buffers using copy-on-write semantics that
28 // avoids the cost of std::string's iterator stability guarantees.
29 class ByteString {
30  public:
31   using CharType = char;
32   using const_iterator = const CharType*;
33   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
34 
35   static ByteString FormatInteger(int i) WARN_UNUSED_RESULT;
36   static ByteString FormatFloat(float f) WARN_UNUSED_RESULT;
37   static ByteString Format(const char* lpszFormat, ...) WARN_UNUSED_RESULT;
38   static ByteString FormatV(const char* lpszFormat,
39                             va_list argList) WARN_UNUSED_RESULT;
40 
41   ByteString();
42   ByteString(const ByteString& other);
43   ByteString(ByteString&& other) noexcept;
44 
45   // Deliberately implicit to avoid calling on every string literal.
46   // NOLINTNEXTLINE(runtime/explicit)
47   ByteString(char ch);
48   // NOLINTNEXTLINE(runtime/explicit)
49   ByteString(const char* ptr);
50 
51   // No implicit conversions from wide strings.
52   // NOLINTNEXTLINE(runtime/explicit)
53   ByteString(wchar_t) = delete;
54 
55   ByteString(const char* ptr, size_t len);
56   ByteString(const uint8_t* ptr, size_t len);
57 
58   explicit ByteString(const ByteStringView& bstrc);
59   ByteString(const ByteStringView& bstrc1, const ByteStringView& bstrc2);
60   ByteString(const std::initializer_list<ByteStringView>& list);
61   explicit ByteString(const std::ostringstream& outStream);
62 
63   ~ByteString();
64 
clear()65   void clear() { m_pData.Reset(); }
66 
67   static ByteString FromUnicode(const WideString& str) WARN_UNUSED_RESULT;
68 
69   // Explicit conversion to C-style string.
70   // Note: Any subsequent modification of |this| will invalidate the result.
c_str()71   const char* c_str() const { return m_pData ? m_pData->m_String : ""; }
72 
73   // Explicit conversion to uint8_t*.
74   // Note: Any subsequent modification of |this| will invalidate the result.
raw_str()75   const uint8_t* raw_str() const {
76     return m_pData ? reinterpret_cast<const uint8_t*>(m_pData->m_String)
77                    : nullptr;
78   }
79 
80   // Explicit conversion to ByteStringView.
81   // Note: Any subsequent modification of |this| will invalidate the result.
AsStringView()82   ByteStringView AsStringView() const {
83     return ByteStringView(raw_str(), GetLength());
84   }
85 
86   // Note: Any subsequent modification of |this| will invalidate iterators.
begin()87   const_iterator begin() const { return m_pData ? m_pData->m_String : nullptr; }
end()88   const_iterator end() const {
89     return m_pData ? m_pData->m_String + m_pData->m_nDataLength : nullptr;
90   }
91 
92   // Note: Any subsequent modification of |this| will invalidate iterators.
rbegin()93   const_reverse_iterator rbegin() const {
94     return const_reverse_iterator(end());
95   }
rend()96   const_reverse_iterator rend() const {
97     return const_reverse_iterator(begin());
98   }
99 
GetLength()100   size_t GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; }
GetStringLength()101   size_t GetStringLength() const {
102     return m_pData ? strlen(m_pData->m_String) : 0;
103   }
IsEmpty()104   bool IsEmpty() const { return !GetLength(); }
IsValidIndex(size_t index)105   bool IsValidIndex(size_t index) const { return index < GetLength(); }
IsValidLength(size_t length)106   bool IsValidLength(size_t length) const { return length <= GetLength(); }
107 
108   int Compare(const ByteStringView& str) const;
109   bool EqualNoCase(const ByteStringView& str) const;
110 
111   bool operator==(const char* ptr) const;
112   bool operator==(const ByteStringView& str) const;
113   bool operator==(const ByteString& other) const;
114 
115   bool operator!=(const char* ptr) const { return !(*this == ptr); }
116   bool operator!=(const ByteStringView& str) const { return !(*this == str); }
117   bool operator!=(const ByteString& other) const { return !(*this == other); }
118 
119   bool operator<(const char* ptr) const;
120   bool operator<(const ByteStringView& str) const;
121   bool operator<(const ByteString& other) const;
122 
123   const ByteString& operator=(const char* str);
124   const ByteString& operator=(const ByteStringView& bstrc);
125   const ByteString& operator=(const ByteString& stringSrc);
126 
127   const ByteString& operator+=(char ch);
128   const ByteString& operator+=(const char* str);
129   const ByteString& operator+=(const ByteString& str);
130   const ByteString& operator+=(const ByteStringView& bstrc);
131 
132   CharType operator[](const size_t index) const {
133     ASSERT(IsValidIndex(index));
134     return m_pData ? m_pData->m_String[index] : 0;
135   }
136 
First()137   CharType First() const { return GetLength() ? (*this)[0] : 0; }
Last()138   CharType Last() const { return GetLength() ? (*this)[GetLength() - 1] : 0; }
139 
140   void SetAt(size_t index, char c);
141 
142   size_t Insert(size_t index, char ch);
InsertAtFront(char ch)143   size_t InsertAtFront(char ch) { return Insert(0, ch); }
InsertAtBack(char ch)144   size_t InsertAtBack(char ch) { return Insert(GetLength(), ch); }
145   size_t Delete(size_t index, size_t count = 1);
146 
147   void Reserve(size_t len);
148   char* GetBuffer(size_t len);
149   void ReleaseBuffer(size_t len);
150 
151   ByteString Mid(size_t first, size_t count) const;
152   ByteString Left(size_t count) const;
153   ByteString Right(size_t count) const;
154 
155   Optional<size_t> Find(const ByteStringView& lpszSub, size_t start = 0) const;
156   Optional<size_t> Find(char ch, size_t start = 0) const;
157   Optional<size_t> ReverseFind(char ch) const;
158 
159   bool Contains(const ByteStringView& lpszSub, size_t start = 0) const {
160     return Find(lpszSub, start).has_value();
161   }
162 
163   bool Contains(char ch, size_t start = 0) const {
164     return Find(ch, start).has_value();
165   }
166 
167   void MakeLower();
168   void MakeUpper();
169 
170   void Trim();
171   void Trim(char target);
172   void Trim(const ByteStringView& targets);
173 
174   void TrimLeft();
175   void TrimLeft(char target);
176   void TrimLeft(const ByteStringView& targets);
177 
178   void TrimRight();
179   void TrimRight(char target);
180   void TrimRight(const ByteStringView& targets);
181 
182   size_t Replace(const ByteStringView& lpszOld, const ByteStringView& lpszNew);
183 
184   size_t Remove(char ch);
185 
186   WideString UTF8Decode() const;
187 
GetID()188   uint32_t GetID() const { return AsStringView().GetID(); }
189 
190  protected:
191   using StringData = StringDataTemplate<char>;
192 
193   void ReallocBeforeWrite(size_t nNewLen);
194   void AllocBeforeWrite(size_t nNewLen);
195   void AllocCopy(ByteString& dest, size_t nCopyLen, size_t nCopyIndex) const;
196   void AssignCopy(const char* pSrcData, size_t nSrcLen);
197   void Concat(const char* lpszSrcData, size_t nSrcLen);
198 
199   RetainPtr<StringData> m_pData;
200 
201   friend ByteString_Concat_Test;
202   friend class StringPool_ByteString_Test;
203 };
204 
205 inline bool operator==(const char* lhs, const ByteString& rhs) {
206   return rhs == lhs;
207 }
208 inline bool operator==(const ByteStringView& lhs, const ByteString& rhs) {
209   return rhs == lhs;
210 }
211 inline bool operator!=(const char* lhs, const ByteString& rhs) {
212   return rhs != lhs;
213 }
214 inline bool operator!=(const ByteStringView& lhs, const ByteString& rhs) {
215   return rhs != lhs;
216 }
217 inline bool operator<(const char* lhs, const ByteString& rhs) {
218   return rhs.Compare(lhs) > 0;
219 }
220 
221 inline ByteString operator+(const ByteStringView& str1,
222                             const ByteStringView& str2) {
223   return ByteString(str1, str2);
224 }
225 inline ByteString operator+(const ByteStringView& str1, const char* str2) {
226   return ByteString(str1, str2);
227 }
228 inline ByteString operator+(const char* str1, const ByteStringView& str2) {
229   return ByteString(str1, str2);
230 }
231 inline ByteString operator+(const ByteStringView& str1, char ch) {
232   return ByteString(str1, ByteStringView(ch));
233 }
234 inline ByteString operator+(char ch, const ByteStringView& str2) {
235   return ByteString(ch, str2);
236 }
237 inline ByteString operator+(const ByteString& str1, const ByteString& str2) {
238   return ByteString(str1.AsStringView(), str2.AsStringView());
239 }
240 inline ByteString operator+(const ByteString& str1, char ch) {
241   return ByteString(str1.AsStringView(), ByteStringView(ch));
242 }
243 inline ByteString operator+(char ch, const ByteString& str2) {
244   return ByteString(ch, str2.AsStringView());
245 }
246 inline ByteString operator+(const ByteString& str1, const char* str2) {
247   return ByteString(str1.AsStringView(), str2);
248 }
249 inline ByteString operator+(const char* str1, const ByteString& str2) {
250   return ByteString(str1, str2.AsStringView());
251 }
252 inline ByteString operator+(const ByteString& str1,
253                             const ByteStringView& str2) {
254   return ByteString(str1.AsStringView(), str2);
255 }
256 inline ByteString operator+(const ByteStringView& str1,
257                             const ByteString& str2) {
258   return ByteString(str1, str2.AsStringView());
259 }
260 
261 std::ostream& operator<<(std::ostream& os, const ByteString& str);
262 std::ostream& operator<<(std::ostream& os, const ByteStringView& str);
263 
264 }  // namespace fxcrt
265 
266 using ByteString = fxcrt::ByteString;
267 
268 uint32_t FX_HashCode_GetA(const ByteStringView& str, bool bIgnoreCase);
269 
270 namespace std {
271 
272 template <>
273 struct hash<ByteString> {
274   std::size_t operator()(const ByteString& str) const {
275     return FX_HashCode_GetA(str.AsStringView(), false);
276   }
277 };
278 
279 }  // namespace std
280 
281 extern template struct std::hash<ByteString>;
282 
283 #endif  // CORE_FXCRT_BYTESTRING_H_
284