|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ |
|
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 /** |
|
9 * This is the canonical null-terminated string class. All subclasses |
|
10 * promise null-terminated storage. Instances of this class allocate |
|
11 * strings on the heap. |
|
12 * |
|
13 * NAMES: |
|
14 * nsString for wide characters |
|
15 * nsCString for narrow characters |
|
16 * |
|
17 * This class is also known as nsAFlat[C]String, where "flat" is used |
|
18 * to denote a null-terminated string. |
|
19 */ |
|
20 class nsTString_CharT : public nsTSubstring_CharT |
|
21 { |
|
22 public: |
|
23 |
|
24 typedef nsTString_CharT self_type; |
|
25 |
|
26 public: |
|
27 |
|
28 /** |
|
29 * constructors |
|
30 */ |
|
31 |
|
32 nsTString_CharT() |
|
33 : substring_type() {} |
|
34 |
|
35 explicit |
|
36 nsTString_CharT( const char_type* data, size_type length = size_type(-1) ) |
|
37 : substring_type() |
|
38 { |
|
39 Assign(data, length); |
|
40 } |
|
41 |
|
42 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) |
|
43 explicit |
|
44 nsTString_CharT( char16ptr_t data, size_type length = size_type(-1) ) |
|
45 : substring_type() |
|
46 { |
|
47 Assign(static_cast<const char16_t*>(data), length); |
|
48 } |
|
49 #endif |
|
50 |
|
51 nsTString_CharT( const self_type& str ) |
|
52 : substring_type() |
|
53 { |
|
54 Assign(str); |
|
55 } |
|
56 |
|
57 nsTString_CharT( const substring_tuple_type& tuple ) |
|
58 : substring_type() |
|
59 { |
|
60 Assign(tuple); |
|
61 } |
|
62 |
|
63 explicit |
|
64 nsTString_CharT( const substring_type& readable ) |
|
65 : substring_type() |
|
66 { |
|
67 Assign(readable); |
|
68 } |
|
69 |
|
70 |
|
71 // |operator=| does not inherit, so we must define our own |
|
72 self_type& operator=( char_type c ) { Assign(c); return *this; } |
|
73 self_type& operator=( const char_type* data ) { Assign(data); return *this; } |
|
74 self_type& operator=( const self_type& str ) { Assign(str); return *this; } |
|
75 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) |
|
76 self_type& operator=( const char16ptr_t data ) { Assign(static_cast<const char16_t*>(data)); return *this; } |
|
77 #endif |
|
78 self_type& operator=( const substring_type& str ) { Assign(str); return *this; } |
|
79 self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; } |
|
80 |
|
81 /** |
|
82 * returns the null-terminated string |
|
83 */ |
|
84 |
|
85 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) |
|
86 char16ptr_t get() const |
|
87 #else |
|
88 const char_type* get() const |
|
89 #endif |
|
90 { |
|
91 return mData; |
|
92 } |
|
93 |
|
94 |
|
95 /** |
|
96 * returns character at specified index. |
|
97 * |
|
98 * NOTE: unlike nsTSubstring::CharAt, this function allows you to index |
|
99 * the null terminator character. |
|
100 */ |
|
101 |
|
102 char_type CharAt( index_type i ) const |
|
103 { |
|
104 NS_ASSERTION(i <= mLength, "index exceeds allowable range"); |
|
105 return mData[i]; |
|
106 } |
|
107 |
|
108 char_type operator[]( index_type i ) const |
|
109 { |
|
110 return CharAt(i); |
|
111 } |
|
112 |
|
113 |
|
114 #if MOZ_STRING_WITH_OBSOLETE_API |
|
115 |
|
116 |
|
117 /** |
|
118 * Search for the given substring within this string. |
|
119 * |
|
120 * @param aString is substring to be sought in this |
|
121 * @param aIgnoreCase selects case sensitivity |
|
122 * @param aOffset tells us where in this string to start searching |
|
123 * @param aCount tells us how far from the offset we are to search. Use |
|
124 * -1 to search the whole string. |
|
125 * @return offset in string, or kNotFound |
|
126 */ |
|
127 |
|
128 int32_t Find( const nsCString& aString, bool aIgnoreCase=false, int32_t aOffset=0, int32_t aCount=-1 ) const; |
|
129 int32_t Find( const char* aString, bool aIgnoreCase=false, int32_t aOffset=0, int32_t aCount=-1 ) const; |
|
130 |
|
131 #ifdef CharT_is_PRUnichar |
|
132 int32_t Find( const nsAFlatString& aString, int32_t aOffset=0, int32_t aCount=-1 ) const; |
|
133 int32_t Find( const char16_t* aString, int32_t aOffset=0, int32_t aCount=-1 ) const; |
|
134 #ifdef MOZ_USE_CHAR16_WRAPPER |
|
135 int32_t Find( char16ptr_t aString, int32_t aOffset=0, int32_t aCount=-1 ) const |
|
136 { |
|
137 return Find(static_cast<const char16_t*>(aString), aOffset, aCount); |
|
138 } |
|
139 #endif |
|
140 #endif |
|
141 |
|
142 |
|
143 /** |
|
144 * This methods scans the string backwards, looking for the given string |
|
145 * |
|
146 * @param aString is substring to be sought in this |
|
147 * @param aIgnoreCase tells us whether or not to do caseless compare |
|
148 * @param aOffset tells us where in this string to start searching. |
|
149 * Use -1 to search from the end of the string. |
|
150 * @param aCount tells us how many iterations to make starting at the |
|
151 * given offset. |
|
152 * @return offset in string, or kNotFound |
|
153 */ |
|
154 |
|
155 int32_t RFind( const nsCString& aString, bool aIgnoreCase=false, int32_t aOffset=-1, int32_t aCount=-1 ) const; |
|
156 int32_t RFind( const char* aCString, bool aIgnoreCase=false, int32_t aOffset=-1, int32_t aCount=-1 ) const; |
|
157 |
|
158 #ifdef CharT_is_PRUnichar |
|
159 int32_t RFind( const nsAFlatString& aString, int32_t aOffset=-1, int32_t aCount=-1 ) const; |
|
160 int32_t RFind( const char16_t* aString, int32_t aOffset=-1, int32_t aCount=-1 ) const; |
|
161 #endif |
|
162 |
|
163 |
|
164 /** |
|
165 * Search for given char within this string |
|
166 * |
|
167 * @param aChar is the character to search for |
|
168 * @param aOffset tells us where in this string to start searching |
|
169 * @param aCount tells us how far from the offset we are to search. |
|
170 * Use -1 to search the whole string. |
|
171 * @return offset in string, or kNotFound |
|
172 */ |
|
173 |
|
174 // int32_t FindChar( char16_t aChar, int32_t aOffset=0, int32_t aCount=-1 ) const; |
|
175 int32_t RFindChar( char16_t aChar, int32_t aOffset=-1, int32_t aCount=-1 ) const; |
|
176 |
|
177 |
|
178 /** |
|
179 * This method searches this string for the first character found in |
|
180 * the given string. |
|
181 * |
|
182 * @param aString contains set of chars to be found |
|
183 * @param aOffset tells us where in this string to start searching |
|
184 * (counting from left) |
|
185 * @return offset in string, or kNotFound |
|
186 */ |
|
187 |
|
188 int32_t FindCharInSet( const char* aString, int32_t aOffset=0 ) const; |
|
189 int32_t FindCharInSet( const self_type& aString, int32_t aOffset=0 ) const |
|
190 { |
|
191 return FindCharInSet(aString.get(), aOffset); |
|
192 } |
|
193 |
|
194 #ifdef CharT_is_PRUnichar |
|
195 int32_t FindCharInSet( const char16_t* aString, int32_t aOffset=0 ) const; |
|
196 #endif |
|
197 |
|
198 |
|
199 /** |
|
200 * This method searches this string for the last character found in |
|
201 * the given string. |
|
202 * |
|
203 * @param aString contains set of chars to be found |
|
204 * @param aOffset tells us where in this string to start searching |
|
205 * (counting from left) |
|
206 * @return offset in string, or kNotFound |
|
207 */ |
|
208 |
|
209 int32_t RFindCharInSet( const char_type* aString, int32_t aOffset=-1 ) const; |
|
210 int32_t RFindCharInSet( const self_type& aString, int32_t aOffset=-1 ) const |
|
211 { |
|
212 return RFindCharInSet(aString.get(), aOffset); |
|
213 } |
|
214 |
|
215 |
|
216 /** |
|
217 * Compares a given string to this string. |
|
218 * |
|
219 * @param aString is the string to be compared |
|
220 * @param aIgnoreCase tells us how to treat case |
|
221 * @param aCount tells us how many chars to compare |
|
222 * @return -1,0,1 |
|
223 */ |
|
224 |
|
225 #ifdef CharT_is_char |
|
226 int32_t Compare( const char* aString, bool aIgnoreCase=false, int32_t aCount=-1 ) const; |
|
227 #endif |
|
228 |
|
229 |
|
230 /** |
|
231 * Equality check between given string and this string. |
|
232 * |
|
233 * @param aString is the string to check |
|
234 * @param aIgnoreCase tells us how to treat case |
|
235 * @param aCount tells us how many chars to compare |
|
236 * @return boolean |
|
237 */ |
|
238 #ifdef CharT_is_char |
|
239 bool EqualsIgnoreCase( const char* aString, int32_t aCount=-1 ) const { |
|
240 return Compare(aString, true, aCount) == 0; |
|
241 } |
|
242 #else |
|
243 bool EqualsIgnoreCase( const char* aString, int32_t aCount=-1 ) const; |
|
244 |
|
245 |
|
246 #endif // !CharT_is_PRUnichar |
|
247 |
|
248 /** |
|
249 * Perform string to double-precision float conversion. |
|
250 * |
|
251 * @param aErrorCode will contain error if one occurs |
|
252 * @return double-precision float rep of string value |
|
253 */ |
|
254 double ToDouble( nsresult* aErrorCode ) const; |
|
255 |
|
256 /** |
|
257 * Perform string to single-precision float conversion. |
|
258 * |
|
259 * @param aErrorCode will contain error if one occurs |
|
260 * @return single-precision float rep of string value |
|
261 */ |
|
262 float ToFloat( nsresult* aErrorCode ) const { |
|
263 return (float)ToDouble(aErrorCode); |
|
264 } |
|
265 |
|
266 |
|
267 /** |
|
268 * Perform string to int conversion. |
|
269 * @param aErrorCode will contain error if one occurs |
|
270 * @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you. |
|
271 * @return int rep of string value, and possible (out) error code |
|
272 */ |
|
273 int32_t ToInteger( nsresult* aErrorCode, uint32_t aRadix=kRadix10 ) const; |
|
274 |
|
275 /** |
|
276 * Perform string to 64-bit int conversion. |
|
277 * @param aErrorCode will contain error if one occurs |
|
278 * @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you. |
|
279 * @return 64-bit int rep of string value, and possible (out) error code |
|
280 */ |
|
281 int64_t ToInteger64( nsresult* aErrorCode, uint32_t aRadix=kRadix10 ) const; |
|
282 |
|
283 |
|
284 /** |
|
285 * |Left|, |Mid|, and |Right| are annoying signatures that seem better almost |
|
286 * any _other_ way than they are now. Consider these alternatives |
|
287 * |
|
288 * aWritable = aReadable.Left(17); // ...a member function that returns a |Substring| |
|
289 * aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring| |
|
290 * Left(aReadable, 17, aWritable); // ...a global function that does the assignment |
|
291 * |
|
292 * as opposed to the current signature |
|
293 * |
|
294 * aReadable.Left(aWritable, 17); // ...a member function that does the assignment |
|
295 * |
|
296 * or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality |
|
297 * |
|
298 * aWritable = Substring(aReadable, 0, 17); |
|
299 */ |
|
300 |
|
301 size_type Mid( self_type& aResult, uint32_t aStartPos, uint32_t aCount ) const; |
|
302 |
|
303 size_type Left( self_type& aResult, size_type aCount ) const |
|
304 { |
|
305 return Mid(aResult, 0, aCount); |
|
306 } |
|
307 |
|
308 size_type Right( self_type& aResult, size_type aCount ) const |
|
309 { |
|
310 aCount = XPCOM_MIN(mLength, aCount); |
|
311 return Mid(aResult, mLength - aCount, aCount); |
|
312 } |
|
313 |
|
314 |
|
315 /** |
|
316 * Set a char inside this string at given index |
|
317 * |
|
318 * @param aChar is the char you want to write into this string |
|
319 * @param anIndex is the ofs where you want to write the given char |
|
320 * @return TRUE if successful |
|
321 */ |
|
322 |
|
323 bool SetCharAt( char16_t aChar, uint32_t aIndex ); |
|
324 |
|
325 |
|
326 /** |
|
327 * These methods are used to remove all occurrences of the |
|
328 * characters found in aSet from this string. |
|
329 * |
|
330 * @param aSet -- characters to be cut from this |
|
331 */ |
|
332 void StripChars( const char* aSet ); |
|
333 |
|
334 |
|
335 /** |
|
336 * This method strips whitespace throughout the string. |
|
337 */ |
|
338 void StripWhitespace(); |
|
339 |
|
340 |
|
341 /** |
|
342 * swaps occurence of 1 string for another |
|
343 */ |
|
344 |
|
345 void ReplaceChar( char_type aOldChar, char_type aNewChar ); |
|
346 void ReplaceChar( const char* aSet, char_type aNewChar ); |
|
347 #ifdef CharT_is_PRUnichar |
|
348 void ReplaceChar( const char16_t* aSet, char16_t aNewChar ); |
|
349 #endif |
|
350 void ReplaceSubstring( const self_type& aTarget, const self_type& aNewValue); |
|
351 void ReplaceSubstring( const char_type* aTarget, const char_type* aNewValue); |
|
352 |
|
353 |
|
354 /** |
|
355 * This method trims characters found in aTrimSet from |
|
356 * either end of the underlying string. |
|
357 * |
|
358 * @param aSet -- contains chars to be trimmed from both ends |
|
359 * @param aEliminateLeading |
|
360 * @param aEliminateTrailing |
|
361 * @param aIgnoreQuotes -- if true, causes surrounding quotes to be ignored |
|
362 * @return this |
|
363 */ |
|
364 void Trim( const char* aSet, bool aEliminateLeading=true, bool aEliminateTrailing=true, bool aIgnoreQuotes=false ); |
|
365 |
|
366 /** |
|
367 * This method strips whitespace from string. |
|
368 * You can control whether whitespace is yanked from start and end of |
|
369 * string as well. |
|
370 * |
|
371 * @param aEliminateLeading controls stripping of leading ws |
|
372 * @param aEliminateTrailing controls stripping of trailing ws |
|
373 */ |
|
374 void CompressWhitespace( bool aEliminateLeading=true, bool aEliminateTrailing=true ); |
|
375 |
|
376 |
|
377 /** |
|
378 * assign/append/insert with _LOSSY_ conversion |
|
379 */ |
|
380 |
|
381 void AssignWithConversion( const nsTAString_IncompatibleCharT& aString ); |
|
382 void AssignWithConversion( const incompatible_char_type* aData, int32_t aLength=-1 ); |
|
383 |
|
384 #endif // !MOZ_STRING_WITH_OBSOLETE_API |
|
385 |
|
386 /** |
|
387 * Allow this string to be bound to a character buffer |
|
388 * until the string is rebound or mutated; the caller |
|
389 * must ensure that the buffer outlives the string. |
|
390 */ |
|
391 void Rebind( const char_type* data, size_type length ); |
|
392 |
|
393 /** |
|
394 * verify restrictions for dependent strings |
|
395 */ |
|
396 void AssertValidDepedentString() |
|
397 { |
|
398 NS_ASSERTION(mData, "nsTDependentString must wrap a non-NULL buffer"); |
|
399 NS_ASSERTION(mLength != size_type(-1), "nsTDependentString has bogus length"); |
|
400 NS_ASSERTION(mData[mLength] == 0, "nsTDependentString must wrap only null-terminated strings. You are probably looking for nsTDependentSubstring."); |
|
401 } |
|
402 |
|
403 |
|
404 protected: |
|
405 |
|
406 explicit |
|
407 nsTString_CharT( uint32_t flags ) |
|
408 : substring_type(flags) {} |
|
409 |
|
410 // allow subclasses to initialize fields directly |
|
411 nsTString_CharT( char_type* data, size_type length, uint32_t flags ) |
|
412 : substring_type(data, length, flags) {} |
|
413 }; |
|
414 |
|
415 |
|
416 class nsTFixedString_CharT : public nsTString_CharT |
|
417 { |
|
418 public: |
|
419 |
|
420 typedef nsTFixedString_CharT self_type; |
|
421 typedef nsTFixedString_CharT fixed_string_type; |
|
422 |
|
423 public: |
|
424 |
|
425 /** |
|
426 * @param data |
|
427 * fixed-size buffer to be used by the string (the contents of |
|
428 * this buffer may be modified by the string) |
|
429 * @param storageSize |
|
430 * the size of the fixed buffer |
|
431 * @param length (optional) |
|
432 * the length of the string already contained in the buffer |
|
433 */ |
|
434 |
|
435 nsTFixedString_CharT( char_type* data, size_type storageSize ) |
|
436 : string_type(data, uint32_t(char_traits::length(data)), F_TERMINATED | F_FIXED | F_CLASS_FIXED) |
|
437 , mFixedCapacity(storageSize - 1) |
|
438 , mFixedBuf(data) |
|
439 {} |
|
440 |
|
441 nsTFixedString_CharT( char_type* data, size_type storageSize, size_type length ) |
|
442 : string_type(data, length, F_TERMINATED | F_FIXED | F_CLASS_FIXED) |
|
443 , mFixedCapacity(storageSize - 1) |
|
444 , mFixedBuf(data) |
|
445 { |
|
446 // null-terminate |
|
447 mFixedBuf[length] = char_type(0); |
|
448 } |
|
449 |
|
450 // |operator=| does not inherit, so we must define our own |
|
451 self_type& operator=( char_type c ) { Assign(c); return *this; } |
|
452 self_type& operator=( const char_type* data ) { Assign(data); return *this; } |
|
453 self_type& operator=( const substring_type& str ) { Assign(str); return *this; } |
|
454 self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; } |
|
455 |
|
456 protected: |
|
457 |
|
458 friend class nsTSubstring_CharT; |
|
459 |
|
460 size_type mFixedCapacity; |
|
461 char_type *mFixedBuf; |
|
462 }; |
|
463 |
|
464 |
|
465 /** |
|
466 * nsTAutoString_CharT |
|
467 * |
|
468 * Subclass of nsTString_CharT that adds support for stack-based string |
|
469 * allocation. It is normally not a good idea to use this class on the |
|
470 * heap, because it will allocate space which may be wasted if the string |
|
471 * it contains is significantly smaller or any larger than 64 characters. |
|
472 * |
|
473 * NAMES: |
|
474 * nsAutoString for wide characters |
|
475 * nsAutoCString for narrow characters |
|
476 */ |
|
477 class nsTAutoString_CharT : public nsTFixedString_CharT |
|
478 { |
|
479 public: |
|
480 |
|
481 typedef nsTAutoString_CharT self_type; |
|
482 |
|
483 public: |
|
484 |
|
485 /** |
|
486 * constructors |
|
487 */ |
|
488 |
|
489 nsTAutoString_CharT() |
|
490 : fixed_string_type(mStorage, kDefaultStorageSize, 0) |
|
491 {} |
|
492 |
|
493 explicit |
|
494 nsTAutoString_CharT( char_type c ) |
|
495 : fixed_string_type(mStorage, kDefaultStorageSize, 0) |
|
496 { |
|
497 Assign(c); |
|
498 } |
|
499 |
|
500 explicit |
|
501 nsTAutoString_CharT( const char_type* data, size_type length = size_type(-1) ) |
|
502 : fixed_string_type(mStorage, kDefaultStorageSize, 0) |
|
503 { |
|
504 Assign(data, length); |
|
505 } |
|
506 |
|
507 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) |
|
508 explicit |
|
509 nsTAutoString_CharT( char16ptr_t data, size_type length = size_type(-1) ) |
|
510 : nsTAutoString_CharT(static_cast<const char16_t*>(data), length) |
|
511 {} |
|
512 #endif |
|
513 |
|
514 nsTAutoString_CharT( const self_type& str ) |
|
515 : fixed_string_type(mStorage, kDefaultStorageSize, 0) |
|
516 { |
|
517 Assign(str); |
|
518 } |
|
519 |
|
520 explicit |
|
521 nsTAutoString_CharT( const substring_type& str ) |
|
522 : fixed_string_type(mStorage, kDefaultStorageSize, 0) |
|
523 { |
|
524 Assign(str); |
|
525 } |
|
526 |
|
527 nsTAutoString_CharT( const substring_tuple_type& tuple ) |
|
528 : fixed_string_type(mStorage, kDefaultStorageSize, 0) |
|
529 { |
|
530 Assign(tuple); |
|
531 } |
|
532 |
|
533 // |operator=| does not inherit, so we must define our own |
|
534 self_type& operator=( char_type c ) { Assign(c); return *this; } |
|
535 self_type& operator=( const char_type* data ) { Assign(data); return *this; } |
|
536 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) |
|
537 self_type& operator=( char16ptr_t data ) { Assign(data); return *this; } |
|
538 #endif |
|
539 self_type& operator=( const self_type& str ) { Assign(str); return *this; } |
|
540 self_type& operator=( const substring_type& str ) { Assign(str); return *this; } |
|
541 self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; } |
|
542 |
|
543 enum { kDefaultStorageSize = 64 }; |
|
544 |
|
545 private: |
|
546 |
|
547 char_type mStorage[kDefaultStorageSize]; |
|
548 }; |
|
549 |
|
550 |
|
551 // |
|
552 // nsAutoString stores pointers into itself which are invalidated when an |
|
553 // nsTArray is resized, so nsTArray must not be instantiated with nsAutoString |
|
554 // elements! |
|
555 // |
|
556 template<class E> class nsTArrayElementTraits; |
|
557 template<> |
|
558 class nsTArrayElementTraits<nsTAutoString_CharT> { |
|
559 public: |
|
560 template<class A> struct Dont_Instantiate_nsTArray_of; |
|
561 template<class A> struct Instead_Use_nsTArray_of; |
|
562 |
|
563 static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT> * |
|
564 Construct(Instead_Use_nsTArray_of<nsTString_CharT> *e) { |
|
565 return 0; |
|
566 } |
|
567 template<class A> |
|
568 static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT> * |
|
569 Construct(Instead_Use_nsTArray_of<nsTString_CharT> *e, |
|
570 const A &arg) { |
|
571 return 0; |
|
572 } |
|
573 static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT> * |
|
574 Destruct(Instead_Use_nsTArray_of<nsTString_CharT> *e) { |
|
575 return 0; |
|
576 } |
|
577 }; |
|
578 |
|
579 /** |
|
580 * nsTXPIDLString extends nsTString such that: |
|
581 * |
|
582 * (1) mData can be null |
|
583 * (2) objects of this type can be automatically cast to |const CharT*| |
|
584 * (3) getter_Copies method is supported to adopt data allocated with |
|
585 * NS_Alloc, such as "out string" parameters in XPIDL. |
|
586 * |
|
587 * NAMES: |
|
588 * nsXPIDLString for wide characters |
|
589 * nsXPIDLCString for narrow characters |
|
590 */ |
|
591 class nsTXPIDLString_CharT : public nsTString_CharT |
|
592 { |
|
593 public: |
|
594 |
|
595 typedef nsTXPIDLString_CharT self_type; |
|
596 |
|
597 public: |
|
598 |
|
599 nsTXPIDLString_CharT() |
|
600 : string_type(char_traits::sEmptyBuffer, 0, F_TERMINATED | F_VOIDED) {} |
|
601 |
|
602 // copy-constructor required to avoid default |
|
603 nsTXPIDLString_CharT( const self_type& str ) |
|
604 : string_type(char_traits::sEmptyBuffer, 0, F_TERMINATED | F_VOIDED) |
|
605 { |
|
606 Assign(str); |
|
607 } |
|
608 |
|
609 // return nullptr if we are voided |
|
610 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) |
|
611 char16ptr_t get() const |
|
612 #else |
|
613 const char_type* get() const |
|
614 #endif |
|
615 { |
|
616 return (mFlags & F_VOIDED) ? nullptr : mData; |
|
617 } |
|
618 |
|
619 // this case operator is the reason why this class cannot just be a |
|
620 // typedef for nsTString |
|
621 operator const char_type*() const |
|
622 { |
|
623 return get(); |
|
624 } |
|
625 |
|
626 // need this to diambiguous operator[int] |
|
627 char_type operator[]( int32_t i ) const |
|
628 { |
|
629 return CharAt(index_type(i)); |
|
630 } |
|
631 |
|
632 // |operator=| does not inherit, so we must define our own |
|
633 self_type& operator=( char_type c ) { Assign(c); return *this; } |
|
634 self_type& operator=( const char_type* data ) { Assign(data); return *this; } |
|
635 self_type& operator=( const self_type& str ) { Assign(str); return *this; } |
|
636 self_type& operator=( const substring_type& str ) { Assign(str); return *this; } |
|
637 self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; } |
|
638 }; |
|
639 |
|
640 |
|
641 /** |
|
642 * getter_Copies support for use with raw string out params: |
|
643 * |
|
644 * NS_IMETHOD GetBlah(char**); |
|
645 * |
|
646 * void some_function() |
|
647 * { |
|
648 * nsXPIDLCString blah; |
|
649 * GetBlah(getter_Copies(blah)); |
|
650 * // ... |
|
651 * } |
|
652 */ |
|
653 class MOZ_STACK_CLASS nsTGetterCopies_CharT |
|
654 { |
|
655 public: |
|
656 typedef CharT char_type; |
|
657 |
|
658 nsTGetterCopies_CharT(nsTSubstring_CharT& str) |
|
659 : mString(str), mData(nullptr) {} |
|
660 |
|
661 ~nsTGetterCopies_CharT() |
|
662 { |
|
663 mString.Adopt(mData); // OK if mData is null |
|
664 } |
|
665 |
|
666 operator char_type**() |
|
667 { |
|
668 return &mData; |
|
669 } |
|
670 |
|
671 private: |
|
672 nsTSubstring_CharT& mString; |
|
673 char_type* mData; |
|
674 }; |
|
675 |
|
676 inline |
|
677 nsTGetterCopies_CharT |
|
678 getter_Copies( nsTSubstring_CharT& aString ) |
|
679 { |
|
680 return nsTGetterCopies_CharT(aString); |
|
681 } |
|
682 |
|
683 |
|
684 /** |
|
685 * nsTAdoptingString extends nsTXPIDLString such that: |
|
686 * |
|
687 * (1) Adopt given string on construction or assignment, i.e. take |
|
688 * the value of what's given, and make what's given forget its |
|
689 * value. Note that this class violates constness in a few |
|
690 * places. Be careful! |
|
691 */ |
|
692 class nsTAdoptingString_CharT : public nsTXPIDLString_CharT |
|
693 { |
|
694 public: |
|
695 |
|
696 typedef nsTAdoptingString_CharT self_type; |
|
697 |
|
698 public: |
|
699 |
|
700 explicit nsTAdoptingString_CharT() {} |
|
701 explicit nsTAdoptingString_CharT(char_type* str, size_type length = size_type(-1)) |
|
702 { |
|
703 Adopt(str, length); |
|
704 } |
|
705 |
|
706 // copy-constructor required to adopt on copy. Note that this |
|
707 // will violate the constness of |str| in the operator=() |
|
708 // call. |str| will be truncated as a side-effect of this |
|
709 // constructor. |
|
710 nsTAdoptingString_CharT( const self_type& str ) |
|
711 { |
|
712 *this = str; |
|
713 } |
|
714 |
|
715 // |operator=| does not inherit, so we must define our own |
|
716 self_type& operator=( const substring_type& str ) { Assign(str); return *this; } |
|
717 self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; } |
|
718 |
|
719 // Adopt(), if possible, when assigning to a self_type&. Note |
|
720 // that this violates the constness of str, str is always |
|
721 // truncated when this operator is called. |
|
722 self_type& operator=( const self_type& str ); |
|
723 |
|
724 private: |
|
725 self_type& operator=( const char_type* data ) MOZ_DELETE; |
|
726 self_type& operator=( char_type* data ) MOZ_DELETE; |
|
727 }; |
|
728 |