1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/string/public/nsTSubstring.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,956 @@ 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 +#include "mozilla/Casting.h" 1.12 +#include "mozilla/MemoryReporting.h" 1.13 + 1.14 +#ifndef MOZILLA_INTERNAL_API 1.15 +#error Cannot use internal string classes without MOZILLA_INTERNAL_API defined. Use the frozen header nsStringAPI.h instead. 1.16 +#endif 1.17 + 1.18 + /** 1.19 + * The base for string comparators 1.20 + */ 1.21 +class nsTStringComparator_CharT 1.22 + { 1.23 + public: 1.24 + typedef CharT char_type; 1.25 + 1.26 + nsTStringComparator_CharT() {} 1.27 + 1.28 + virtual int operator()( const char_type*, const char_type*, uint32_t, uint32_t ) const = 0; 1.29 + }; 1.30 + 1.31 + 1.32 + /** 1.33 + * The default string comparator (case-sensitive comparision) 1.34 + */ 1.35 +class nsTDefaultStringComparator_CharT 1.36 + : public nsTStringComparator_CharT 1.37 + { 1.38 + public: 1.39 + typedef CharT char_type; 1.40 + 1.41 + nsTDefaultStringComparator_CharT() {} 1.42 + 1.43 + virtual int operator()( const char_type*, const char_type*, uint32_t, uint32_t ) const; 1.44 + }; 1.45 + 1.46 + /** 1.47 + * nsTSubstring is the most abstract class in the string hierarchy. It 1.48 + * represents a single contiguous array of characters, which may or may not 1.49 + * be null-terminated. This type is not instantiated directly. A sub-class 1.50 + * is instantiated instead. For example, see nsTString. 1.51 + * 1.52 + * NAMES: 1.53 + * nsAString for wide characters 1.54 + * nsACString for narrow characters 1.55 + * 1.56 + * Many of the accessors on nsTSubstring are inlined as an optimization. 1.57 + */ 1.58 +class nsTSubstring_CharT 1.59 + { 1.60 + public: 1.61 + typedef mozilla::fallible_t fallible_t; 1.62 + 1.63 + typedef CharT char_type; 1.64 + 1.65 + typedef nsCharTraits<char_type> char_traits; 1.66 + typedef char_traits::incompatible_char_type incompatible_char_type; 1.67 + 1.68 + typedef nsTSubstring_CharT self_type; 1.69 + typedef self_type abstract_string_type; 1.70 + typedef self_type base_string_type; 1.71 + 1.72 + typedef self_type substring_type; 1.73 + typedef nsTSubstringTuple_CharT substring_tuple_type; 1.74 + typedef nsTString_CharT string_type; 1.75 + 1.76 + typedef nsReadingIterator<char_type> const_iterator; 1.77 + typedef nsWritingIterator<char_type> iterator; 1.78 + 1.79 + typedef nsTStringComparator_CharT comparator_type; 1.80 + 1.81 + typedef char_type* char_iterator; 1.82 + typedef const char_type* const_char_iterator; 1.83 + 1.84 + typedef uint32_t size_type; 1.85 + typedef uint32_t index_type; 1.86 + 1.87 + public: 1.88 + 1.89 + // this acts like a virtual destructor 1.90 + ~nsTSubstring_CharT() { Finalize(); } 1.91 + 1.92 + /** 1.93 + * reading iterators 1.94 + */ 1.95 + 1.96 + const_char_iterator BeginReading() const { return mData; } 1.97 + const_char_iterator EndReading() const { return mData + mLength; } 1.98 + 1.99 + /** 1.100 + * deprecated reading iterators 1.101 + */ 1.102 + 1.103 + const_iterator& BeginReading( const_iterator& iter ) const 1.104 + { 1.105 + iter.mStart = mData; 1.106 + iter.mEnd = mData + mLength; 1.107 + iter.mPosition = iter.mStart; 1.108 + return iter; 1.109 + } 1.110 + 1.111 + const_iterator& EndReading( const_iterator& iter ) const 1.112 + { 1.113 + iter.mStart = mData; 1.114 + iter.mEnd = mData + mLength; 1.115 + iter.mPosition = iter.mEnd; 1.116 + return iter; 1.117 + } 1.118 + 1.119 + const_char_iterator& BeginReading( const_char_iterator& iter ) const 1.120 + { 1.121 + return iter = mData; 1.122 + } 1.123 + 1.124 + const_char_iterator& EndReading( const_char_iterator& iter ) const 1.125 + { 1.126 + return iter = mData + mLength; 1.127 + } 1.128 + 1.129 + 1.130 + /** 1.131 + * writing iterators 1.132 + */ 1.133 + 1.134 + char_iterator BeginWriting() 1.135 + { 1.136 + if (!EnsureMutable()) 1.137 + NS_ABORT_OOM(mLength); 1.138 + 1.139 + return mData; 1.140 + } 1.141 + 1.142 + char_iterator BeginWriting( const fallible_t& ) 1.143 + { 1.144 + return EnsureMutable() ? mData : char_iterator(0); 1.145 + } 1.146 + 1.147 + char_iterator EndWriting() 1.148 + { 1.149 + if (!EnsureMutable()) 1.150 + NS_ABORT_OOM(mLength); 1.151 + 1.152 + return mData + mLength; 1.153 + } 1.154 + 1.155 + char_iterator EndWriting( const fallible_t& ) 1.156 + { 1.157 + return EnsureMutable() ? (mData + mLength) : char_iterator(0); 1.158 + } 1.159 + 1.160 + char_iterator& BeginWriting( char_iterator& iter ) 1.161 + { 1.162 + return iter = BeginWriting(); 1.163 + } 1.164 + 1.165 + char_iterator& BeginWriting( char_iterator& iter, const fallible_t& ) 1.166 + { 1.167 + return iter = BeginWriting(fallible_t()); 1.168 + } 1.169 + 1.170 + char_iterator& EndWriting( char_iterator& iter ) 1.171 + { 1.172 + return iter = EndWriting(); 1.173 + } 1.174 + 1.175 + char_iterator& EndWriting( char_iterator& iter, const fallible_t& ) 1.176 + { 1.177 + return iter = EndWriting(fallible_t()); 1.178 + } 1.179 + 1.180 + /** 1.181 + * deprecated writing iterators 1.182 + */ 1.183 + 1.184 + iterator& BeginWriting( iterator& iter ) 1.185 + { 1.186 + char_type *data = BeginWriting(); 1.187 + iter.mStart = data; 1.188 + iter.mEnd = data + mLength; 1.189 + iter.mPosition = iter.mStart; 1.190 + return iter; 1.191 + } 1.192 + 1.193 + iterator& EndWriting( iterator& iter ) 1.194 + { 1.195 + char_type *data = BeginWriting(); 1.196 + iter.mStart = data; 1.197 + iter.mEnd = data + mLength; 1.198 + iter.mPosition = iter.mEnd; 1.199 + return iter; 1.200 + } 1.201 + 1.202 + /** 1.203 + * accessors 1.204 + */ 1.205 + 1.206 + // returns pointer to string data (not necessarily null-terminated) 1.207 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.208 + char16ptr_t Data() const 1.209 +#else 1.210 + const char_type *Data() const 1.211 +#endif 1.212 + { 1.213 + return mData; 1.214 + } 1.215 + 1.216 + size_type Length() const 1.217 + { 1.218 + return mLength; 1.219 + } 1.220 + 1.221 + uint32_t Flags() const 1.222 + { 1.223 + return mFlags; 1.224 + } 1.225 + 1.226 + bool IsEmpty() const 1.227 + { 1.228 + return mLength == 0; 1.229 + } 1.230 + 1.231 + bool IsLiteral() const 1.232 + { 1.233 + return (mFlags & F_LITERAL) != 0; 1.234 + } 1.235 + 1.236 + bool IsVoid() const 1.237 + { 1.238 + return (mFlags & F_VOIDED) != 0; 1.239 + } 1.240 + 1.241 + bool IsTerminated() const 1.242 + { 1.243 + return (mFlags & F_TERMINATED) != 0; 1.244 + } 1.245 + 1.246 + char_type CharAt( index_type i ) const 1.247 + { 1.248 + NS_ASSERTION(i < mLength, "index exceeds allowable range"); 1.249 + return mData[i]; 1.250 + } 1.251 + 1.252 + char_type operator[]( index_type i ) const 1.253 + { 1.254 + return CharAt(i); 1.255 + } 1.256 + 1.257 + char_type First() const 1.258 + { 1.259 + NS_ASSERTION(mLength > 0, "|First()| called on an empty string"); 1.260 + return mData[0]; 1.261 + } 1.262 + 1.263 + inline 1.264 + char_type Last() const 1.265 + { 1.266 + NS_ASSERTION(mLength > 0, "|Last()| called on an empty string"); 1.267 + return mData[mLength - 1]; 1.268 + } 1.269 + 1.270 + size_type NS_FASTCALL CountChar( char_type ) const; 1.271 + int32_t NS_FASTCALL FindChar( char_type, index_type offset = 0 ) const; 1.272 + 1.273 + 1.274 + /** 1.275 + * equality 1.276 + */ 1.277 + 1.278 + bool NS_FASTCALL Equals( const self_type& ) const; 1.279 + bool NS_FASTCALL Equals( const self_type&, const comparator_type& ) const; 1.280 + 1.281 + bool NS_FASTCALL Equals( const char_type* data ) const; 1.282 + bool NS_FASTCALL Equals( const char_type* data, const comparator_type& comp ) const; 1.283 + 1.284 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.285 + bool NS_FASTCALL Equals( char16ptr_t data ) const 1.286 + { 1.287 + return Equals(static_cast<const char16_t*>(data)); 1.288 + } 1.289 + bool NS_FASTCALL Equals( char16ptr_t data, const comparator_type& comp ) const 1.290 + { 1.291 + return Equals(static_cast<const char16_t*>(data), comp); 1.292 + } 1.293 +#endif 1.294 + 1.295 + /** 1.296 + * An efficient comparison with ASCII that can be used even 1.297 + * for wide strings. Call this version when you know the 1.298 + * length of 'data'. 1.299 + */ 1.300 + bool NS_FASTCALL EqualsASCII( const char* data, size_type len ) const; 1.301 + /** 1.302 + * An efficient comparison with ASCII that can be used even 1.303 + * for wide strings. Call this version when 'data' is 1.304 + * null-terminated. 1.305 + */ 1.306 + bool NS_FASTCALL EqualsASCII( const char* data ) const; 1.307 + 1.308 + // EqualsLiteral must ONLY be applied to an actual literal string, or 1.309 + // a char array *constant* declared without an explicit size. 1.310 + // Do not attempt to use it with a regular char* pointer, or with a 1.311 + // non-constant char array variable. Use EqualsASCII for them. 1.312 + // The template trick to acquire the array length at compile time without 1.313 + // using a macro is due to Corey Kosak, with much thanks. 1.314 + template<int N> 1.315 + inline bool EqualsLiteral( const char (&str)[N] ) const 1.316 + { 1.317 + return EqualsASCII(str, N-1); 1.318 + } 1.319 + 1.320 + // The LowerCaseEquals methods compare the ASCII-lowercase version of 1.321 + // this string (lowercasing only ASCII uppercase characters) to some 1.322 + // ASCII/Literal string. The ASCII string is *not* lowercased for 1.323 + // you. If you compare to an ASCII or literal string that contains an 1.324 + // uppercase character, it is guaranteed to return false. We will 1.325 + // throw assertions too. 1.326 + bool NS_FASTCALL LowerCaseEqualsASCII( const char* data, size_type len ) const; 1.327 + bool NS_FASTCALL LowerCaseEqualsASCII( const char* data ) const; 1.328 + 1.329 + // LowerCaseEqualsLiteral must ONLY be applied to an actual 1.330 + // literal string, or a char array *constant* declared without an 1.331 + // explicit size. Do not attempt to use it with a regular char* 1.332 + // pointer, or with a non-constant char array variable. Use 1.333 + // LowerCaseEqualsASCII for them. 1.334 + template<int N> 1.335 + inline bool LowerCaseEqualsLiteral( const char (&str)[N] ) const 1.336 + { 1.337 + return LowerCaseEqualsASCII(str, N-1); 1.338 + } 1.339 + 1.340 + /** 1.341 + * assignment 1.342 + */ 1.343 + 1.344 + void NS_FASTCALL Assign( char_type c ); 1.345 + bool NS_FASTCALL Assign( char_type c, const fallible_t& ) NS_WARN_UNUSED_RESULT; 1.346 + 1.347 + void NS_FASTCALL Assign( const char_type* data ); 1.348 + void NS_FASTCALL Assign( const char_type* data, size_type length ); 1.349 + bool NS_FASTCALL Assign( const char_type* data, size_type length, const fallible_t& ) NS_WARN_UNUSED_RESULT; 1.350 + 1.351 + void NS_FASTCALL Assign( const self_type& ); 1.352 + bool NS_FASTCALL Assign( const self_type&, const fallible_t& ) NS_WARN_UNUSED_RESULT; 1.353 + 1.354 + void NS_FASTCALL Assign( const substring_tuple_type& ); 1.355 + bool NS_FASTCALL Assign( const substring_tuple_type&, const fallible_t& ) NS_WARN_UNUSED_RESULT; 1.356 + 1.357 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.358 + void Assign (char16ptr_t data) 1.359 + { 1.360 + Assign(static_cast<const char16_t*>(data)); 1.361 + } 1.362 + 1.363 + bool Assign(char16ptr_t data, const fallible_t&) NS_WARN_UNUSED_RESULT 1.364 + { 1.365 + return Assign(static_cast<const char16_t*>(data), fallible_t()); 1.366 + } 1.367 + 1.368 + void Assign (char16ptr_t data, size_type length) 1.369 + { 1.370 + Assign(static_cast<const char16_t*>(data), length); 1.371 + } 1.372 + 1.373 + bool Assign(char16ptr_t data, size_type length, const fallible_t&) NS_WARN_UNUSED_RESULT 1.374 + { 1.375 + return Assign(static_cast<const char16_t*>(data), length, fallible_t()); 1.376 + } 1.377 +#endif 1.378 + 1.379 + void NS_FASTCALL AssignASCII( const char* data, size_type length ); 1.380 + bool NS_FASTCALL AssignASCII( const char* data, size_type length, const fallible_t& ) NS_WARN_UNUSED_RESULT; 1.381 + 1.382 + void NS_FASTCALL AssignASCII( const char* data ) 1.383 + { 1.384 + AssignASCII(data, mozilla::SafeCast<size_type, size_t>(strlen(data))); 1.385 + } 1.386 + bool NS_FASTCALL AssignASCII( const char* data, const fallible_t& ) NS_WARN_UNUSED_RESULT 1.387 + { 1.388 + return AssignASCII(data, mozilla::SafeCast<size_type, size_t>(strlen(data)), fallible_t()); 1.389 + } 1.390 + 1.391 + // AssignLiteral must ONLY be applied to an actual literal string, or 1.392 + // a char array *constant* declared without an explicit size. 1.393 + // Do not attempt to use it with a regular char* pointer, or with a 1.394 + // non-constant char array variable. Use AssignASCII for those. 1.395 + // There are not fallible version of these methods because they only really 1.396 + // apply to small allocations that we wouldn't want to check anyway. 1.397 + template<int N> 1.398 + void AssignLiteral( const char_type (&str)[N] ) 1.399 + { AssignLiteral(str, N - 1); } 1.400 +#ifdef CharT_is_PRUnichar 1.401 + template<int N> 1.402 + void AssignLiteral( const char (&str)[N] ) 1.403 + { AssignASCII(str, N-1); } 1.404 +#endif 1.405 + 1.406 + self_type& operator=( char_type c ) { Assign(c); return *this; } 1.407 + self_type& operator=( const char_type* data ) { Assign(data); return *this; } 1.408 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.409 + self_type& operator=( char16ptr_t data ) { Assign(data); return *this; } 1.410 +#endif 1.411 + self_type& operator=( const self_type& str ) { Assign(str); return *this; } 1.412 + self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; } 1.413 + 1.414 + void NS_FASTCALL Adopt( char_type* data, size_type length = size_type(-1) ); 1.415 + 1.416 + 1.417 + /** 1.418 + * buffer manipulation 1.419 + */ 1.420 + 1.421 + void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, char_type c ); 1.422 + bool NS_FASTCALL Replace( index_type cutStart, size_type cutLength, char_type c, const mozilla::fallible_t&) NS_WARN_UNUSED_RESULT; 1.423 + void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length = size_type(-1) ); 1.424 + bool NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length, const mozilla::fallible_t&) NS_WARN_UNUSED_RESULT; 1.425 + void Replace( index_type cutStart, size_type cutLength, const self_type& str ) { Replace(cutStart, cutLength, str.Data(), str.Length()); } 1.426 + bool Replace( index_type cutStart, size_type cutLength, const self_type& str, const mozilla::fallible_t&) NS_WARN_UNUSED_RESULT 1.427 + { return Replace(cutStart, cutLength, str.Data(), str.Length(), mozilla::fallible_t()); } 1.428 + void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& tuple ); 1.429 + 1.430 + void NS_FASTCALL ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) ); 1.431 + 1.432 + // ReplaceLiteral must ONLY be applied to an actual literal string. 1.433 + // Do not attempt to use it with a regular char* pointer, or with a char 1.434 + // array variable. Use Replace or ReplaceASCII for those. 1.435 + template<int N> 1.436 + void ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type (&str)[N] ) { ReplaceLiteral(cutStart, cutLength, str, N - 1); } 1.437 + 1.438 + void Append( char_type c ) { Replace(mLength, 0, c); } 1.439 + bool Append( char_type c, const mozilla::fallible_t&) NS_WARN_UNUSED_RESULT { return Replace(mLength, 0, c, mozilla::fallible_t()); } 1.440 + void Append( const char_type* data, size_type length = size_type(-1) ) { Replace(mLength, 0, data, length); } 1.441 + bool Append( const char_type* data, size_type length, const mozilla::fallible_t&) NS_WARN_UNUSED_RESULT 1.442 + { return Replace(mLength, 0, data, length, mozilla::fallible_t()); } 1.443 + 1.444 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.445 + void Append( char16ptr_t data, size_type length = size_type(-1) ) { Append(static_cast<const char16_t*>(data), length); } 1.446 +#endif 1.447 + 1.448 + void Append( const self_type& str ) { Replace(mLength, 0, str); } 1.449 + void Append( const substring_tuple_type& tuple ) { Replace(mLength, 0, tuple); } 1.450 + 1.451 + void AppendASCII( const char* data, size_type length = size_type(-1) ) { ReplaceASCII(mLength, 0, data, length); } 1.452 + 1.453 + /** 1.454 + * Append a formatted string to the current string. Uses the format 1.455 + * codes documented in prprf.h 1.456 + */ 1.457 + void AppendPrintf( const char* format, ... ); 1.458 + void AppendPrintf( const char* format, va_list ap ); 1.459 + void AppendInt( int32_t aInteger ) 1.460 + { AppendPrintf( "%d", aInteger ); } 1.461 + void AppendInt( int32_t aInteger, int aRadix ) 1.462 + { 1.463 + const char *fmt = aRadix == 10 ? "%d" : aRadix == 8 ? "%o" : "%x"; 1.464 + AppendPrintf( fmt, aInteger ); 1.465 + } 1.466 + void AppendInt( uint32_t aInteger ) 1.467 + { AppendPrintf( "%u", aInteger ); } 1.468 + void AppendInt( uint32_t aInteger, int aRadix ) 1.469 + { 1.470 + const char *fmt = aRadix == 10 ? "%u" : aRadix == 8 ? "%o" : "%x"; 1.471 + AppendPrintf( fmt, aInteger ); 1.472 + } 1.473 + void AppendInt( int64_t aInteger ) 1.474 + { AppendPrintf( "%lld", aInteger ); } 1.475 + void AppendInt( int64_t aInteger, int aRadix ) 1.476 + { 1.477 + const char *fmt = aRadix == 10 ? "%lld" : aRadix == 8 ? "%llo" : "%llx"; 1.478 + AppendPrintf( fmt, aInteger ); 1.479 + } 1.480 + void AppendInt( uint64_t aInteger ) 1.481 + { AppendPrintf( "%llu", aInteger ); } 1.482 + void AppendInt( uint64_t aInteger, int aRadix ) 1.483 + { 1.484 + const char *fmt = aRadix == 10 ? "%llu" : aRadix == 8 ? "%llo" : "%llx"; 1.485 + AppendPrintf( fmt, aInteger ); 1.486 + } 1.487 + 1.488 + /** 1.489 + * Append the given float to this string 1.490 + */ 1.491 + void NS_FASTCALL AppendFloat( float aFloat ); 1.492 + void NS_FASTCALL AppendFloat( double aFloat ); 1.493 + public: 1.494 + 1.495 + // AppendLiteral must ONLY be applied to an actual literal string. 1.496 + // Do not attempt to use it with a regular char* pointer, or with a char 1.497 + // array variable. Use Append or AppendASCII for those. 1.498 + template<int N> 1.499 + void AppendLiteral( const char_type (&str)[N] ) { ReplaceLiteral(mLength, 0, str, N - 1); } 1.500 +#ifdef CharT_is_PRUnichar 1.501 + template<int N> 1.502 + void AppendLiteral( const char (&str)[N] ) 1.503 + { AppendASCII(str, N-1); } 1.504 +#endif 1.505 + 1.506 + self_type& operator+=( char_type c ) { Append(c); return *this; } 1.507 + self_type& operator+=( const char_type* data ) { Append(data); return *this; } 1.508 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.509 + self_type& operator+=( char16ptr_t data ) { Append(data); return *this; } 1.510 +#endif 1.511 + self_type& operator+=( const self_type& str ) { Append(str); return *this; } 1.512 + self_type& operator+=( const substring_tuple_type& tuple ) { Append(tuple); return *this; } 1.513 + 1.514 + void Insert( char_type c, index_type pos ) { Replace(pos, 0, c); } 1.515 + void Insert( const char_type* data, index_type pos, size_type length = size_type(-1) ) { Replace(pos, 0, data, length); } 1.516 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.517 + void Insert( char16ptr_t data, index_type pos, size_type length = size_type(-1) ) 1.518 + { Insert(static_cast<const char16_t*>(data), pos, length); } 1.519 +#endif 1.520 + void Insert( const self_type& str, index_type pos ) { Replace(pos, 0, str); } 1.521 + void Insert( const substring_tuple_type& tuple, index_type pos ) { Replace(pos, 0, tuple); } 1.522 + 1.523 + // InsertLiteral must ONLY be applied to an actual literal string. 1.524 + // Do not attempt to use it with a regular char* pointer, or with a char 1.525 + // array variable. Use Insert for those. 1.526 + template<int N> 1.527 + void InsertLiteral( const char_type (&str)[N], index_type pos ) { ReplaceLiteral(pos, 0, str, N - 1); } 1.528 + 1.529 + void Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, char_traits::sEmptyBuffer, 0); } 1.530 + 1.531 + 1.532 + /** 1.533 + * buffer sizing 1.534 + */ 1.535 + 1.536 + /** 1.537 + * Attempts to set the capacity to the given size in number of 1.538 + * characters, without affecting the length of the string. 1.539 + * There is no need to include room for the null terminator: it is 1.540 + * the job of the string class. 1.541 + * Also ensures that the buffer is mutable. 1.542 + */ 1.543 + void NS_FASTCALL SetCapacity( size_type newCapacity ); 1.544 + bool NS_FASTCALL SetCapacity( size_type newCapacity, const fallible_t& ) NS_WARN_UNUSED_RESULT; 1.545 + 1.546 + void NS_FASTCALL SetLength( size_type newLength ); 1.547 + bool NS_FASTCALL SetLength( size_type newLength, const fallible_t& ) NS_WARN_UNUSED_RESULT; 1.548 + 1.549 + void Truncate( size_type newLength = 0 ) 1.550 + { 1.551 + NS_ASSERTION(newLength <= mLength, "Truncate cannot make string longer"); 1.552 + SetLength(newLength); 1.553 + } 1.554 + 1.555 + 1.556 + /** 1.557 + * buffer access 1.558 + */ 1.559 + 1.560 + 1.561 + /** 1.562 + * Get a const pointer to the string's internal buffer. The caller 1.563 + * MUST NOT modify the characters at the returned address. 1.564 + * 1.565 + * @returns The length of the buffer in characters. 1.566 + */ 1.567 + inline size_type GetData( const char_type** data ) const 1.568 + { 1.569 + *data = mData; 1.570 + return mLength; 1.571 + } 1.572 + 1.573 + /** 1.574 + * Get a pointer to the string's internal buffer, optionally resizing 1.575 + * the buffer first. If size_type(-1) is passed for newLen, then the 1.576 + * current length of the string is used. The caller MAY modify the 1.577 + * characters at the returned address (up to but not exceeding the 1.578 + * length of the string). 1.579 + * 1.580 + * @returns The length of the buffer in characters or 0 if unable to 1.581 + * satisfy the request due to low-memory conditions. 1.582 + */ 1.583 + size_type GetMutableData( char_type** data, size_type newLen = size_type(-1) ) 1.584 + { 1.585 + if (!EnsureMutable(newLen)) 1.586 + NS_ABORT_OOM(newLen == size_type(-1) ? mLength : newLen); 1.587 + 1.588 + *data = mData; 1.589 + return mLength; 1.590 + } 1.591 + 1.592 + size_type GetMutableData( char_type** data, size_type newLen, const fallible_t& ) 1.593 + { 1.594 + if (!EnsureMutable(newLen)) 1.595 + { 1.596 + *data = nullptr; 1.597 + return 0; 1.598 + } 1.599 + 1.600 + *data = mData; 1.601 + return mLength; 1.602 + } 1.603 + 1.604 +#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER) 1.605 + size_type GetMutableData( wchar_t** data, size_type newLen = size_type(-1) ) 1.606 + { 1.607 + return GetMutableData(reinterpret_cast<char16_t**>(data), newLen); 1.608 + } 1.609 + 1.610 + size_type GetMutableData( wchar_t** data, size_type newLen, const fallible_t& ) 1.611 + { 1.612 + return GetMutableData(reinterpret_cast<char16_t**>(data), newLen, fallible_t()); 1.613 + } 1.614 +#endif 1.615 + 1.616 + 1.617 + /** 1.618 + * string data is never null, but can be marked void. if true, the 1.619 + * string will be truncated. @see nsTSubstring::IsVoid 1.620 + */ 1.621 + 1.622 + void NS_FASTCALL SetIsVoid( bool ); 1.623 + 1.624 + /** 1.625 + * This method is used to remove all occurrences of aChar from this 1.626 + * string. 1.627 + * 1.628 + * @param aChar -- char to be stripped 1.629 + * @param aOffset -- where in this string to start stripping chars 1.630 + */ 1.631 + 1.632 + void StripChar( char_type aChar, int32_t aOffset=0 ); 1.633 + 1.634 + /** 1.635 + * This method is used to remove all occurrences of aChars from this 1.636 + * string. 1.637 + * 1.638 + * @param aChars -- chars to be stripped 1.639 + * @param aOffset -- where in this string to start stripping chars 1.640 + */ 1.641 + 1.642 + void StripChars( const char_type* aChars, uint32_t aOffset=0 ); 1.643 + 1.644 + /** 1.645 + * If the string uses a shared buffer, this method 1.646 + * clears the pointer without releasing the buffer. 1.647 + */ 1.648 + void ForgetSharedBuffer() 1.649 + { 1.650 + if (mFlags & nsSubstring::F_SHARED) 1.651 + { 1.652 + mData = char_traits::sEmptyBuffer; 1.653 + mLength = 0; 1.654 + mFlags = F_TERMINATED; 1.655 + } 1.656 + } 1.657 + 1.658 + public: 1.659 + 1.660 + /** 1.661 + * this is public to support automatic conversion of tuple to string 1.662 + * base type, which helps avoid converting to nsTAString. 1.663 + */ 1.664 + nsTSubstring_CharT(const substring_tuple_type& tuple) 1.665 + : mData(nullptr), 1.666 + mLength(0), 1.667 + mFlags(F_NONE) 1.668 + { 1.669 + Assign(tuple); 1.670 + } 1.671 + 1.672 + /** 1.673 + * allows for direct initialization of a nsTSubstring object. 1.674 + * 1.675 + * NOTE: this constructor is declared public _only_ for convenience 1.676 + * inside the string implementation. 1.677 + */ 1.678 + // XXXbz or can I just include nscore.h and use NS_BUILD_REFCNT_LOGGING? 1.679 +#if defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING) 1.680 +#define XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE 1.681 + nsTSubstring_CharT( char_type *data, size_type length, uint32_t flags ); 1.682 +#else 1.683 +#undef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE 1.684 + nsTSubstring_CharT( char_type *data, size_type length, uint32_t flags ) 1.685 + : mData(data), 1.686 + mLength(length), 1.687 + mFlags(flags) {} 1.688 +#endif /* DEBUG || FORCE_BUILD_REFCNT_LOGGING */ 1.689 + 1.690 + size_t SizeOfExcludingThisMustBeUnshared(mozilla::MallocSizeOf mallocSizeOf) 1.691 + const; 1.692 + size_t SizeOfIncludingThisMustBeUnshared(mozilla::MallocSizeOf mallocSizeOf) 1.693 + const; 1.694 + 1.695 + size_t SizeOfExcludingThisIfUnshared(mozilla::MallocSizeOf mallocSizeOf) 1.696 + const; 1.697 + size_t SizeOfIncludingThisIfUnshared(mozilla::MallocSizeOf mallocSizeOf) 1.698 + const; 1.699 + 1.700 + /** 1.701 + * WARNING: Only use these functions if you really know what you are 1.702 + * doing, because they can easily lead to double-counting strings. If 1.703 + * you do use them, please explain clearly in a comment why it's safe 1.704 + * and won't lead to double-counting. 1.705 + */ 1.706 + size_t SizeOfExcludingThisEvenIfShared(mozilla::MallocSizeOf mallocSizeOf) 1.707 + const; 1.708 + size_t SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf mallocSizeOf) 1.709 + const; 1.710 + 1.711 + protected: 1.712 + 1.713 + friend class nsTObsoleteAStringThunk_CharT; 1.714 + friend class nsTSubstringTuple_CharT; 1.715 + 1.716 + // XXX GCC 3.4 needs this :-( 1.717 + friend class nsTPromiseFlatString_CharT; 1.718 + 1.719 + char_type* mData; 1.720 + size_type mLength; 1.721 + uint32_t mFlags; 1.722 + 1.723 + // default initialization 1.724 + nsTSubstring_CharT() 1.725 + : mData(char_traits::sEmptyBuffer), 1.726 + mLength(0), 1.727 + mFlags(F_TERMINATED) {} 1.728 + 1.729 + // version of constructor that leaves mData and mLength uninitialized 1.730 + explicit 1.731 + nsTSubstring_CharT( uint32_t flags ) 1.732 + : mFlags(flags) {} 1.733 + 1.734 + // copy-constructor, constructs as dependent on given object 1.735 + // (NOTE: this is for internal use only) 1.736 + nsTSubstring_CharT( const self_type& str ) 1.737 + : mData(str.mData), 1.738 + mLength(str.mLength), 1.739 + mFlags(str.mFlags & (F_TERMINATED | F_VOIDED)) {} 1.740 + 1.741 + /** 1.742 + * this function releases mData and does not change the value of 1.743 + * any of its member variables. in other words, this function acts 1.744 + * like a destructor. 1.745 + */ 1.746 + void NS_FASTCALL Finalize(); 1.747 + 1.748 + /** 1.749 + * this function prepares mData to be mutated. 1.750 + * 1.751 + * @param capacity specifies the required capacity of mData 1.752 + * @param old_data returns null or the old value of mData 1.753 + * @param old_flags returns 0 or the old value of mFlags 1.754 + * 1.755 + * if mData is already mutable and of sufficient capacity, then this 1.756 + * function will return immediately. otherwise, it will either resize 1.757 + * mData or allocate a new shared buffer. if it needs to allocate a 1.758 + * new buffer, then it will return the old buffer and the corresponding 1.759 + * flags. this allows the caller to decide when to free the old data. 1.760 + * 1.761 + * this function returns false if is unable to allocate sufficient 1.762 + * memory. 1.763 + * 1.764 + * XXX we should expose a way for subclasses to free old_data. 1.765 + */ 1.766 + bool NS_FASTCALL MutatePrep( size_type capacity, char_type** old_data, uint32_t* old_flags ); 1.767 + 1.768 + /** 1.769 + * this function prepares a section of mData to be modified. if 1.770 + * necessary, this function will reallocate mData and possibly move 1.771 + * existing data to open up the specified section. 1.772 + * 1.773 + * @param cutStart specifies the starting offset of the section 1.774 + * @param cutLength specifies the length of the section to be replaced 1.775 + * @param newLength specifies the length of the new section 1.776 + * 1.777 + * for example, suppose mData contains the string "abcdef" then 1.778 + * 1.779 + * ReplacePrep(2, 3, 4); 1.780 + * 1.781 + * would cause mData to look like "ab____f" where the characters 1.782 + * indicated by '_' have an unspecified value and can be freely 1.783 + * modified. this function will null-terminate mData upon return. 1.784 + * 1.785 + * this function returns false if is unable to allocate sufficient 1.786 + * memory. 1.787 + */ 1.788 + bool ReplacePrep(index_type cutStart, size_type cutLength, 1.789 + size_type newLength) NS_WARN_UNUSED_RESULT 1.790 + { 1.791 + cutLength = XPCOM_MIN(cutLength, mLength - cutStart); 1.792 + uint32_t newTotalLen = mLength - cutLength + newLength; 1.793 + if (cutStart == mLength && Capacity() > newTotalLen) { 1.794 + mFlags &= ~F_VOIDED; 1.795 + mData[newTotalLen] = char_type(0); 1.796 + mLength = newTotalLen; 1.797 + return true; 1.798 + } 1.799 + return ReplacePrepInternal(cutStart, cutLength, newLength, newTotalLen); 1.800 + } 1.801 + 1.802 + bool NS_FASTCALL ReplacePrepInternal(index_type cutStart, 1.803 + size_type cutLength, 1.804 + size_type newFragLength, 1.805 + size_type newTotalLength) 1.806 + NS_WARN_UNUSED_RESULT; 1.807 + 1.808 + /** 1.809 + * returns the number of writable storage units starting at mData. 1.810 + * the value does not include space for the null-terminator character. 1.811 + * 1.812 + * NOTE: this function returns 0 if mData is immutable (or the buffer 1.813 + * is 0-sized). 1.814 + */ 1.815 + size_type NS_FASTCALL Capacity() const; 1.816 + 1.817 + /** 1.818 + * this helper function can be called prior to directly manipulating 1.819 + * the contents of mData. see, for example, BeginWriting. 1.820 + */ 1.821 + bool NS_FASTCALL EnsureMutable( size_type newLen = size_type(-1) ) NS_WARN_UNUSED_RESULT; 1.822 + 1.823 + /** 1.824 + * returns true if this string overlaps with the given string fragment. 1.825 + */ 1.826 + bool IsDependentOn( const char_type *start, const char_type *end ) const 1.827 + { 1.828 + /** 1.829 + * if it _isn't_ the case that one fragment starts after the other ends, 1.830 + * or ends before the other starts, then, they conflict: 1.831 + * 1.832 + * !(f2.begin >= f1.end || f2.end <= f1.begin) 1.833 + * 1.834 + * Simplified, that gives us: 1.835 + */ 1.836 + return ( start < (mData + mLength) && end > mData ); 1.837 + } 1.838 + 1.839 + /** 1.840 + * this helper function stores the specified dataFlags in mFlags 1.841 + */ 1.842 + void SetDataFlags(uint32_t dataFlags) 1.843 + { 1.844 + NS_ASSERTION((dataFlags & 0xFFFF0000) == 0, "bad flags"); 1.845 + mFlags = dataFlags | (mFlags & 0xFFFF0000); 1.846 + } 1.847 + 1.848 + void NS_FASTCALL ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type* data, size_type length ); 1.849 + 1.850 + static int AppendFunc( void* arg, const char* s, uint32_t len); 1.851 + 1.852 + public: 1.853 + 1.854 + // NOTE: this method is declared public _only_ for convenience for 1.855 + // callers who don't have access to the original nsLiteralString_CharT. 1.856 + void NS_FASTCALL AssignLiteral( const char_type* data, size_type length ); 1.857 + 1.858 + // mFlags is a bitwise combination of the following flags. the meaning 1.859 + // and interpretation of these flags is an implementation detail. 1.860 + // 1.861 + // NOTE: these flags are declared public _only_ for convenience inside 1.862 + // the string implementation. 1.863 + 1.864 + enum 1.865 + { 1.866 + F_NONE = 0, // no flags 1.867 + 1.868 + // data flags are in the lower 16-bits 1.869 + F_TERMINATED = 1 << 0, // IsTerminated returns true 1.870 + F_VOIDED = 1 << 1, // IsVoid returns true 1.871 + F_SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer 1.872 + F_OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer 1.873 + F_FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer 1.874 + F_LITERAL = 1 << 5, // mData points to a string literal; F_TERMINATED will also be set 1.875 + 1.876 + // class flags are in the upper 16-bits 1.877 + F_CLASS_FIXED = 1 << 16 // indicates that |this| is of type nsTFixedString 1.878 + }; 1.879 + 1.880 + // 1.881 + // Some terminology: 1.882 + // 1.883 + // "dependent buffer" A dependent buffer is one that the string class 1.884 + // does not own. The string class relies on some 1.885 + // external code to ensure the lifetime of the 1.886 + // dependent buffer. 1.887 + // 1.888 + // "shared buffer" A shared buffer is one that the string class 1.889 + // allocates. When it allocates a shared string 1.890 + // buffer, it allocates some additional space at 1.891 + // the beginning of the buffer for additional 1.892 + // fields, including a reference count and a 1.893 + // buffer length. See nsStringHeader. 1.894 + // 1.895 + // "adopted buffer" An adopted buffer is a raw string buffer 1.896 + // allocated on the heap (using nsMemory::Alloc) 1.897 + // of which the string class subsumes ownership. 1.898 + // 1.899 + // Some comments about the string flags: 1.900 + // 1.901 + // F_SHARED, F_OWNED, and F_FIXED are all mutually exlusive. They 1.902 + // indicate the allocation type of mData. If none of these flags 1.903 + // are set, then the string buffer is dependent. 1.904 + // 1.905 + // F_SHARED, F_OWNED, or F_FIXED imply F_TERMINATED. This is because 1.906 + // the string classes always allocate null-terminated buffers, and 1.907 + // non-terminated substrings are always dependent. 1.908 + // 1.909 + // F_VOIDED implies F_TERMINATED, and moreover it implies that mData 1.910 + // points to char_traits::sEmptyBuffer. Therefore, F_VOIDED is 1.911 + // mutually exclusive with F_SHARED, F_OWNED, and F_FIXED. 1.912 + // 1.913 + }; 1.914 + 1.915 +int NS_FASTCALL Compare( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs, const nsTStringComparator_CharT& = nsTDefaultStringComparator_CharT() ); 1.916 + 1.917 + 1.918 +inline 1.919 +bool operator!=( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs ) 1.920 + { 1.921 + return !lhs.Equals(rhs); 1.922 + } 1.923 + 1.924 +inline 1.925 +bool operator< ( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs ) 1.926 + { 1.927 + return Compare(lhs, rhs)< 0; 1.928 + } 1.929 + 1.930 +inline 1.931 +bool operator<=( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs ) 1.932 + { 1.933 + return Compare(lhs, rhs)<=0; 1.934 + } 1.935 + 1.936 +inline 1.937 +bool operator==( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs ) 1.938 + { 1.939 + return lhs.Equals(rhs); 1.940 + } 1.941 + 1.942 +inline 1.943 +bool operator==( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::char_type* rhs ) 1.944 + { 1.945 + return lhs.Equals(rhs); 1.946 + } 1.947 + 1.948 + 1.949 +inline 1.950 +bool operator>=( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs ) 1.951 + { 1.952 + return Compare(lhs, rhs)>=0; 1.953 + } 1.954 + 1.955 +inline 1.956 +bool operator> ( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs ) 1.957 + { 1.958 + return Compare(lhs, rhs)> 0; 1.959 + }