1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/string/public/nsTString.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,728 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 +// IWYU pragma: private, include "nsString.h" 1.10 + 1.11 + /** 1.12 + * This is the canonical null-terminated string class. All subclasses 1.13 + * promise null-terminated storage. Instances of this class allocate 1.14 + * strings on the heap. 1.15 + * 1.16 + * NAMES: 1.17 + * nsString for wide characters 1.18 + * nsCString for narrow characters 1.19 + * 1.20 + * This class is also known as nsAFlat[C]String, where "flat" is used 1.21 + * to denote a null-terminated string. 1.22 + */ 1.23 +class nsTString_CharT : public nsTSubstring_CharT 1.24 + { 1.25 + public: 1.26 + 1.27 + typedef nsTString_CharT self_type; 1.28 + 1.29 + public: 1.30 + 1.31 + /** 1.32 + * constructors 1.33 + */ 1.34 + 1.35 + nsTString_CharT() 1.36 + : substring_type() {} 1.37 + 1.38 + explicit 1.39 + nsTString_CharT( const char_type* data, size_type length = size_type(-1) ) 1.40 + : substring_type() 1.41 + { 1.42 + Assign(data, length); 1.43 + } 1.44 + 1.45 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.46 + explicit 1.47 + nsTString_CharT( char16ptr_t data, size_type length = size_type(-1) ) 1.48 + : substring_type() 1.49 + { 1.50 + Assign(static_cast<const char16_t*>(data), length); 1.51 + } 1.52 +#endif 1.53 + 1.54 + nsTString_CharT( const self_type& str ) 1.55 + : substring_type() 1.56 + { 1.57 + Assign(str); 1.58 + } 1.59 + 1.60 + nsTString_CharT( const substring_tuple_type& tuple ) 1.61 + : substring_type() 1.62 + { 1.63 + Assign(tuple); 1.64 + } 1.65 + 1.66 + explicit 1.67 + nsTString_CharT( const substring_type& readable ) 1.68 + : substring_type() 1.69 + { 1.70 + Assign(readable); 1.71 + } 1.72 + 1.73 + 1.74 + // |operator=| does not inherit, so we must define our own 1.75 + self_type& operator=( char_type c ) { Assign(c); return *this; } 1.76 + self_type& operator=( const char_type* data ) { Assign(data); return *this; } 1.77 + self_type& operator=( const self_type& str ) { Assign(str); return *this; } 1.78 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.79 + self_type& operator=( const char16ptr_t data ) { Assign(static_cast<const char16_t*>(data)); return *this; } 1.80 +#endif 1.81 + self_type& operator=( const substring_type& str ) { Assign(str); return *this; } 1.82 + self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; } 1.83 + 1.84 + /** 1.85 + * returns the null-terminated string 1.86 + */ 1.87 + 1.88 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.89 + char16ptr_t get() const 1.90 +#else 1.91 + const char_type* get() const 1.92 +#endif 1.93 + { 1.94 + return mData; 1.95 + } 1.96 + 1.97 + 1.98 + /** 1.99 + * returns character at specified index. 1.100 + * 1.101 + * NOTE: unlike nsTSubstring::CharAt, this function allows you to index 1.102 + * the null terminator character. 1.103 + */ 1.104 + 1.105 + char_type CharAt( index_type i ) const 1.106 + { 1.107 + NS_ASSERTION(i <= mLength, "index exceeds allowable range"); 1.108 + return mData[i]; 1.109 + } 1.110 + 1.111 + char_type operator[]( index_type i ) const 1.112 + { 1.113 + return CharAt(i); 1.114 + } 1.115 + 1.116 + 1.117 +#if MOZ_STRING_WITH_OBSOLETE_API 1.118 + 1.119 + 1.120 + /** 1.121 + * Search for the given substring within this string. 1.122 + * 1.123 + * @param aString is substring to be sought in this 1.124 + * @param aIgnoreCase selects case sensitivity 1.125 + * @param aOffset tells us where in this string to start searching 1.126 + * @param aCount tells us how far from the offset we are to search. Use 1.127 + * -1 to search the whole string. 1.128 + * @return offset in string, or kNotFound 1.129 + */ 1.130 + 1.131 + int32_t Find( const nsCString& aString, bool aIgnoreCase=false, int32_t aOffset=0, int32_t aCount=-1 ) const; 1.132 + int32_t Find( const char* aString, bool aIgnoreCase=false, int32_t aOffset=0, int32_t aCount=-1 ) const; 1.133 + 1.134 +#ifdef CharT_is_PRUnichar 1.135 + int32_t Find( const nsAFlatString& aString, int32_t aOffset=0, int32_t aCount=-1 ) const; 1.136 + int32_t Find( const char16_t* aString, int32_t aOffset=0, int32_t aCount=-1 ) const; 1.137 +#ifdef MOZ_USE_CHAR16_WRAPPER 1.138 + int32_t Find( char16ptr_t aString, int32_t aOffset=0, int32_t aCount=-1 ) const 1.139 + { 1.140 + return Find(static_cast<const char16_t*>(aString), aOffset, aCount); 1.141 + } 1.142 +#endif 1.143 +#endif 1.144 + 1.145 + 1.146 + /** 1.147 + * This methods scans the string backwards, looking for the given string 1.148 + * 1.149 + * @param aString is substring to be sought in this 1.150 + * @param aIgnoreCase tells us whether or not to do caseless compare 1.151 + * @param aOffset tells us where in this string to start searching. 1.152 + * Use -1 to search from the end of the string. 1.153 + * @param aCount tells us how many iterations to make starting at the 1.154 + * given offset. 1.155 + * @return offset in string, or kNotFound 1.156 + */ 1.157 + 1.158 + int32_t RFind( const nsCString& aString, bool aIgnoreCase=false, int32_t aOffset=-1, int32_t aCount=-1 ) const; 1.159 + int32_t RFind( const char* aCString, bool aIgnoreCase=false, int32_t aOffset=-1, int32_t aCount=-1 ) const; 1.160 + 1.161 +#ifdef CharT_is_PRUnichar 1.162 + int32_t RFind( const nsAFlatString& aString, int32_t aOffset=-1, int32_t aCount=-1 ) const; 1.163 + int32_t RFind( const char16_t* aString, int32_t aOffset=-1, int32_t aCount=-1 ) const; 1.164 +#endif 1.165 + 1.166 + 1.167 + /** 1.168 + * Search for given char within this string 1.169 + * 1.170 + * @param aChar is the character to search for 1.171 + * @param aOffset tells us where in this string to start searching 1.172 + * @param aCount tells us how far from the offset we are to search. 1.173 + * Use -1 to search the whole string. 1.174 + * @return offset in string, or kNotFound 1.175 + */ 1.176 + 1.177 + // int32_t FindChar( char16_t aChar, int32_t aOffset=0, int32_t aCount=-1 ) const; 1.178 + int32_t RFindChar( char16_t aChar, int32_t aOffset=-1, int32_t aCount=-1 ) const; 1.179 + 1.180 + 1.181 + /** 1.182 + * This method searches this string for the first character found in 1.183 + * the given string. 1.184 + * 1.185 + * @param aString contains set of chars to be found 1.186 + * @param aOffset tells us where in this string to start searching 1.187 + * (counting from left) 1.188 + * @return offset in string, or kNotFound 1.189 + */ 1.190 + 1.191 + int32_t FindCharInSet( const char* aString, int32_t aOffset=0 ) const; 1.192 + int32_t FindCharInSet( const self_type& aString, int32_t aOffset=0 ) const 1.193 + { 1.194 + return FindCharInSet(aString.get(), aOffset); 1.195 + } 1.196 + 1.197 +#ifdef CharT_is_PRUnichar 1.198 + int32_t FindCharInSet( const char16_t* aString, int32_t aOffset=0 ) const; 1.199 +#endif 1.200 + 1.201 + 1.202 + /** 1.203 + * This method searches this string for the last character found in 1.204 + * the given string. 1.205 + * 1.206 + * @param aString contains set of chars to be found 1.207 + * @param aOffset tells us where in this string to start searching 1.208 + * (counting from left) 1.209 + * @return offset in string, or kNotFound 1.210 + */ 1.211 + 1.212 + int32_t RFindCharInSet( const char_type* aString, int32_t aOffset=-1 ) const; 1.213 + int32_t RFindCharInSet( const self_type& aString, int32_t aOffset=-1 ) const 1.214 + { 1.215 + return RFindCharInSet(aString.get(), aOffset); 1.216 + } 1.217 + 1.218 + 1.219 + /** 1.220 + * Compares a given string to this string. 1.221 + * 1.222 + * @param aString is the string to be compared 1.223 + * @param aIgnoreCase tells us how to treat case 1.224 + * @param aCount tells us how many chars to compare 1.225 + * @return -1,0,1 1.226 + */ 1.227 + 1.228 +#ifdef CharT_is_char 1.229 + int32_t Compare( const char* aString, bool aIgnoreCase=false, int32_t aCount=-1 ) const; 1.230 +#endif 1.231 + 1.232 + 1.233 + /** 1.234 + * Equality check between given string and this string. 1.235 + * 1.236 + * @param aString is the string to check 1.237 + * @param aIgnoreCase tells us how to treat case 1.238 + * @param aCount tells us how many chars to compare 1.239 + * @return boolean 1.240 + */ 1.241 +#ifdef CharT_is_char 1.242 + bool EqualsIgnoreCase( const char* aString, int32_t aCount=-1 ) const { 1.243 + return Compare(aString, true, aCount) == 0; 1.244 + } 1.245 +#else 1.246 + bool EqualsIgnoreCase( const char* aString, int32_t aCount=-1 ) const; 1.247 + 1.248 + 1.249 +#endif // !CharT_is_PRUnichar 1.250 + 1.251 + /** 1.252 + * Perform string to double-precision float conversion. 1.253 + * 1.254 + * @param aErrorCode will contain error if one occurs 1.255 + * @return double-precision float rep of string value 1.256 + */ 1.257 + double ToDouble( nsresult* aErrorCode ) const; 1.258 + 1.259 + /** 1.260 + * Perform string to single-precision float conversion. 1.261 + * 1.262 + * @param aErrorCode will contain error if one occurs 1.263 + * @return single-precision float rep of string value 1.264 + */ 1.265 + float ToFloat( nsresult* aErrorCode ) const { 1.266 + return (float)ToDouble(aErrorCode); 1.267 + } 1.268 + 1.269 + 1.270 + /** 1.271 + * Perform string to int conversion. 1.272 + * @param aErrorCode will contain error if one occurs 1.273 + * @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you. 1.274 + * @return int rep of string value, and possible (out) error code 1.275 + */ 1.276 + int32_t ToInteger( nsresult* aErrorCode, uint32_t aRadix=kRadix10 ) const; 1.277 + 1.278 + /** 1.279 + * Perform string to 64-bit int conversion. 1.280 + * @param aErrorCode will contain error if one occurs 1.281 + * @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you. 1.282 + * @return 64-bit int rep of string value, and possible (out) error code 1.283 + */ 1.284 + int64_t ToInteger64( nsresult* aErrorCode, uint32_t aRadix=kRadix10 ) const; 1.285 + 1.286 + 1.287 + /** 1.288 + * |Left|, |Mid|, and |Right| are annoying signatures that seem better almost 1.289 + * any _other_ way than they are now. Consider these alternatives 1.290 + * 1.291 + * aWritable = aReadable.Left(17); // ...a member function that returns a |Substring| 1.292 + * aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring| 1.293 + * Left(aReadable, 17, aWritable); // ...a global function that does the assignment 1.294 + * 1.295 + * as opposed to the current signature 1.296 + * 1.297 + * aReadable.Left(aWritable, 17); // ...a member function that does the assignment 1.298 + * 1.299 + * or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality 1.300 + * 1.301 + * aWritable = Substring(aReadable, 0, 17); 1.302 + */ 1.303 + 1.304 + size_type Mid( self_type& aResult, uint32_t aStartPos, uint32_t aCount ) const; 1.305 + 1.306 + size_type Left( self_type& aResult, size_type aCount ) const 1.307 + { 1.308 + return Mid(aResult, 0, aCount); 1.309 + } 1.310 + 1.311 + size_type Right( self_type& aResult, size_type aCount ) const 1.312 + { 1.313 + aCount = XPCOM_MIN(mLength, aCount); 1.314 + return Mid(aResult, mLength - aCount, aCount); 1.315 + } 1.316 + 1.317 + 1.318 + /** 1.319 + * Set a char inside this string at given index 1.320 + * 1.321 + * @param aChar is the char you want to write into this string 1.322 + * @param anIndex is the ofs where you want to write the given char 1.323 + * @return TRUE if successful 1.324 + */ 1.325 + 1.326 + bool SetCharAt( char16_t aChar, uint32_t aIndex ); 1.327 + 1.328 + 1.329 + /** 1.330 + * These methods are used to remove all occurrences of the 1.331 + * characters found in aSet from this string. 1.332 + * 1.333 + * @param aSet -- characters to be cut from this 1.334 + */ 1.335 + void StripChars( const char* aSet ); 1.336 + 1.337 + 1.338 + /** 1.339 + * This method strips whitespace throughout the string. 1.340 + */ 1.341 + void StripWhitespace(); 1.342 + 1.343 + 1.344 + /** 1.345 + * swaps occurence of 1 string for another 1.346 + */ 1.347 + 1.348 + void ReplaceChar( char_type aOldChar, char_type aNewChar ); 1.349 + void ReplaceChar( const char* aSet, char_type aNewChar ); 1.350 +#ifdef CharT_is_PRUnichar 1.351 + void ReplaceChar( const char16_t* aSet, char16_t aNewChar ); 1.352 +#endif 1.353 + void ReplaceSubstring( const self_type& aTarget, const self_type& aNewValue); 1.354 + void ReplaceSubstring( const char_type* aTarget, const char_type* aNewValue); 1.355 + 1.356 + 1.357 + /** 1.358 + * This method trims characters found in aTrimSet from 1.359 + * either end of the underlying string. 1.360 + * 1.361 + * @param aSet -- contains chars to be trimmed from both ends 1.362 + * @param aEliminateLeading 1.363 + * @param aEliminateTrailing 1.364 + * @param aIgnoreQuotes -- if true, causes surrounding quotes to be ignored 1.365 + * @return this 1.366 + */ 1.367 + void Trim( const char* aSet, bool aEliminateLeading=true, bool aEliminateTrailing=true, bool aIgnoreQuotes=false ); 1.368 + 1.369 + /** 1.370 + * This method strips whitespace from string. 1.371 + * You can control whether whitespace is yanked from start and end of 1.372 + * string as well. 1.373 + * 1.374 + * @param aEliminateLeading controls stripping of leading ws 1.375 + * @param aEliminateTrailing controls stripping of trailing ws 1.376 + */ 1.377 + void CompressWhitespace( bool aEliminateLeading=true, bool aEliminateTrailing=true ); 1.378 + 1.379 + 1.380 + /** 1.381 + * assign/append/insert with _LOSSY_ conversion 1.382 + */ 1.383 + 1.384 + void AssignWithConversion( const nsTAString_IncompatibleCharT& aString ); 1.385 + void AssignWithConversion( const incompatible_char_type* aData, int32_t aLength=-1 ); 1.386 + 1.387 +#endif // !MOZ_STRING_WITH_OBSOLETE_API 1.388 + 1.389 + /** 1.390 + * Allow this string to be bound to a character buffer 1.391 + * until the string is rebound or mutated; the caller 1.392 + * must ensure that the buffer outlives the string. 1.393 + */ 1.394 + void Rebind( const char_type* data, size_type length ); 1.395 + 1.396 + /** 1.397 + * verify restrictions for dependent strings 1.398 + */ 1.399 + void AssertValidDepedentString() 1.400 + { 1.401 + NS_ASSERTION(mData, "nsTDependentString must wrap a non-NULL buffer"); 1.402 + NS_ASSERTION(mLength != size_type(-1), "nsTDependentString has bogus length"); 1.403 + NS_ASSERTION(mData[mLength] == 0, "nsTDependentString must wrap only null-terminated strings. You are probably looking for nsTDependentSubstring."); 1.404 + } 1.405 + 1.406 + 1.407 + protected: 1.408 + 1.409 + explicit 1.410 + nsTString_CharT( uint32_t flags ) 1.411 + : substring_type(flags) {} 1.412 + 1.413 + // allow subclasses to initialize fields directly 1.414 + nsTString_CharT( char_type* data, size_type length, uint32_t flags ) 1.415 + : substring_type(data, length, flags) {} 1.416 +}; 1.417 + 1.418 + 1.419 +class nsTFixedString_CharT : public nsTString_CharT 1.420 + { 1.421 + public: 1.422 + 1.423 + typedef nsTFixedString_CharT self_type; 1.424 + typedef nsTFixedString_CharT fixed_string_type; 1.425 + 1.426 + public: 1.427 + 1.428 + /** 1.429 + * @param data 1.430 + * fixed-size buffer to be used by the string (the contents of 1.431 + * this buffer may be modified by the string) 1.432 + * @param storageSize 1.433 + * the size of the fixed buffer 1.434 + * @param length (optional) 1.435 + * the length of the string already contained in the buffer 1.436 + */ 1.437 + 1.438 + nsTFixedString_CharT( char_type* data, size_type storageSize ) 1.439 + : string_type(data, uint32_t(char_traits::length(data)), F_TERMINATED | F_FIXED | F_CLASS_FIXED) 1.440 + , mFixedCapacity(storageSize - 1) 1.441 + , mFixedBuf(data) 1.442 + {} 1.443 + 1.444 + nsTFixedString_CharT( char_type* data, size_type storageSize, size_type length ) 1.445 + : string_type(data, length, F_TERMINATED | F_FIXED | F_CLASS_FIXED) 1.446 + , mFixedCapacity(storageSize - 1) 1.447 + , mFixedBuf(data) 1.448 + { 1.449 + // null-terminate 1.450 + mFixedBuf[length] = char_type(0); 1.451 + } 1.452 + 1.453 + // |operator=| does not inherit, so we must define our own 1.454 + self_type& operator=( char_type c ) { Assign(c); return *this; } 1.455 + self_type& operator=( const char_type* data ) { Assign(data); return *this; } 1.456 + self_type& operator=( const substring_type& str ) { Assign(str); return *this; } 1.457 + self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; } 1.458 + 1.459 + protected: 1.460 + 1.461 + friend class nsTSubstring_CharT; 1.462 + 1.463 + size_type mFixedCapacity; 1.464 + char_type *mFixedBuf; 1.465 + }; 1.466 + 1.467 + 1.468 + /** 1.469 + * nsTAutoString_CharT 1.470 + * 1.471 + * Subclass of nsTString_CharT that adds support for stack-based string 1.472 + * allocation. It is normally not a good idea to use this class on the 1.473 + * heap, because it will allocate space which may be wasted if the string 1.474 + * it contains is significantly smaller or any larger than 64 characters. 1.475 + * 1.476 + * NAMES: 1.477 + * nsAutoString for wide characters 1.478 + * nsAutoCString for narrow characters 1.479 + */ 1.480 +class nsTAutoString_CharT : public nsTFixedString_CharT 1.481 + { 1.482 + public: 1.483 + 1.484 + typedef nsTAutoString_CharT self_type; 1.485 + 1.486 + public: 1.487 + 1.488 + /** 1.489 + * constructors 1.490 + */ 1.491 + 1.492 + nsTAutoString_CharT() 1.493 + : fixed_string_type(mStorage, kDefaultStorageSize, 0) 1.494 + {} 1.495 + 1.496 + explicit 1.497 + nsTAutoString_CharT( char_type c ) 1.498 + : fixed_string_type(mStorage, kDefaultStorageSize, 0) 1.499 + { 1.500 + Assign(c); 1.501 + } 1.502 + 1.503 + explicit 1.504 + nsTAutoString_CharT( const char_type* data, size_type length = size_type(-1) ) 1.505 + : fixed_string_type(mStorage, kDefaultStorageSize, 0) 1.506 + { 1.507 + Assign(data, length); 1.508 + } 1.509 + 1.510 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.511 + explicit 1.512 + nsTAutoString_CharT( char16ptr_t data, size_type length = size_type(-1) ) 1.513 + : nsTAutoString_CharT(static_cast<const char16_t*>(data), length) 1.514 + {} 1.515 +#endif 1.516 + 1.517 + nsTAutoString_CharT( const self_type& str ) 1.518 + : fixed_string_type(mStorage, kDefaultStorageSize, 0) 1.519 + { 1.520 + Assign(str); 1.521 + } 1.522 + 1.523 + explicit 1.524 + nsTAutoString_CharT( const substring_type& str ) 1.525 + : fixed_string_type(mStorage, kDefaultStorageSize, 0) 1.526 + { 1.527 + Assign(str); 1.528 + } 1.529 + 1.530 + nsTAutoString_CharT( const substring_tuple_type& tuple ) 1.531 + : fixed_string_type(mStorage, kDefaultStorageSize, 0) 1.532 + { 1.533 + Assign(tuple); 1.534 + } 1.535 + 1.536 + // |operator=| does not inherit, so we must define our own 1.537 + self_type& operator=( char_type c ) { Assign(c); return *this; } 1.538 + self_type& operator=( const char_type* data ) { Assign(data); return *this; } 1.539 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.540 + self_type& operator=( char16ptr_t data ) { Assign(data); return *this; } 1.541 +#endif 1.542 + self_type& operator=( const self_type& str ) { Assign(str); return *this; } 1.543 + self_type& operator=( const substring_type& str ) { Assign(str); return *this; } 1.544 + self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; } 1.545 + 1.546 + enum { kDefaultStorageSize = 64 }; 1.547 + 1.548 + private: 1.549 + 1.550 + char_type mStorage[kDefaultStorageSize]; 1.551 + }; 1.552 + 1.553 + 1.554 + // 1.555 + // nsAutoString stores pointers into itself which are invalidated when an 1.556 + // nsTArray is resized, so nsTArray must not be instantiated with nsAutoString 1.557 + // elements! 1.558 + // 1.559 + template<class E> class nsTArrayElementTraits; 1.560 + template<> 1.561 + class nsTArrayElementTraits<nsTAutoString_CharT> { 1.562 + public: 1.563 + template<class A> struct Dont_Instantiate_nsTArray_of; 1.564 + template<class A> struct Instead_Use_nsTArray_of; 1.565 + 1.566 + static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT> * 1.567 + Construct(Instead_Use_nsTArray_of<nsTString_CharT> *e) { 1.568 + return 0; 1.569 + } 1.570 + template<class A> 1.571 + static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT> * 1.572 + Construct(Instead_Use_nsTArray_of<nsTString_CharT> *e, 1.573 + const A &arg) { 1.574 + return 0; 1.575 + } 1.576 + static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT> * 1.577 + Destruct(Instead_Use_nsTArray_of<nsTString_CharT> *e) { 1.578 + return 0; 1.579 + } 1.580 + }; 1.581 + 1.582 + /** 1.583 + * nsTXPIDLString extends nsTString such that: 1.584 + * 1.585 + * (1) mData can be null 1.586 + * (2) objects of this type can be automatically cast to |const CharT*| 1.587 + * (3) getter_Copies method is supported to adopt data allocated with 1.588 + * NS_Alloc, such as "out string" parameters in XPIDL. 1.589 + * 1.590 + * NAMES: 1.591 + * nsXPIDLString for wide characters 1.592 + * nsXPIDLCString for narrow characters 1.593 + */ 1.594 +class nsTXPIDLString_CharT : public nsTString_CharT 1.595 + { 1.596 + public: 1.597 + 1.598 + typedef nsTXPIDLString_CharT self_type; 1.599 + 1.600 + public: 1.601 + 1.602 + nsTXPIDLString_CharT() 1.603 + : string_type(char_traits::sEmptyBuffer, 0, F_TERMINATED | F_VOIDED) {} 1.604 + 1.605 + // copy-constructor required to avoid default 1.606 + nsTXPIDLString_CharT( const self_type& str ) 1.607 + : string_type(char_traits::sEmptyBuffer, 0, F_TERMINATED | F_VOIDED) 1.608 + { 1.609 + Assign(str); 1.610 + } 1.611 + 1.612 + // return nullptr if we are voided 1.613 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.614 + char16ptr_t get() const 1.615 +#else 1.616 + const char_type* get() const 1.617 +#endif 1.618 + { 1.619 + return (mFlags & F_VOIDED) ? nullptr : mData; 1.620 + } 1.621 + 1.622 + // this case operator is the reason why this class cannot just be a 1.623 + // typedef for nsTString 1.624 + operator const char_type*() const 1.625 + { 1.626 + return get(); 1.627 + } 1.628 + 1.629 + // need this to diambiguous operator[int] 1.630 + char_type operator[]( int32_t i ) const 1.631 + { 1.632 + return CharAt(index_type(i)); 1.633 + } 1.634 + 1.635 + // |operator=| does not inherit, so we must define our own 1.636 + self_type& operator=( char_type c ) { Assign(c); return *this; } 1.637 + self_type& operator=( const char_type* data ) { Assign(data); return *this; } 1.638 + self_type& operator=( const self_type& str ) { Assign(str); return *this; } 1.639 + self_type& operator=( const substring_type& str ) { Assign(str); return *this; } 1.640 + self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; } 1.641 + }; 1.642 + 1.643 + 1.644 + /** 1.645 + * getter_Copies support for use with raw string out params: 1.646 + * 1.647 + * NS_IMETHOD GetBlah(char**); 1.648 + * 1.649 + * void some_function() 1.650 + * { 1.651 + * nsXPIDLCString blah; 1.652 + * GetBlah(getter_Copies(blah)); 1.653 + * // ... 1.654 + * } 1.655 + */ 1.656 +class MOZ_STACK_CLASS nsTGetterCopies_CharT 1.657 + { 1.658 + public: 1.659 + typedef CharT char_type; 1.660 + 1.661 + nsTGetterCopies_CharT(nsTSubstring_CharT& str) 1.662 + : mString(str), mData(nullptr) {} 1.663 + 1.664 + ~nsTGetterCopies_CharT() 1.665 + { 1.666 + mString.Adopt(mData); // OK if mData is null 1.667 + } 1.668 + 1.669 + operator char_type**() 1.670 + { 1.671 + return &mData; 1.672 + } 1.673 + 1.674 + private: 1.675 + nsTSubstring_CharT& mString; 1.676 + char_type* mData; 1.677 + }; 1.678 + 1.679 +inline 1.680 +nsTGetterCopies_CharT 1.681 +getter_Copies( nsTSubstring_CharT& aString ) 1.682 + { 1.683 + return nsTGetterCopies_CharT(aString); 1.684 + } 1.685 + 1.686 + 1.687 + /** 1.688 + * nsTAdoptingString extends nsTXPIDLString such that: 1.689 + * 1.690 + * (1) Adopt given string on construction or assignment, i.e. take 1.691 + * the value of what's given, and make what's given forget its 1.692 + * value. Note that this class violates constness in a few 1.693 + * places. Be careful! 1.694 + */ 1.695 +class nsTAdoptingString_CharT : public nsTXPIDLString_CharT 1.696 + { 1.697 + public: 1.698 + 1.699 + typedef nsTAdoptingString_CharT self_type; 1.700 + 1.701 + public: 1.702 + 1.703 + explicit nsTAdoptingString_CharT() {} 1.704 + explicit nsTAdoptingString_CharT(char_type* str, size_type length = size_type(-1)) 1.705 + { 1.706 + Adopt(str, length); 1.707 + } 1.708 + 1.709 + // copy-constructor required to adopt on copy. Note that this 1.710 + // will violate the constness of |str| in the operator=() 1.711 + // call. |str| will be truncated as a side-effect of this 1.712 + // constructor. 1.713 + nsTAdoptingString_CharT( const self_type& str ) 1.714 + { 1.715 + *this = str; 1.716 + } 1.717 + 1.718 + // |operator=| does not inherit, so we must define our own 1.719 + self_type& operator=( const substring_type& str ) { Assign(str); return *this; } 1.720 + self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; } 1.721 + 1.722 + // Adopt(), if possible, when assigning to a self_type&. Note 1.723 + // that this violates the constness of str, str is always 1.724 + // truncated when this operator is called. 1.725 + self_type& operator=( const self_type& str ); 1.726 + 1.727 + private: 1.728 + self_type& operator=( const char_type* data ) MOZ_DELETE; 1.729 + self_type& operator=( char_type* data ) MOZ_DELETE; 1.730 + }; 1.731 +