• 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_BYTESTRING_H_
8 #define CORE_FXCRT_BYTESTRING_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/fx_string_wrappers.h"
19 #include "core/fxcrt/string_template.h"
20 
21 namespace fxcrt {
22 
23 // A mutable string with shared buffers using copy-on-write semantics that
24 // avoids the cost of std::string's iterator stability guarantees.
25 class ByteString : public StringTemplate<char> {
26  public:
27   [[nodiscard]] static ByteString FormatInteger(int i);
28   [[nodiscard]] static ByteString Format(const char* pFormat, ...);
29   [[nodiscard]] static ByteString FormatV(const char* pFormat, va_list argList);
30 
31   ByteString() = default;
32   ByteString(const ByteString& other) = default;
33 
34   // Move-construct a ByteString. After construction, |other| is empty.
35   ByteString(ByteString&& other) noexcept = default;
36 
37   ~ByteString() = default;
38 
39   UNSAFE_BUFFER_USAGE ByteString(const char* pStr, size_t len);
40   UNSAFE_BUFFER_USAGE ByteString(const uint8_t* pStr, size_t len);
41 
42   // Make a one-character string from a char.
43   explicit ByteString(char ch);
44 
45   // Deliberately implicit to avoid calling on every string literal.
46   // NOLINTNEXTLINE(runtime/explicit)
47   ByteString(const char* ptr);
48 
49   // No implicit conversions from wide strings.
50   // NOLINTNEXTLINE(runtime/explicit)
51   ByteString(wchar_t) = delete;
52 
53   explicit ByteString(ByteStringView bstrc);
54   ByteString(ByteStringView str1, ByteStringView str2);
55   ByteString(const std::initializer_list<ByteStringView>& list);
56   explicit ByteString(const fxcrt::ostringstream& outStream);
57 
58   int Compare(ByteStringView str) const;
59   bool EqualNoCase(ByteStringView str) const;
60 
61   bool operator==(const char* ptr) const;
62   bool operator==(ByteStringView str) const;
63   bool operator==(const ByteString& other) const;
64 
65   bool operator!=(const char* ptr) const { return !(*this == ptr); }
66   bool operator!=(ByteStringView str) const { return !(*this == str); }
67   bool operator!=(const ByteString& other) const { return !(*this == other); }
68 
69   bool operator<(const char* ptr) const;
70   bool operator<(ByteStringView str) const;
71   bool operator<(const ByteString& other) const;
72 
73   ByteString& operator=(const char* str);
74   ByteString& operator=(ByteStringView str);
75   ByteString& operator=(const ByteString& that);
76 
77   // Move-assign a ByteString. After assignment, |that| is empty.
78   ByteString& operator=(ByteString&& that) noexcept;
79 
80   ByteString& operator+=(char ch);
81   ByteString& operator+=(const char* str);
82   ByteString& operator+=(const ByteString& str);
83   ByteString& operator+=(ByteStringView str);
84 
85   ByteString Substr(size_t offset) const;
86   ByteString Substr(size_t first, size_t count) const;
87   ByteString First(size_t count) const;
88   ByteString Last(size_t count) const;
89 
90   void MakeLower();
91   void MakeUpper();
92 
93   // Remove a canonical set of characters from the string.
94   void TrimWhitespace();
95   void TrimWhitespaceBack();
96   void TrimWhitespaceFront();
97 
GetID()98   uint32_t GetID() const { return AsStringView().GetID(); }
99 
100  protected:
101   intptr_t ReferenceCountForTesting() const;
102 
103   friend class ByteString_Assign_Test;
104   friend class ByteString_Concat_Test;
105   friend class ByteString_Construct_Test;
106   friend class StringPool_ByteString_Test;
107 };
108 
109 inline bool operator==(const char* lhs, const ByteString& rhs) {
110   return rhs == lhs;
111 }
112 inline bool operator==(ByteStringView lhs, const ByteString& rhs) {
113   return rhs == lhs;
114 }
115 inline bool operator!=(const char* lhs, const ByteString& rhs) {
116   return rhs != lhs;
117 }
118 inline bool operator!=(ByteStringView lhs, const ByteString& rhs) {
119   return rhs != lhs;
120 }
121 inline bool operator<(const char* lhs, const ByteString& rhs) {
122   return rhs.Compare(lhs) > 0;
123 }
124 inline bool operator<(const ByteStringView& lhs, const ByteString& rhs) {
125   return rhs.Compare(lhs) > 0;
126 }
127 inline bool operator<(const ByteStringView& lhs, const char* rhs) {
128   return lhs < ByteStringView(rhs);
129 }
130 
131 inline ByteString operator+(ByteStringView str1, ByteStringView str2) {
132   return ByteString(str1, str2);
133 }
134 inline ByteString operator+(ByteStringView str1, const char* str2) {
135   return ByteString(str1, str2);
136 }
137 inline ByteString operator+(const char* str1, ByteStringView str2) {
138   return ByteString(str1, str2);
139 }
140 inline ByteString operator+(ByteStringView str1, char ch) {
141   return ByteString(str1, ByteStringView(ch));
142 }
143 inline ByteString operator+(char ch, ByteStringView str2) {
144   return ByteString(ByteStringView(ch), str2);
145 }
146 inline ByteString operator+(const ByteString& str1, const ByteString& str2) {
147   return ByteString(str1.AsStringView(), str2.AsStringView());
148 }
149 inline ByteString operator+(const ByteString& str1, char ch) {
150   return ByteString(str1.AsStringView(), ByteStringView(ch));
151 }
152 inline ByteString operator+(char ch, const ByteString& str2) {
153   return ByteString(ByteStringView(ch), str2.AsStringView());
154 }
155 inline ByteString operator+(const ByteString& str1, const char* str2) {
156   return ByteString(str1.AsStringView(), str2);
157 }
158 inline ByteString operator+(const char* str1, const ByteString& str2) {
159   return ByteString(str1, str2.AsStringView());
160 }
161 inline ByteString operator+(const ByteString& str1, ByteStringView str2) {
162   return ByteString(str1.AsStringView(), str2);
163 }
164 inline ByteString operator+(ByteStringView str1, const ByteString& str2) {
165   return ByteString(str1, str2.AsStringView());
166 }
167 
168 std::ostream& operator<<(std::ostream& os, const ByteString& str);
169 std::ostream& operator<<(std::ostream& os, ByteStringView str);
170 
171 // This is declared here for use in gtest-based tests but is defined in a test
172 // support target. This should not be used in production code. Just use
173 // operator<< from above instead.
174 // In some cases, gtest will automatically use operator<< as well, but in this
175 // case, it needs PrintTo() because ByteString looks like a container to gtest.
176 void PrintTo(const ByteString& str, std::ostream* os);
177 
178 }  // namespace fxcrt
179 
180 using ByteString = fxcrt::ByteString;
181 
182 uint32_t FX_HashCode_GetA(ByteStringView str);
183 uint32_t FX_HashCode_GetLoweredA(ByteStringView str);
184 uint32_t FX_HashCode_GetAsIfW(ByteStringView str);
185 uint32_t FX_HashCode_GetLoweredAsIfW(ByteStringView str);
186 
187 namespace std {
188 
189 template <>
190 struct hash<ByteString> {
191   size_t operator()(const ByteString& str) const {
192     return FX_HashCode_GetA(str.AsStringView());
193   }
194 };
195 
196 }  // namespace std
197 
198 extern template struct std::hash<ByteString>;
199 
200 #endif  // CORE_FXCRT_BYTESTRING_H_
201