/src/mozilla-central/xpcom/string/nsTString.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | // IWYU pragma: private, include "nsString.h" |
7 | | |
8 | | #ifndef nsTString_h |
9 | | #define nsTString_h |
10 | | |
11 | | #include "nsTSubstring.h" |
12 | | |
13 | | /** |
14 | | * This is the canonical null-terminated string class. All subclasses |
15 | | * promise null-terminated storage. Instances of this class allocate |
16 | | * strings on the heap. |
17 | | * |
18 | | * NAMES: |
19 | | * nsString for wide characters |
20 | | * nsCString for narrow characters |
21 | | * |
22 | | * This class is also known as nsAFlat[C]String, where "flat" is used |
23 | | * to denote a null-terminated string. |
24 | | */ |
25 | | template <typename T> |
26 | | class nsTString : public nsTSubstring<T> |
27 | | { |
28 | | public: |
29 | | |
30 | | typedef nsTString<T> self_type; |
31 | | |
32 | | #ifdef __clang__ |
33 | | // bindgen w/ clang 3.9 at least chokes on a typedef, but using is okay. |
34 | | using typename nsTSubstring<T>::substring_type; |
35 | | #else |
36 | | // On the other hand msvc chokes on the using statement. It seems others |
37 | | // don't care either way so we lump them in here. |
38 | | typedef typename nsTSubstring<T>::substring_type substring_type; |
39 | | #endif |
40 | | |
41 | | typedef typename substring_type::fallible_t fallible_t; |
42 | | |
43 | | typedef typename substring_type::char_type char_type; |
44 | | typedef typename substring_type::char_traits char_traits; |
45 | | typedef typename substring_type::incompatible_char_type incompatible_char_type; |
46 | | |
47 | | typedef typename substring_type::substring_tuple_type substring_tuple_type; |
48 | | |
49 | | typedef typename substring_type::const_iterator const_iterator; |
50 | | typedef typename substring_type::iterator iterator; |
51 | | |
52 | | typedef typename substring_type::comparator_type comparator_type; |
53 | | |
54 | | typedef typename substring_type::const_char_iterator const_char_iterator; |
55 | | |
56 | | typedef typename substring_type::index_type index_type; |
57 | | typedef typename substring_type::size_type size_type; |
58 | | |
59 | | // These are only for internal use within the string classes: |
60 | | typedef typename substring_type::DataFlags DataFlags; |
61 | | typedef typename substring_type::ClassFlags ClassFlags; |
62 | | |
63 | | public: |
64 | | |
65 | | /** |
66 | | * constructors |
67 | | */ |
68 | | |
69 | | nsTString() |
70 | | : substring_type(ClassFlags::NULL_TERMINATED) |
71 | 1.05M | { |
72 | 1.05M | } |
73 | | |
74 | | explicit |
75 | | nsTString(const char_type* aData, size_type aLength = size_type(-1)) |
76 | | : substring_type(ClassFlags::NULL_TERMINATED) |
77 | 2.54M | { |
78 | 2.54M | this->Assign(aData, aLength); |
79 | 2.54M | } nsTString<char>::nsTString(char const*, unsigned int) Line | Count | Source | 77 | 2.54M | { | 78 | 2.54M | this->Assign(aData, aLength); | 79 | 2.54M | } |
Unexecuted instantiation: nsTString<char16_t>::nsTString(char16_t const*, unsigned int) |
80 | | |
81 | | #if defined(MOZ_USE_CHAR16_WRAPPER) |
82 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
83 | | explicit |
84 | | nsTString(char16ptr_t aStr, size_type aLength = size_type(-1)) |
85 | | : substring_type(ClassFlags::NULL_TERMINATED) |
86 | | { |
87 | | this->Assign(static_cast<const char16_t*>(aStr), aLength); |
88 | | } |
89 | | #endif |
90 | | |
91 | | nsTString(const self_type& aStr) |
92 | | : substring_type(ClassFlags::NULL_TERMINATED) |
93 | 15.0M | { |
94 | 15.0M | this->Assign(aStr); |
95 | 15.0M | } |
96 | | |
97 | | nsTString(self_type&& aStr) |
98 | | : substring_type(ClassFlags::NULL_TERMINATED) |
99 | 1.12M | { |
100 | 1.12M | this->Assign(std::move(aStr)); |
101 | 1.12M | } nsTString<char>::nsTString(nsTString<char>&&) Line | Count | Source | 99 | 1.12M | { | 100 | 1.12M | this->Assign(std::move(aStr)); | 101 | 1.12M | } |
nsTString<char16_t>::nsTString(nsTString<char16_t>&&) Line | Count | Source | 99 | 24 | { | 100 | 24 | this->Assign(std::move(aStr)); | 101 | 24 | } |
|
102 | | |
103 | | MOZ_IMPLICIT nsTString(const substring_tuple_type& aTuple) |
104 | | : substring_type(ClassFlags::NULL_TERMINATED) |
105 | 3 | { |
106 | 3 | this->Assign(aTuple); |
107 | 3 | } nsTString<char>::nsTString(nsTSubstringTuple<char> const&) Line | Count | Source | 105 | 3 | { | 106 | 3 | this->Assign(aTuple); | 107 | 3 | } |
Unexecuted instantiation: nsTString<char16_t>::nsTString(nsTSubstringTuple<char16_t> const&) |
108 | | |
109 | | explicit |
110 | | nsTString(const substring_type& aReadable) |
111 | | : substring_type(ClassFlags::NULL_TERMINATED) |
112 | 192k | { |
113 | 192k | this->Assign(aReadable); |
114 | 192k | } |
115 | | |
116 | | explicit |
117 | | nsTString(substring_type&& aReadable) |
118 | | : substring_type(ClassFlags::NULL_TERMINATED) |
119 | 0 | { |
120 | 0 | this->Assign(std::move(aReadable)); |
121 | 0 | } Unexecuted instantiation: nsTString<char>::nsTString(nsTSubstring<char>&&) Unexecuted instantiation: nsTString<char16_t>::nsTString(nsTSubstring<char16_t>&&) |
122 | | |
123 | | // |operator=| does not inherit, so we must define our own |
124 | | self_type& operator=(char_type aChar) |
125 | 0 | { |
126 | 0 | this->Assign(aChar); |
127 | 0 | return *this; |
128 | 0 | } Unexecuted instantiation: nsTString<char>::operator=(char) Unexecuted instantiation: nsTString<char16_t>::operator=(char16_t) |
129 | | self_type& operator=(const char_type* aData) |
130 | 0 | { |
131 | 0 | this->Assign(aData); |
132 | 0 | return *this; |
133 | 0 | } |
134 | | self_type& operator=(const self_type& aStr) |
135 | 3.59M | { |
136 | 3.59M | this->Assign(aStr); |
137 | 3.59M | return *this; |
138 | 3.59M | } |
139 | | self_type& operator=(self_type&& aStr) |
140 | 3.99k | { |
141 | 3.99k | this->Assign(std::move(aStr)); |
142 | 3.99k | return *this; |
143 | 3.99k | } nsTString<char>::operator=(nsTString<char>&&) Line | Count | Source | 140 | 3.99k | { | 141 | 3.99k | this->Assign(std::move(aStr)); | 142 | 3.99k | return *this; | 143 | 3.99k | } |
Unexecuted instantiation: nsTString<char16_t>::operator=(nsTString<char16_t>&&) |
144 | | #if defined(MOZ_USE_CHAR16_WRAPPER) |
145 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
146 | | self_type& operator=(const char16ptr_t aStr) |
147 | | { |
148 | | this->Assign(static_cast<const char16_t*>(aStr)); |
149 | | return *this; |
150 | | } |
151 | | #endif |
152 | | self_type& operator=(const substring_type& aStr) |
153 | 26.5k | { |
154 | 26.5k | this->Assign(aStr); |
155 | 26.5k | return *this; |
156 | 26.5k | } nsTString<char16_t>::operator=(nsTSubstring<char16_t> const&) Line | Count | Source | 153 | 21.9k | { | 154 | 21.9k | this->Assign(aStr); | 155 | 21.9k | return *this; | 156 | 21.9k | } |
nsTString<char>::operator=(nsTSubstring<char> const&) Line | Count | Source | 153 | 4.58k | { | 154 | 4.58k | this->Assign(aStr); | 155 | 4.58k | return *this; | 156 | 4.58k | } |
|
157 | | self_type& operator=(substring_type&& aStr) |
158 | 0 | { |
159 | 0 | this->Assign(std::move(aStr)); |
160 | 0 | return *this; |
161 | 0 | } Unexecuted instantiation: nsTString<char>::operator=(nsTSubstring<char>&&) Unexecuted instantiation: nsTString<char16_t>::operator=(nsTSubstring<char16_t>&&) |
162 | | self_type& operator=(const substring_tuple_type& aTuple) |
163 | 0 | { |
164 | 0 | this->Assign(aTuple); |
165 | 0 | return *this; |
166 | 0 | } Unexecuted instantiation: nsTString<char>::operator=(nsTSubstringTuple<char> const&) Unexecuted instantiation: nsTString<char16_t>::operator=(nsTSubstringTuple<char16_t> const&) |
167 | | |
168 | | /** |
169 | | * returns the null-terminated string |
170 | | */ |
171 | | |
172 | | template <typename U, typename Dummy> struct raw_type { typedef const U* type; }; |
173 | | #if defined(MOZ_USE_CHAR16_WRAPPER) |
174 | | template <typename Dummy> struct raw_type<char16_t, Dummy> { typedef char16ptr_t type; }; |
175 | | #endif |
176 | | |
177 | | MOZ_NO_DANGLING_ON_TEMPORARIES typename raw_type<T, int>::type get() const |
178 | 689k | { |
179 | 689k | return this->mData; |
180 | 689k | } |
181 | | |
182 | | |
183 | | /** |
184 | | * returns character at specified index. |
185 | | * |
186 | | * NOTE: unlike nsTSubstring::CharAt, this function allows you to index |
187 | | * the null terminator character. |
188 | | */ |
189 | | |
190 | | char_type CharAt(index_type aIndex) const |
191 | 0 | { |
192 | 0 | NS_ASSERTION(aIndex <= this->mLength, "index exceeds allowable range"); |
193 | 0 | return this->mData[aIndex]; |
194 | 0 | } |
195 | | |
196 | | char_type operator[](index_type aIndex) const |
197 | 0 | { |
198 | 0 | return CharAt(aIndex); |
199 | 0 | } |
200 | | |
201 | | |
202 | | #if MOZ_STRING_WITH_OBSOLETE_API |
203 | | |
204 | | |
205 | | /** |
206 | | * Search for the given substring within this string. |
207 | | * |
208 | | * @param aString is substring to be sought in this |
209 | | * @param aIgnoreCase selects case sensitivity |
210 | | * @param aOffset tells us where in this string to start searching |
211 | | * @param aCount tells us how far from the offset we are to search. Use |
212 | | * -1 to search the whole string. |
213 | | * @return offset in string, or kNotFound |
214 | | */ |
215 | | |
216 | | int32_t Find(const nsTString<char>& aString, bool aIgnoreCase = false, |
217 | | int32_t aOffset = 0, int32_t aCount = -1) const; |
218 | | int32_t Find(const char* aString, bool aIgnoreCase = false, |
219 | | int32_t aOffset = 0, int32_t aCount = -1) const; |
220 | | |
221 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
222 | | int32_t Find(const self_type& aString, int32_t aOffset = 0, |
223 | | int32_t aCount = -1) const; |
224 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
225 | | int32_t Find(const char_type* aString, int32_t aOffset = 0, |
226 | | int32_t aCount = -1) const; |
227 | | #ifdef MOZ_USE_CHAR16_WRAPPER |
228 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
229 | | int32_t Find(char16ptr_t aString, int32_t aOffset = 0, |
230 | | int32_t aCount = -1) const |
231 | | { |
232 | | return Find(static_cast<const char16_t*>(aString), aOffset, aCount); |
233 | | } |
234 | | #endif |
235 | | |
236 | | |
237 | | /** |
238 | | * This methods scans the string backwards, looking for the given string |
239 | | * |
240 | | * @param aString is substring to be sought in this |
241 | | * @param aIgnoreCase tells us whether or not to do caseless compare |
242 | | * @param aOffset tells us where in this string to start searching. |
243 | | * Use -1 to search from the end of the string. |
244 | | * @param aCount tells us how many iterations to make starting at the |
245 | | * given offset. |
246 | | * @return offset in string, or kNotFound |
247 | | */ |
248 | | |
249 | | // Case aIgnoreCase option only with char versions |
250 | | int32_t RFind(const nsTString<char>& aString, bool aIgnoreCase = false, |
251 | | int32_t aOffset = -1, int32_t aCount = -1) const; |
252 | | int32_t RFind(const char* aCString, bool aIgnoreCase = false, |
253 | | int32_t aOffset = -1, int32_t aCount = -1) const; |
254 | | |
255 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
256 | | int32_t RFind(const self_type& aString, int32_t aOffset = -1, |
257 | | int32_t aCount = -1) const; |
258 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
259 | | int32_t RFind(const char_type* aString, int32_t aOffset = -1, |
260 | | int32_t aCount = -1) const; |
261 | | |
262 | | |
263 | | /** |
264 | | * Search for given char within this string |
265 | | * |
266 | | * @param aChar is the character to search for |
267 | | * @param aOffset tells us where in this string to start searching |
268 | | * @param aCount tells us how far from the offset we are to search. |
269 | | * Use -1 to search the whole string. |
270 | | * @return offset in string, or kNotFound |
271 | | */ |
272 | | |
273 | | // int32_t FindChar( char16_t aChar, int32_t aOffset=0, int32_t aCount=-1 ) const; |
274 | | int32_t RFindChar(char16_t aChar, int32_t aOffset = -1, |
275 | | int32_t aCount = -1) const; |
276 | | |
277 | | |
278 | | /** |
279 | | * This method searches this string for the first character found in |
280 | | * the given string. |
281 | | * |
282 | | * @param aString contains set of chars to be found |
283 | | * @param aOffset tells us where in this string to start searching |
284 | | * (counting from left) |
285 | | * @return offset in string, or kNotFound |
286 | | */ |
287 | | |
288 | | int32_t FindCharInSet(const char_type* aString, int32_t aOffset = 0) const; |
289 | | int32_t FindCharInSet(const self_type& aString, int32_t aOffset = 0) const |
290 | 31.7k | { |
291 | 31.7k | return FindCharInSet(aString.get(), aOffset); |
292 | 31.7k | } nsTString<char>::FindCharInSet(nsTString<char> const&, int) const Line | Count | Source | 290 | 4.94k | { | 291 | 4.94k | return FindCharInSet(aString.get(), aOffset); | 292 | 4.94k | } |
nsTString<char16_t>::FindCharInSet(nsTString<char16_t> const&, int) const Line | Count | Source | 290 | 26.8k | { | 291 | 26.8k | return FindCharInSet(aString.get(), aOffset); | 292 | 26.8k | } |
|
293 | | |
294 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
295 | | int32_t FindCharInSet(const char* aSet, int32_t aOffset = 0) const; |
296 | | |
297 | | |
298 | | /** |
299 | | * This method searches this string for the last character found in |
300 | | * the given string. |
301 | | * |
302 | | * @param aString contains set of chars to be found |
303 | | * @param aOffset tells us where in this string to start searching |
304 | | * (counting from left) |
305 | | * @return offset in string, or kNotFound |
306 | | */ |
307 | | |
308 | | int32_t RFindCharInSet(const char_type* aString, int32_t aOffset = -1) const; |
309 | | int32_t RFindCharInSet(const self_type& aString, int32_t aOffset = -1) const |
310 | 0 | { |
311 | 0 | return RFindCharInSet(aString.get(), aOffset); |
312 | 0 | } Unexecuted instantiation: nsTString<char>::RFindCharInSet(nsTString<char> const&, int) const Unexecuted instantiation: nsTString<char16_t>::RFindCharInSet(nsTString<char16_t> const&, int) const |
313 | | |
314 | | |
315 | | /** |
316 | | * Compares a given string to this string. |
317 | | * |
318 | | * @param aString is the string to be compared |
319 | | * @param aIgnoreCase tells us how to treat case |
320 | | * @param aCount tells us how many chars to compare |
321 | | * @return -1,0,1 |
322 | | */ |
323 | | template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>> |
324 | | int32_t Compare(const char_type* aString, bool aIgnoreCase = false, |
325 | | int32_t aCount = -1) const; |
326 | | |
327 | | |
328 | | /** |
329 | | * Equality check between given string and this string. |
330 | | * |
331 | | * @param aString is the string to check |
332 | | * @param aIgnoreCase tells us how to treat case |
333 | | * @param aCount tells us how many chars to compare |
334 | | * @return boolean |
335 | | */ |
336 | | template <typename Q = T, typename EnableIfChar = mozilla::CharOnlyT<Q>> |
337 | | bool EqualsIgnoreCase(const char_type* aString, int32_t aCount = -1) const |
338 | | { |
339 | | return Compare(aString, true, aCount) == 0; |
340 | | } |
341 | | |
342 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
343 | | bool EqualsIgnoreCase(const incompatible_char_type* aString, int32_t aCount = -1) const; |
344 | | |
345 | | /** |
346 | | * Perform string to double-precision float conversion. |
347 | | * |
348 | | * @param aErrorCode will contain error if one occurs |
349 | | * @return double-precision float rep of string value |
350 | | */ |
351 | | double ToDouble(nsresult* aErrorCode) const; |
352 | | |
353 | | /** |
354 | | * Perform string to single-precision float conversion. |
355 | | * |
356 | | * @param aErrorCode will contain error if one occurs |
357 | | * @return single-precision float rep of string value |
358 | | */ |
359 | | float ToFloat(nsresult* aErrorCode) const; |
360 | | |
361 | | /** |
362 | | * |Left|, |Mid|, and |Right| are annoying signatures that seem better almost |
363 | | * any _other_ way than they are now. Consider these alternatives |
364 | | * |
365 | | * aWritable = aReadable.Left(17); // ...a member function that returns a |Substring| |
366 | | * aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring| |
367 | | * Left(aReadable, 17, aWritable); // ...a global function that does the assignment |
368 | | * |
369 | | * as opposed to the current signature |
370 | | * |
371 | | * aReadable.Left(aWritable, 17); // ...a member function that does the assignment |
372 | | * |
373 | | * or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality |
374 | | * |
375 | | * aWritable = Substring(aReadable, 0, 17); |
376 | | */ |
377 | | |
378 | | size_type Mid(self_type& aResult, index_type aStartPos, size_type aCount) const; |
379 | | |
380 | | size_type Left(self_type& aResult, size_type aCount) const |
381 | 0 | { |
382 | 0 | return Mid(aResult, 0, aCount); |
383 | 0 | } |
384 | | |
385 | | size_type Right(self_type& aResult, size_type aCount) const |
386 | 0 | { |
387 | 0 | aCount = XPCOM_MIN(this->mLength, aCount); |
388 | 0 | return Mid(aResult, this->mLength - aCount, aCount); |
389 | 0 | } |
390 | | |
391 | | |
392 | | /** |
393 | | * Set a char inside this string at given index |
394 | | * |
395 | | * @param aChar is the char you want to write into this string |
396 | | * @param anIndex is the ofs where you want to write the given char |
397 | | * @return TRUE if successful |
398 | | */ |
399 | | |
400 | | bool SetCharAt(char16_t aChar, uint32_t aIndex); |
401 | | |
402 | | |
403 | | /** |
404 | | * These methods are used to remove all occurrences of the |
405 | | * characters found in aSet from this string. |
406 | | * |
407 | | * @param aSet -- characters to be cut from this |
408 | | */ |
409 | | void StripChars(const char_type* aSet); |
410 | | |
411 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
412 | | bool StripChars(const incompatible_char_type* aSet, const fallible_t&); |
413 | | |
414 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
415 | | void StripChars(const incompatible_char_type* aSet); |
416 | | |
417 | | /** |
418 | | * This method strips whitespace throughout the string. |
419 | | */ |
420 | | void StripWhitespace(); |
421 | | bool StripWhitespace(const fallible_t&); |
422 | | |
423 | | |
424 | | /** |
425 | | * swaps occurence of 1 string for another |
426 | | */ |
427 | | |
428 | | void ReplaceChar(char_type aOldChar, char_type aNewChar); |
429 | | void ReplaceChar(const char_type* aSet, char_type aNewChar); |
430 | | |
431 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
432 | | void ReplaceChar(const char* aSet, char16_t aNewChar); |
433 | | |
434 | | /** |
435 | | * Replace all occurrences of aTarget with aNewValue. |
436 | | * The complexity of this function is O(n+m), n being the length of the string |
437 | | * and m being the length of aNewValue. |
438 | | */ |
439 | | void ReplaceSubstring(const self_type& aTarget, const self_type& aNewValue); |
440 | | void ReplaceSubstring(const char_type* aTarget, const char_type* aNewValue); |
441 | | MOZ_MUST_USE bool ReplaceSubstring(const self_type& aTarget, |
442 | | const self_type& aNewValue, |
443 | | const fallible_t&); |
444 | | MOZ_MUST_USE bool ReplaceSubstring(const char_type* aTarget, |
445 | | const char_type* aNewValue, |
446 | | const fallible_t&); |
447 | | |
448 | | |
449 | | /** |
450 | | * This method trims characters found in aTrimSet from |
451 | | * either end of the underlying string. |
452 | | * |
453 | | * @param aSet -- contains chars to be trimmed from both ends |
454 | | * @param aEliminateLeading |
455 | | * @param aEliminateTrailing |
456 | | * @param aIgnoreQuotes -- if true, causes surrounding quotes to be ignored |
457 | | * @return this |
458 | | */ |
459 | | void Trim(const char* aSet, bool aEliminateLeading = true, |
460 | | bool aEliminateTrailing = true, bool aIgnoreQuotes = false); |
461 | | |
462 | | /** |
463 | | * This method strips whitespace from string. |
464 | | * You can control whether whitespace is yanked from start and end of |
465 | | * string as well. |
466 | | * |
467 | | * @param aEliminateLeading controls stripping of leading ws |
468 | | * @param aEliminateTrailing controls stripping of trailing ws |
469 | | */ |
470 | | void CompressWhitespace(bool aEliminateLeading = true, |
471 | | bool aEliminateTrailing = true); |
472 | | |
473 | | #endif // !MOZ_STRING_WITH_OBSOLETE_API |
474 | | |
475 | | /** |
476 | | * Allow this string to be bound to a character buffer |
477 | | * until the string is rebound or mutated; the caller |
478 | | * must ensure that the buffer outlives the string. |
479 | | */ |
480 | | void Rebind(const char_type* aData, size_type aLength); |
481 | | |
482 | | /** |
483 | | * verify restrictions for dependent strings |
484 | | */ |
485 | | void AssertValidDependentString() |
486 | 421k | { |
487 | 421k | NS_ASSERTION(this->mData, "nsTDependentString must wrap a non-NULL buffer"); |
488 | 421k | NS_ASSERTION(this->mLength != size_type(-1), "nsTDependentString has bogus length"); |
489 | 421k | NS_ASSERTION(this->mData[substring_type::mLength] == 0, |
490 | 421k | "nsTDependentString must wrap only null-terminated strings. " |
491 | 421k | "You are probably looking for nsTDependentSubstring."); |
492 | 421k | } |
493 | | |
494 | | |
495 | | protected: |
496 | | |
497 | | // allow subclasses to initialize fields directly |
498 | | nsTString(char_type* aData, size_type aLength, DataFlags aDataFlags, |
499 | | ClassFlags aClassFlags) |
500 | | : substring_type(aData, aLength, aDataFlags, |
501 | | aClassFlags | ClassFlags::NULL_TERMINATED) |
502 | | { |
503 | | } |
504 | | |
505 | | friend const nsTString<char>& VoidCString(); |
506 | | friend const nsTString<char16_t>& VoidString(); |
507 | | |
508 | | // Used by Null[C]String. |
509 | | explicit nsTString(DataFlags aDataFlags) |
510 | | : substring_type(char_traits::sEmptyBuffer, 0, |
511 | | aDataFlags | DataFlags::TERMINATED, |
512 | | ClassFlags::NULL_TERMINATED) |
513 | 3 | {} nsTString<char>::nsTString(mozilla::detail::StringDataFlags) Line | Count | Source | 513 | 3 | {} |
Unexecuted instantiation: nsTString<char16_t>::nsTString(mozilla::detail::StringDataFlags) |
514 | | |
515 | | struct Segment { |
516 | | uint32_t mBegin, mLength; |
517 | | Segment(uint32_t aBegin, uint32_t aLength) |
518 | | : mBegin(aBegin) |
519 | | , mLength(aLength) |
520 | 349 | {} nsTString<char>::Segment::Segment(unsigned int, unsigned int) Line | Count | Source | 520 | 349 | {} |
Unexecuted instantiation: nsTString<char16_t>::Segment::Segment(unsigned int, unsigned int) |
521 | | }; |
522 | | }; |
523 | | |
524 | | // TODO(erahm): Do something with ToDouble so that we can extern the |
525 | | // nsTString templates. |
526 | | //extern template class nsTString<char>; |
527 | | //extern template class nsTString<char16_t>; |
528 | | |
529 | | /** |
530 | | * nsTAutoStringN |
531 | | * |
532 | | * Subclass of nsTString that adds support for stack-based string |
533 | | * allocation. It is normally not a good idea to use this class on the |
534 | | * heap, because it will allocate space which may be wasted if the string |
535 | | * it contains is significantly smaller or any larger than 64 characters. |
536 | | * |
537 | | * NAMES: |
538 | | * nsAutoStringN / nsTAutoString for wide characters |
539 | | * nsAutoCStringN / nsTAutoCString for narrow characters |
540 | | */ |
541 | | template<typename T, size_t N> |
542 | | class MOZ_NON_MEMMOVABLE nsTAutoStringN : public nsTString<T> |
543 | | { |
544 | | public: |
545 | | |
546 | | typedef nsTAutoStringN<T, N> self_type; |
547 | | |
548 | | typedef nsTString<T> base_string_type; |
549 | | typedef typename base_string_type::string_type string_type; |
550 | | typedef typename base_string_type::char_type char_type; |
551 | | typedef typename base_string_type::char_traits char_traits; |
552 | | typedef typename base_string_type::substring_type substring_type; |
553 | | typedef typename base_string_type::size_type size_type; |
554 | | typedef typename base_string_type::substring_tuple_type substring_tuple_type; |
555 | | |
556 | | // These are only for internal use within the string classes: |
557 | | typedef typename base_string_type::DataFlags DataFlags; |
558 | | typedef typename base_string_type::ClassFlags ClassFlags; |
559 | | |
560 | | public: |
561 | | |
562 | | /** |
563 | | * constructors |
564 | | */ |
565 | | |
566 | | nsTAutoStringN() |
567 | | : string_type(mStorage, 0, DataFlags::TERMINATED | DataFlags::INLINE, |
568 | | ClassFlags::INLINE) |
569 | | , mInlineCapacity(N - 1) |
570 | | { |
571 | | // null-terminate |
572 | | mStorage[0] = char_type(0); |
573 | | } |
574 | | |
575 | | explicit |
576 | | nsTAutoStringN(char_type aChar) |
577 | | : self_type() |
578 | 0 | { |
579 | 0 | this->Assign(aChar); |
580 | 0 | } Unexecuted instantiation: nsTAutoStringN<char, 64ul>::nsTAutoStringN(char) Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::nsTAutoStringN(char16_t) |
581 | | |
582 | | explicit |
583 | | nsTAutoStringN(const char_type* aData, size_type aLength = size_type(-1)) |
584 | | : self_type() |
585 | 0 | { |
586 | 0 | this->Assign(aData, aLength); |
587 | 0 | } |
588 | | |
589 | | #if defined(MOZ_USE_CHAR16_WRAPPER) |
590 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
591 | | explicit |
592 | | nsTAutoStringN(char16ptr_t aData, size_type aLength = size_type(-1)) |
593 | | : self_type(static_cast<const char16_t*>(aData), aLength) |
594 | | { |
595 | | } |
596 | | #endif |
597 | | |
598 | | nsTAutoStringN(const self_type& aStr) |
599 | | : self_type() |
600 | 0 | { |
601 | 0 | this->Assign(aStr); |
602 | 0 | } |
603 | | |
604 | | nsTAutoStringN(self_type&& aStr) |
605 | | : self_type() |
606 | 9.49k | { |
607 | 9.49k | this->Assign(std::move(aStr)); |
608 | 9.49k | } nsTAutoStringN<char, 64ul>::nsTAutoStringN(nsTAutoStringN<char, 64ul>&&) Line | Count | Source | 606 | 9.49k | { | 607 | 9.49k | this->Assign(std::move(aStr)); | 608 | 9.49k | } |
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::nsTAutoStringN(nsTAutoStringN<char16_t, 64ul>&&) |
609 | | |
610 | | explicit |
611 | | nsTAutoStringN(const substring_type& aStr) |
612 | | : self_type() |
613 | 2.20k | { |
614 | 2.20k | this->Assign(aStr); |
615 | 2.20k | } |
616 | | |
617 | | explicit |
618 | | nsTAutoStringN(substring_type&& aStr) |
619 | | : self_type() |
620 | 3.86M | { |
621 | 3.86M | this->Assign(std::move(aStr)); |
622 | 3.86M | } nsTAutoStringN<char, 64ul>::nsTAutoStringN(nsTSubstring<char>&&) Line | Count | Source | 620 | 3.86M | { | 621 | 3.86M | this->Assign(std::move(aStr)); | 622 | 3.86M | } |
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::nsTAutoStringN(nsTSubstring<char16_t>&&) |
623 | | |
624 | | MOZ_IMPLICIT nsTAutoStringN(const substring_tuple_type& aTuple) |
625 | | : self_type() |
626 | 2.22k | { |
627 | 2.22k | this->Assign(aTuple); |
628 | 2.22k | } nsTAutoStringN<char, 64ul>::nsTAutoStringN(nsTSubstringTuple<char> const&) Line | Count | Source | 626 | 2.22k | { | 627 | 2.22k | this->Assign(aTuple); | 628 | 2.22k | } |
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::nsTAutoStringN(nsTSubstringTuple<char16_t> const&) |
629 | | |
630 | | // |operator=| does not inherit, so we must define our own |
631 | | self_type& operator=(char_type aChar) |
632 | 0 | { |
633 | 0 | this->Assign(aChar); |
634 | 0 | return *this; |
635 | 0 | } Unexecuted instantiation: nsTAutoStringN<char, 64ul>::operator=(char) Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::operator=(char16_t) |
636 | | self_type& operator=(const char_type* aData) |
637 | 2 | { |
638 | 2 | this->Assign(aData); |
639 | 2 | return *this; |
640 | 2 | } nsTAutoStringN<char, 64ul>::operator=(char const*) Line | Count | Source | 637 | 2 | { | 638 | 2 | this->Assign(aData); | 639 | 2 | return *this; | 640 | 2 | } |
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::operator=(char16_t const*) |
641 | | #if defined(MOZ_USE_CHAR16_WRAPPER) |
642 | | template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>> |
643 | | self_type& operator=(char16ptr_t aStr) |
644 | | { |
645 | | this->Assign(aStr); |
646 | | return *this; |
647 | | } |
648 | | #endif |
649 | | self_type& operator=(const self_type& aStr) |
650 | 0 | { |
651 | 0 | this->Assign(aStr); |
652 | 0 | return *this; |
653 | 0 | } |
654 | | self_type& operator=(self_type&& aStr) |
655 | 5 | { |
656 | 5 | this->Assign(std::move(aStr)); |
657 | 5 | return *this; |
658 | 5 | } nsTAutoStringN<char, 64ul>::operator=(nsTAutoStringN<char, 64ul>&&) Line | Count | Source | 655 | 5 | { | 656 | 5 | this->Assign(std::move(aStr)); | 657 | 5 | return *this; | 658 | 5 | } |
Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::operator=(nsTAutoStringN<char16_t, 64ul>&&) |
659 | | self_type& operator=(const substring_type& aStr) |
660 | 12 | { |
661 | 12 | this->Assign(aStr); |
662 | 12 | return *this; |
663 | 12 | } |
664 | | self_type& operator=(substring_type&& aStr) |
665 | 0 | { |
666 | 0 | this->Assign(std::move(aStr)); |
667 | 0 | return *this; |
668 | 0 | } Unexecuted instantiation: nsTAutoStringN<char, 64ul>::operator=(nsTSubstring<char>&&) Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::operator=(nsTSubstring<char16_t>&&) |
669 | | self_type& operator=(const substring_tuple_type& aTuple) |
670 | 0 | { |
671 | 0 | this->Assign(aTuple); |
672 | 0 | return *this; |
673 | 0 | } Unexecuted instantiation: nsTAutoStringN<char, 64ul>::operator=(nsTSubstringTuple<char> const&) Unexecuted instantiation: nsTAutoStringN<char16_t, 64ul>::operator=(nsTSubstringTuple<char16_t> const&) |
674 | | |
675 | | static const size_t kStorageSize = N; |
676 | | |
677 | | protected: |
678 | | friend class nsTSubstring<T>; |
679 | | |
680 | | size_type mInlineCapacity; |
681 | | |
682 | | private: |
683 | | char_type mStorage[N]; |
684 | | }; |
685 | | |
686 | | // Externs for the most common nsTAutoStringN variations. |
687 | | extern template class nsTAutoStringN<char, 64>; |
688 | | extern template class nsTAutoStringN<char16_t, 64>; |
689 | | |
690 | | // |
691 | | // nsAutoString stores pointers into itself which are invalidated when an |
692 | | // nsTArray is resized, so nsTArray must not be instantiated with nsAutoString |
693 | | // elements! |
694 | | // |
695 | | template<class E> class nsTArrayElementTraits; |
696 | | template<typename T> |
697 | | class nsTArrayElementTraits<nsTAutoString<T>> |
698 | | { |
699 | | public: |
700 | | template<class A> struct Dont_Instantiate_nsTArray_of; |
701 | | template<class A> struct Instead_Use_nsTArray_of; |
702 | | |
703 | | static Dont_Instantiate_nsTArray_of<nsTAutoString<T>>* |
704 | | Construct(Instead_Use_nsTArray_of<nsTString<T>>* aE) |
705 | | { |
706 | | return 0; |
707 | | } |
708 | | template<class A> |
709 | | static Dont_Instantiate_nsTArray_of<nsTAutoString<T>>* |
710 | | Construct(Instead_Use_nsTArray_of<nsTString<T>>* aE, const A& aArg) |
711 | | { |
712 | | return 0; |
713 | | } |
714 | | static Dont_Instantiate_nsTArray_of<nsTAutoString<T>>* |
715 | | Destruct(Instead_Use_nsTArray_of<nsTString<T>>* aE) |
716 | | { |
717 | | return 0; |
718 | | } |
719 | | }; |
720 | | |
721 | | /** |
722 | | * getter_Copies support for adopting raw string out params that are |
723 | | * heap-allocated, e.g.: |
724 | | * |
725 | | * char* gStr; |
726 | | * void GetBlah(char** aStr) |
727 | | * { |
728 | | * *aStr = strdup(gStr); |
729 | | * } |
730 | | * |
731 | | * // This works, but is clumsy. |
732 | | * void Inelegant() |
733 | | * { |
734 | | * char* buf; |
735 | | * GetBlah(&buf); |
736 | | * nsCString str; |
737 | | * str.Adopt(buf); |
738 | | * // ... |
739 | | * } |
740 | | * |
741 | | * // This is nicer. |
742 | | * void Elegant() |
743 | | * { |
744 | | * nsCString str; |
745 | | * GetBlah(getter_Copies(str)); |
746 | | * // ... |
747 | | * } |
748 | | */ |
749 | | template <typename T> |
750 | | class MOZ_STACK_CLASS nsTGetterCopies |
751 | | { |
752 | | public: |
753 | | typedef T char_type; |
754 | | |
755 | | explicit nsTGetterCopies(nsTSubstring<T>& aStr) |
756 | | : mString(aStr) |
757 | | , mData(nullptr) |
758 | | { |
759 | | } |
760 | | |
761 | | ~nsTGetterCopies() |
762 | | { |
763 | | mString.Adopt(mData); // OK if mData is null |
764 | | } |
765 | | |
766 | | operator char_type**() |
767 | | { |
768 | | return &mData; |
769 | | } |
770 | | |
771 | | private: |
772 | | nsTSubstring<T>& mString; |
773 | | char_type* mData; |
774 | | }; |
775 | | |
776 | | // See the comment above nsTGetterCopies_CharT for how to use this. |
777 | | template <typename T> |
778 | | inline nsTGetterCopies<T> |
779 | | getter_Copies(nsTSubstring<T>& aString) |
780 | | { |
781 | | return nsTGetterCopies<T>(aString); |
782 | | } |
783 | | |
784 | | #endif |