xpcom/string/public/nsTString.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial