LCOV - code coverage report
Current view: top level - xpcom/string - nsTSubstring.h (source / functions) Hit Total Coverage
Test: output.info Lines: 235 295 79.7 %
Date: 2017-07-14 16:53:18 Functions: 255 535 47.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : // IWYU pragma: private, include "nsString.h"
       7             : 
       8             : #include "mozilla/Casting.h"
       9             : #include "mozilla/IntegerPrintfMacros.h"
      10             : #include "mozilla/UniquePtr.h"
      11             : #include "mozilla/MemoryReporting.h"
      12             : #include "mozilla/IntegerTypeTraits.h"
      13             : #include "mozilla/Span.h"
      14             : 
      15             : #ifndef MOZILLA_INTERNAL_API
      16             : #error "Using XPCOM strings is limited to code linked into libxul."
      17             : #endif
      18             : 
      19             : /**
      20             :  * The base for string comparators
      21             :  */
      22             : class nsTStringComparator_CharT
      23             : {
      24             : public:
      25             :   typedef CharT char_type;
      26             : 
      27        3121 :   nsTStringComparator_CharT()
      28        3121 :   {
      29        3121 :   }
      30             : 
      31             :   virtual int operator()(const char_type*, const char_type*,
      32             :                          uint32_t, uint32_t) const = 0;
      33             : };
      34             : 
      35             : 
      36             : /**
      37             :  * The default string comparator (case-sensitive comparision)
      38             :  */
      39             : class nsTDefaultStringComparator_CharT
      40             :   : public nsTStringComparator_CharT
      41             : {
      42             : public:
      43             :   typedef CharT char_type;
      44             : 
      45        2274 :   nsTDefaultStringComparator_CharT()
      46        2274 :   {
      47        2274 :   }
      48             : 
      49             :   virtual int operator()(const char_type*, const char_type*,
      50             :                          uint32_t, uint32_t) const override;
      51             : };
      52             : 
      53             : class nsTSubstringSplitter_CharT;
      54             : 
      55             : namespace mozilla {
      56             : namespace detail {
      57             : 
      58             : /**
      59             :  * nsTStringRepr defines a string's memory layout and some accessor methods.
      60             :  * This class exists so that nsTLiteralString can avoid inheriting
      61             :  * nsTSubstring's destructor. All methods on this class must be const because
      62             :  * literal strings are not writable.
      63             :  *
      64             :  * This class is an implementation detail and should not be instantiated
      65             :  * directly, nor used in any way outside of the string code itself. It is
      66             :  * buried in a namespace to discourage its use in function parameters.
      67             :  * If you need to take a parameter, use [const] ns[C]Substring&.
      68             :  * If you need to instantiate a string, use ns[C]String or descendents.
      69             :  *
      70             :  * NAMES:
      71             :  *   nsStringRepr for wide characters
      72             :  *   nsCStringRepr for narrow characters
      73             :  *
      74             :  */
      75             : class nsTStringRepr_CharT
      76             : {
      77             : public:
      78             :   typedef mozilla::fallible_t                 fallible_t;
      79             : 
      80             :   typedef CharT                               char_type;
      81             : 
      82             :   typedef nsCharTraits<char_type>             char_traits;
      83             :   typedef char_traits::incompatible_char_type incompatible_char_type;
      84             : 
      85             :   typedef nsTStringRepr_CharT                 self_type;
      86             :   typedef self_type                           base_string_type;
      87             : 
      88             :   typedef nsTSubstring_CharT                  substring_type;
      89             :   typedef nsTSubstringTuple_CharT             substring_tuple_type;
      90             :   typedef nsTString_CharT                     string_type;
      91             : 
      92             :   typedef nsReadingIterator<char_type>        const_iterator;
      93             :   typedef nsWritingIterator<char_type>        iterator;
      94             : 
      95             :   typedef nsTStringComparator_CharT           comparator_type;
      96             : 
      97             :   typedef char_type*                          char_iterator;
      98             :   typedef const char_type*                    const_char_iterator;
      99             : 
     100             :   typedef uint32_t                            index_type;
     101             :   typedef uint32_t                            size_type;
     102             : 
     103             :   // These are only for internal use within the string classes:
     104             :   typedef StringDataFlags                     DataFlags;
     105             :   typedef StringClassFlags                    ClassFlags;
     106             : 
     107             :   /**
     108             :    * reading iterators
     109             :    */
     110             : 
     111      178221 :   const_char_iterator BeginReading() const
     112             :   {
     113      178221 :     return mData;
     114             :   }
     115       18171 :   const_char_iterator EndReading() const
     116             :   {
     117       18171 :     return mData + mLength;
     118             :   }
     119             : 
     120             :   /**
     121             :    * deprecated reading iterators
     122             :    */
     123             : 
     124       78152 :   const_iterator& BeginReading(const_iterator& aIter) const
     125             :   {
     126       78152 :     aIter.mStart = mData;
     127       78152 :     aIter.mEnd = mData + mLength;
     128       78152 :     aIter.mPosition = aIter.mStart;
     129       78152 :     return aIter;
     130             :   }
     131             : 
     132       61725 :   const_iterator& EndReading(const_iterator& aIter) const
     133             :   {
     134       61725 :     aIter.mStart = mData;
     135       61725 :     aIter.mEnd = mData + mLength;
     136       61725 :     aIter.mPosition = aIter.mEnd;
     137       61725 :     return aIter;
     138             :   }
     139             : 
     140        8312 :   const_char_iterator& BeginReading(const_char_iterator& aIter) const
     141             :   {
     142        8312 :     return aIter = mData;
     143             :   }
     144             : 
     145        8312 :   const_char_iterator& EndReading(const_char_iterator& aIter) const
     146             :   {
     147        8312 :     return aIter = mData + mLength;
     148             :   }
     149             : 
     150             :   /**
     151             :    * accessors
     152             :    */
     153             : 
     154             :   // returns pointer to string data (not necessarily null-terminated)
     155             : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
     156             :   char16ptr_t Data() const
     157             : #else
     158      235215 :   const char_type* Data() const
     159             : #endif
     160             :   {
     161      235215 :     return mData;
     162             :   }
     163             : 
     164      844116 :   size_type Length() const
     165             :   {
     166      844116 :     return mLength;
     167             :   }
     168             : 
     169       30267 :   DataFlags GetDataFlags() const
     170             :   {
     171       30267 :     return mDataFlags;
     172             :   }
     173             : 
     174      117928 :   bool IsEmpty() const
     175             :   {
     176      117928 :     return mLength == 0;
     177             :   }
     178             : 
     179         380 :   bool IsLiteral() const
     180             :   {
     181         380 :     return !!(mDataFlags & DataFlags::LITERAL);
     182             :   }
     183             : 
     184       62398 :   bool IsVoid() const
     185             :   {
     186       62398 :     return !!(mDataFlags & DataFlags::VOIDED);
     187             :   }
     188             : 
     189       27921 :   bool IsTerminated() const
     190             :   {
     191       27921 :     return !!(mDataFlags & DataFlags::TERMINATED);
     192             :   }
     193             : 
     194         775 :   char_type CharAt(index_type aIndex) const
     195             :   {
     196         775 :     NS_ASSERTION(aIndex < mLength, "index exceeds allowable range");
     197         775 :     return mData[aIndex];
     198             :   }
     199             : 
     200         741 :   char_type operator[](index_type aIndex) const
     201             :   {
     202         741 :     return CharAt(aIndex);
     203             :   }
     204             : 
     205             :   char_type First() const;
     206             : 
     207             :   char_type Last() const;
     208             : 
     209             :   size_type NS_FASTCALL CountChar(char_type) const;
     210             :   int32_t NS_FASTCALL FindChar(char_type, index_type aOffset = 0) const;
     211             : 
     212        3197 :   inline bool Contains(char_type aChar) const
     213             :   {
     214        3197 :     return FindChar(aChar) != kNotFound;
     215             :   }
     216             : 
     217             :   /**
     218             :    * equality
     219             :    */
     220             : 
     221             :   bool NS_FASTCALL Equals(const self_type&) const;
     222             :   bool NS_FASTCALL Equals(const self_type&, const comparator_type&) const;
     223             : 
     224             :   bool NS_FASTCALL Equals(const substring_tuple_type& aTuple) const;
     225             :   bool NS_FASTCALL Equals(const substring_tuple_type& aTuple,
     226             :                           const comparator_type& aComp) const;
     227             : 
     228             :   bool NS_FASTCALL Equals(const char_type* aData) const;
     229             :   bool NS_FASTCALL Equals(const char_type* aData,
     230             :                           const comparator_type& aComp) const;
     231             : 
     232             : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
     233             :   bool NS_FASTCALL Equals(char16ptr_t aData) const
     234             :   {
     235             :     return Equals(static_cast<const char16_t*>(aData));
     236             :   }
     237             :   bool NS_FASTCALL Equals(char16ptr_t aData, const comparator_type& aComp) const
     238             :   {
     239             :     return Equals(static_cast<const char16_t*>(aData), aComp);
     240             :   }
     241             : #endif
     242             : 
     243             :   /**
     244             :    * An efficient comparison with ASCII that can be used even
     245             :    * for wide strings. Call this version when you know the
     246             :    * length of 'data'.
     247             :    */
     248             :   bool NS_FASTCALL EqualsASCII(const char* aData, size_type aLen) const;
     249             :   /**
     250             :    * An efficient comparison with ASCII that can be used even
     251             :    * for wide strings. Call this version when 'data' is
     252             :    * null-terminated.
     253             :    */
     254             :   bool NS_FASTCALL EqualsASCII(const char* aData) const;
     255             : 
     256             :   // EqualsLiteral must ONLY be applied to an actual literal string, or
     257             :   // a char array *constant* declared without an explicit size.
     258             :   // Do not attempt to use it with a regular char* pointer, or with a
     259             :   // non-constant char array variable. Use EqualsASCII for them.
     260             :   // The template trick to acquire the array length at compile time without
     261             :   // using a macro is due to Corey Kosak, with much thanks.
     262             :   template<int N>
     263       27024 :   inline bool EqualsLiteral(const char (&aStr)[N]) const
     264             :   {
     265       27024 :     return EqualsASCII(aStr, N - 1);
     266             :   }
     267             : 
     268             :   // The LowerCaseEquals methods compare the ASCII-lowercase version of
     269             :   // this string (lowercasing only ASCII uppercase characters) to some
     270             :   // ASCII/Literal string. The ASCII string is *not* lowercased for
     271             :   // you. If you compare to an ASCII or literal string that contains an
     272             :   // uppercase character, it is guaranteed to return false. We will
     273             :   // throw assertions too.
     274             :   bool NS_FASTCALL LowerCaseEqualsASCII(const char* aData,
     275             :                                         size_type aLen) const;
     276             :   bool NS_FASTCALL LowerCaseEqualsASCII(const char* aData) const;
     277             : 
     278             :   // LowerCaseEqualsLiteral must ONLY be applied to an actual
     279             :   // literal string, or a char array *constant* declared without an
     280             :   // explicit size.  Do not attempt to use it with a regular char*
     281             :   // pointer, or with a non-constant char array variable. Use
     282             :   // LowerCaseEqualsASCII for them.
     283             :   template<int N>
     284       49560 :   inline bool LowerCaseEqualsLiteral(const char (&aStr)[N]) const
     285             :   {
     286       49560 :     return LowerCaseEqualsASCII(aStr, N - 1);
     287             :   }
     288             : 
     289             :   /**
     290             :    * returns true if this string overlaps with the given string fragment.
     291             :    */
     292      218356 :   bool IsDependentOn(const char_type* aStart, const char_type* aEnd) const
     293             :   {
     294             :     /**
     295             :      * if it _isn't_ the case that one fragment starts after the other ends,
     296             :      * or ends before the other starts, then, they conflict:
     297             :      *
     298             :      *   !(f2.begin >= f1.aEnd || f2.aEnd <= f1.begin)
     299             :      *
     300             :      * Simplified, that gives us:
     301             :      */
     302      218356 :     return (aStart < (mData + mLength) && aEnd > mData);
     303             :   }
     304             : 
     305             : protected:
     306             :   nsTStringRepr_CharT() = delete; // Never instantiate directly
     307             : 
     308             :   constexpr
     309      796998 :   nsTStringRepr_CharT(char_type* aData, size_type aLength,
     310             :                       DataFlags aDataFlags, ClassFlags aClassFlags)
     311      796998 :     : mData(aData)
     312             :     , mLength(aLength)
     313             :     , mDataFlags(aDataFlags)
     314      796998 :     , mClassFlags(aClassFlags)
     315             :   {
     316      796998 :   }
     317             : 
     318             :   char_type* mData;
     319             :   size_type mLength;
     320             :   DataFlags mDataFlags;
     321             :   ClassFlags const mClassFlags;
     322             : };
     323             : 
     324             : } // namespace detail
     325             : } // namespace mozilla
     326             : 
     327             : /**
     328             :  * nsTSubstring is an abstract string class. From an API perspective, this
     329             :  * class is the root of the string class hierarchy. It represents a single
     330             :  * contiguous array of characters, which may or may not be null-terminated.
     331             :  * This type is not instantiated directly. A sub-class is instantiated
     332             :  * instead. For example, see nsTString.
     333             :  *
     334             :  * NAMES:
     335             :  *   nsAString for wide characters
     336             :  *   nsACString for narrow characters
     337             :  *
     338             :  */
     339             : class nsTSubstring_CharT : public mozilla::detail::nsTStringRepr_CharT
     340             : {
     341             : public:
     342             :   typedef nsTSubstring_CharT                  self_type;
     343             : 
     344             :   // this acts like a virtual destructor
     345      711303 :   ~nsTSubstring_CharT()
     346      711303 :   {
     347      711303 :     Finalize();
     348      711303 :   }
     349             : 
     350             :   /**
     351             :    * writing iterators
     352             :    */
     353             : 
     354       98027 :   char_iterator BeginWriting()
     355             :   {
     356       98027 :     if (!EnsureMutable()) {
     357           0 :       AllocFailed(mLength);
     358             :     }
     359             : 
     360       98027 :     return mData;
     361             :   }
     362             : 
     363           0 :   char_iterator BeginWriting(const fallible_t&)
     364             :   {
     365           0 :     return EnsureMutable() ? mData : char_iterator(0);
     366             :   }
     367             : 
     368        3998 :   char_iterator EndWriting()
     369             :   {
     370        3998 :     if (!EnsureMutable()) {
     371           0 :       AllocFailed(mLength);
     372             :     }
     373             : 
     374        3998 :     return mData + mLength;
     375             :   }
     376             : 
     377             :   char_iterator EndWriting(const fallible_t&)
     378             :   {
     379             :     return EnsureMutable() ? (mData + mLength) : char_iterator(0);
     380             :   }
     381             : 
     382       24347 :   char_iterator& BeginWriting(char_iterator& aIter)
     383             :   {
     384       24347 :     return aIter = BeginWriting();
     385             :   }
     386             : 
     387           0 :   char_iterator& BeginWriting(char_iterator& aIter, const fallible_t& aFallible)
     388             :   {
     389           0 :     return aIter = BeginWriting(aFallible);
     390             :   }
     391             : 
     392             :   char_iterator& EndWriting(char_iterator& aIter)
     393             :   {
     394             :     return aIter = EndWriting();
     395             :   }
     396             : 
     397             :   char_iterator& EndWriting(char_iterator& aIter, const fallible_t& aFallible)
     398             :   {
     399             :     return aIter = EndWriting(aFallible);
     400             :   }
     401             : 
     402             :   /**
     403             :    * deprecated writing iterators
     404             :    */
     405             : 
     406       23843 :   iterator& BeginWriting(iterator& aIter)
     407             :   {
     408       23843 :     char_type* data = BeginWriting();
     409       23843 :     aIter.mStart = data;
     410       23843 :     aIter.mEnd = data + mLength;
     411       23843 :     aIter.mPosition = aIter.mStart;
     412       23843 :     return aIter;
     413             :   }
     414             : 
     415        3654 :   iterator& EndWriting(iterator& aIter)
     416             :   {
     417        3654 :     char_type* data = BeginWriting();
     418        3654 :     aIter.mStart = data;
     419        3654 :     aIter.mEnd = data + mLength;
     420        3654 :     aIter.mPosition = aIter.mEnd;
     421        3654 :     return aIter;
     422             :   }
     423             : 
     424             :   /**
     425             :    * assignment
     426             :    */
     427             : 
     428             :   void NS_FASTCALL Assign(char_type aChar);
     429             :   MOZ_MUST_USE bool NS_FASTCALL Assign(char_type aChar, const fallible_t&);
     430             : 
     431             :   void NS_FASTCALL Assign(const char_type* aData);
     432             :   MOZ_MUST_USE bool NS_FASTCALL Assign(const char_type* aData,
     433             :                                        const fallible_t&);
     434             : 
     435             :   void NS_FASTCALL Assign(const char_type* aData, size_type aLength);
     436             :   MOZ_MUST_USE bool NS_FASTCALL Assign(const char_type* aData,
     437             :                                        size_type aLength, const fallible_t&);
     438             : 
     439             :   void NS_FASTCALL Assign(const self_type&);
     440             :   MOZ_MUST_USE bool NS_FASTCALL Assign(const self_type&, const fallible_t&);
     441             : 
     442             :   void NS_FASTCALL Assign(const substring_tuple_type&);
     443             :   MOZ_MUST_USE bool NS_FASTCALL Assign(const substring_tuple_type&,
     444             :                                        const fallible_t&);
     445             : 
     446             : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
     447             :   void Assign(char16ptr_t aData)
     448             :   {
     449             :     Assign(static_cast<const char16_t*>(aData));
     450             :   }
     451             : 
     452             :   void Assign(char16ptr_t aData, size_type aLength)
     453             :   {
     454             :     Assign(static_cast<const char16_t*>(aData), aLength);
     455             :   }
     456             : 
     457             :   MOZ_MUST_USE bool Assign(char16ptr_t aData, size_type aLength,
     458             :                            const fallible_t& aFallible)
     459             :   {
     460             :     return Assign(static_cast<const char16_t*>(aData), aLength,
     461             :                   aFallible);
     462             :   }
     463             : #endif
     464             : 
     465             :   void NS_FASTCALL AssignASCII(const char* aData, size_type aLength);
     466             :   MOZ_MUST_USE bool NS_FASTCALL AssignASCII(const char* aData,
     467             :                                             size_type aLength,
     468             :                                             const fallible_t&);
     469             : 
     470        1228 :   void NS_FASTCALL AssignASCII(const char* aData)
     471             :   {
     472        1228 :     AssignASCII(aData, mozilla::AssertedCast<size_type, size_t>(strlen(aData)));
     473        1228 :   }
     474             :   MOZ_MUST_USE bool NS_FASTCALL AssignASCII(const char* aData,
     475             :                                             const fallible_t& aFallible)
     476             :   {
     477             :     return AssignASCII(aData,
     478             :                        mozilla::AssertedCast<size_type, size_t>(strlen(aData)),
     479             :                        aFallible);
     480             :   }
     481             : 
     482             :   // AssignLiteral must ONLY be applied to an actual literal string, or
     483             :   // a char array *constant* declared without an explicit size.
     484             :   // Do not attempt to use it with a regular char* pointer, or with a
     485             :   // non-constant char array variable. Use AssignASCII for those.
     486             :   // There are not fallible version of these methods because they only really
     487             :   // apply to small allocations that we wouldn't want to check anyway.
     488             :   template<int N>
     489        3932 :   void AssignLiteral(const char_type (&aStr)[N])
     490             :   {
     491        3932 :     AssignLiteral(aStr, N - 1);
     492        3932 :   }
     493             : #ifdef CharT_is_PRUnichar
     494             :   template<int N>
     495         812 :   void AssignLiteral(const char (&aStr)[N])
     496             :   {
     497         812 :     AssignASCII(aStr, N - 1);
     498         812 :   }
     499             : #endif
     500             : 
     501           0 :   self_type& operator=(char_type aChar)
     502             :   {
     503           0 :     Assign(aChar);
     504           0 :     return *this;
     505             :   }
     506         281 :   self_type& operator=(const char_type* aData)
     507             :   {
     508         281 :     Assign(aData);
     509         281 :     return *this;
     510             :   }
     511             : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
     512             :   self_type& operator=(char16ptr_t aData)
     513             :   {
     514             :     Assign(aData);
     515             :     return *this;
     516             :   }
     517             : #endif
     518       42129 :   self_type& operator=(const self_type& aStr)
     519             :   {
     520       42129 :     Assign(aStr);
     521       42130 :     return *this;
     522             :   }
     523         173 :   self_type& operator=(const substring_tuple_type& aTuple)
     524             :   {
     525         173 :     Assign(aTuple);
     526         173 :     return *this;
     527             :   }
     528             : 
     529             :   void NS_FASTCALL Adopt(char_type* aData, size_type aLength = size_type(-1));
     530             : 
     531             : 
     532             :   /**
     533             :    * buffer manipulation
     534             :    */
     535             : 
     536             :   void NS_FASTCALL Replace(index_type aCutStart, size_type aCutLength,
     537             :                            char_type aChar);
     538             :   MOZ_MUST_USE bool NS_FASTCALL Replace(index_type aCutStart,
     539             :                                         size_type aCutLength,
     540             :                                         char_type aChar,
     541             :                                         const fallible_t&);
     542             :   void NS_FASTCALL Replace(index_type aCutStart, size_type aCutLength,
     543             :                            const char_type* aData,
     544             :                            size_type aLength = size_type(-1));
     545             :   MOZ_MUST_USE bool NS_FASTCALL Replace(index_type aCutStart,
     546             :                                         size_type aCutLength,
     547             :                                         const char_type* aData,
     548             :                                         size_type aLength,
     549             :                                         const fallible_t&);
     550       15485 :   void Replace(index_type aCutStart, size_type aCutLength,
     551             :                const self_type& aStr)
     552             :   {
     553       15485 :     Replace(aCutStart, aCutLength, aStr.Data(), aStr.Length());
     554       15485 :   }
     555         315 :   MOZ_MUST_USE bool Replace(index_type aCutStart,
     556             :                             size_type aCutLength,
     557             :                             const self_type& aStr,
     558             :                             const fallible_t& aFallible)
     559             :   {
     560         315 :     return Replace(aCutStart, aCutLength, aStr.Data(), aStr.Length(),
     561         315 :                    aFallible);
     562             :   }
     563             :   void NS_FASTCALL Replace(index_type aCutStart, size_type aCutLength,
     564             :                            const substring_tuple_type& aTuple);
     565             : 
     566             :   void NS_FASTCALL ReplaceASCII(index_type aCutStart, size_type aCutLength,
     567             :                                 const char* aData,
     568             :                                 size_type aLength = size_type(-1));
     569             : 
     570             :   MOZ_MUST_USE bool NS_FASTCALL ReplaceASCII(index_type aCutStart, size_type aCutLength,
     571             :                                              const char* aData,
     572             :                                              size_type aLength,
     573             :                                              const fallible_t&);
     574             : 
     575             :   // ReplaceLiteral must ONLY be applied to an actual literal string.
     576             :   // Do not attempt to use it with a regular char* pointer, or with a char
     577             :   // array variable. Use Replace or ReplaceASCII for those.
     578             :   template<int N>
     579             :   void ReplaceLiteral(index_type aCutStart, size_type aCutLength,
     580             :                       const char_type (&aStr)[N])
     581             :   {
     582             :     ReplaceLiteral(aCutStart, aCutLength, aStr, N - 1);
     583             :   }
     584             : 
     585       12812 :   void Append(char_type aChar)
     586             :   {
     587       12812 :     Replace(mLength, 0, aChar);
     588       12812 :   }
     589           0 :   MOZ_MUST_USE bool Append(char_type aChar, const fallible_t& aFallible)
     590             :   {
     591           0 :     return Replace(mLength, 0, aChar, aFallible);
     592             :   }
     593       55318 :   void Append(const char_type* aData, size_type aLength = size_type(-1))
     594             :   {
     595       55318 :     Replace(mLength, 0, aData, aLength);
     596       55318 :   }
     597        8392 :   MOZ_MUST_USE bool Append(const char_type* aData, size_type aLength,
     598             :                            const fallible_t& aFallible)
     599             :   {
     600        8392 :     return Replace(mLength, 0, aData, aLength, aFallible);
     601             :   }
     602             : 
     603             : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
     604             :   void Append(char16ptr_t aData, size_type aLength = size_type(-1))
     605             :   {
     606             :     Append(static_cast<const char16_t*>(aData), aLength);
     607             :   }
     608             : #endif
     609             : 
     610       15076 :   void Append(const self_type& aStr)
     611             :   {
     612       15076 :     Replace(mLength, 0, aStr);
     613       15076 :   }
     614         315 :   MOZ_MUST_USE bool Append(const self_type& aStr, const fallible_t& aFallible)
     615             :   {
     616         315 :     return Replace(mLength, 0, aStr, aFallible);
     617             :   }
     618           9 :   void Append(const substring_tuple_type& aTuple)
     619             :   {
     620           9 :     Replace(mLength, 0, aTuple);
     621           9 :   }
     622             : 
     623        6249 :   void AppendASCII(const char* aData, size_type aLength = size_type(-1))
     624             :   {
     625        6249 :     ReplaceASCII(mLength, 0, aData, aLength);
     626        6249 :   }
     627             : 
     628           0 :   MOZ_MUST_USE bool AppendASCII(const char* aData, const fallible_t& aFallible)
     629             :   {
     630           0 :     return ReplaceASCII(mLength, 0, aData, size_type(-1), aFallible);
     631             :   }
     632             : 
     633           0 :   MOZ_MUST_USE bool AppendASCII(const char* aData, size_type aLength, const fallible_t& aFallible)
     634             :   {
     635           0 :     return ReplaceASCII(mLength, 0, aData, aLength, aFallible);
     636             :   }
     637             : 
     638             :   /**
     639             :    * Append a formatted string to the current string. Uses the
     640             :    * standard printf format codes.  This uses NSPR formatting, which will be
     641             :    * locale-aware for floating-point values.  You probably don't want to use
     642             :    * this with floating-point values as a result.
     643             :    */
     644             :   void AppendPrintf(const char* aFormat, ...) MOZ_FORMAT_PRINTF(2, 3);
     645             :   void AppendPrintf(const char* aFormat, va_list aAp) MOZ_FORMAT_PRINTF(2, 0);
     646         197 :   void AppendInt(int32_t aInteger)
     647             :   {
     648         197 :     AppendPrintf("%" PRId32, aInteger);
     649         197 :   }
     650          11 :   void AppendInt(int32_t aInteger, int aRadix)
     651             :   {
     652          11 :     if (aRadix == 10) {
     653          11 :       AppendPrintf("%" PRId32, aInteger);
     654             :     } else {
     655           0 :       AppendPrintf(aRadix == 8 ? "%" PRIo32 : "%" PRIx32,
     656           0 :                    static_cast<uint32_t>(aInteger));
     657             :     }
     658          11 :   }
     659          20 :   void AppendInt(uint32_t aInteger)
     660             :   {
     661          20 :     AppendPrintf("%" PRIu32, aInteger);
     662          20 :   }
     663          27 :   void AppendInt(uint32_t aInteger, int aRadix)
     664             :   {
     665          27 :     AppendPrintf(aRadix == 10 ? "%" PRIu32 : aRadix == 8 ? "%" PRIo32 : "%" PRIx32,
     666          27 :                  aInteger);
     667          27 :   }
     668          10 :   void AppendInt(int64_t aInteger)
     669             :   {
     670          10 :     AppendPrintf("%" PRId64, aInteger);
     671          10 :   }
     672           0 :   void AppendInt(int64_t aInteger, int aRadix)
     673             :   {
     674           0 :     if (aRadix == 10) {
     675           0 :       AppendPrintf("%" PRId64, aInteger);
     676             :     } else {
     677           0 :       AppendPrintf(aRadix == 8 ? "%" PRIo64 : "%" PRIx64,
     678           0 :                    static_cast<uint64_t>(aInteger));
     679             :     }
     680           0 :   }
     681          10 :   void AppendInt(uint64_t aInteger)
     682             :   {
     683          10 :     AppendPrintf("%" PRIu64, aInteger);
     684          10 :   }
     685           0 :   void AppendInt(uint64_t aInteger, int aRadix)
     686             :   {
     687           0 :     AppendPrintf(aRadix == 10 ? "%" PRIu64 : aRadix == 8 ? "%" PRIo64 : "%" PRIx64,
     688           0 :                  aInteger);
     689           0 :   }
     690             : 
     691             :   /**
     692             :    * Append the given float to this string
     693             :    */
     694             :   void NS_FASTCALL AppendFloat(float aFloat);
     695             :   void NS_FASTCALL AppendFloat(double aFloat);
     696             : public:
     697             : 
     698             :   // AppendLiteral must ONLY be applied to an actual literal string.
     699             :   // Do not attempt to use it with a regular char* pointer, or with a char
     700             :   // array variable. Use Append or AppendASCII for those.
     701             :   template<int N>
     702        1323 :   void AppendLiteral(const char_type (&aStr)[N])
     703             :   {
     704        1323 :     ReplaceLiteral(mLength, 0, aStr, N - 1);
     705        1323 :   }
     706             : #ifdef CharT_is_PRUnichar
     707             :   template<int N>
     708          17 :   void AppendLiteral(const char (&aStr)[N])
     709             :   {
     710          17 :     AppendASCII(aStr, N - 1);
     711          17 :   }
     712             : 
     713             :   template<int N>
     714           0 :   MOZ_MUST_USE bool AppendLiteral(const char (&aStr)[N], const fallible_t& aFallible)
     715             :   {
     716           0 :     return AppendASCII(aStr, N - 1, aFallible);
     717             :   }
     718             : #endif
     719             : 
     720        2706 :   self_type& operator+=(char_type aChar)
     721             :   {
     722        2706 :     Append(aChar);
     723        2706 :     return *this;
     724             :   }
     725         850 :   self_type& operator+=(const char_type* aData)
     726             :   {
     727         850 :     Append(aData);
     728         850 :     return *this;
     729             :   }
     730             : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
     731             :   self_type& operator+=(char16ptr_t aData)
     732             :   {
     733             :     Append(aData);
     734             :     return *this;
     735             :   }
     736             : #endif
     737        2645 :   self_type& operator+=(const self_type& aStr)
     738             :   {
     739        2645 :     Append(aStr);
     740        2645 :     return *this;
     741             :   }
     742           1 :   self_type& operator+=(const substring_tuple_type& aTuple)
     743             :   {
     744           1 :     Append(aTuple);
     745           1 :     return *this;
     746             :   }
     747             : 
     748         316 :   void Insert(char_type aChar, index_type aPos)
     749             :   {
     750         316 :     Replace(aPos, 0, aChar);
     751         316 :   }
     752         195 :   void Insert(const char_type* aData, index_type aPos,
     753             :               size_type aLength = size_type(-1))
     754             :   {
     755         195 :     Replace(aPos, 0, aData, aLength);
     756         195 :   }
     757             : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
     758             :   void Insert(char16ptr_t aData, index_type aPos,
     759             :               size_type aLength = size_type(-1))
     760             :   {
     761             :     Insert(static_cast<const char16_t*>(aData), aPos, aLength);
     762             :   }
     763             : #endif
     764         387 :   void Insert(const self_type& aStr, index_type aPos)
     765             :   {
     766         387 :     Replace(aPos, 0, aStr);
     767         387 :   }
     768           0 :   void Insert(const substring_tuple_type& aTuple, index_type aPos)
     769             :   {
     770           0 :     Replace(aPos, 0, aTuple);
     771           0 :   }
     772             : 
     773             :   // InsertLiteral must ONLY be applied to an actual literal string.
     774             :   // Do not attempt to use it with a regular char* pointer, or with a char
     775             :   // array variable. Use Insert for those.
     776             :   template<int N>
     777         172 :   void InsertLiteral(const char_type (&aStr)[N], index_type aPos)
     778             :   {
     779         172 :     ReplaceLiteral(aPos, 0, aStr, N - 1);
     780         172 :   }
     781             : 
     782         992 :   void Cut(index_type aCutStart, size_type aCutLength)
     783             :   {
     784         992 :     Replace(aCutStart, aCutLength, char_traits::sEmptyBuffer, 0);
     785         992 :   }
     786             : 
     787             :   nsTSubstringSplitter_CharT Split(const char_type aChar) const;
     788             : 
     789             :   /**
     790             :    * buffer sizing
     791             :    */
     792             : 
     793             :   /**
     794             :    * Attempts to set the capacity to the given size in number of
     795             :    * characters, without affecting the length of the string.
     796             :    * There is no need to include room for the null terminator: it is
     797             :    * the job of the string class.
     798             :    * Also ensures that the buffer is mutable.
     799             :    */
     800             :   void NS_FASTCALL SetCapacity(size_type aNewCapacity);
     801             :   MOZ_MUST_USE bool NS_FASTCALL SetCapacity(size_type aNewCapacity,
     802             :                                             const fallible_t&);
     803             : 
     804             :   void NS_FASTCALL SetLength(size_type aNewLength);
     805             :   MOZ_MUST_USE bool NS_FASTCALL SetLength(size_type aNewLength,
     806             :                                           const fallible_t&);
     807             : 
     808      268250 :   void Truncate(size_type aNewLength = 0)
     809             :   {
     810      268250 :     NS_ASSERTION(aNewLength <= mLength, "Truncate cannot make string longer");
     811      268250 :     SetLength(aNewLength);
     812      268250 :   }
     813             : 
     814             : 
     815             :   /**
     816             :    * buffer access
     817             :    */
     818             : 
     819             : 
     820             :   /**
     821             :    * Get a const pointer to the string's internal buffer.  The caller
     822             :    * MUST NOT modify the characters at the returned address.
     823             :    *
     824             :    * @returns The length of the buffer in characters.
     825             :    */
     826           0 :   inline size_type GetData(const char_type** aData) const
     827             :   {
     828           0 :     *aData = mData;
     829           0 :     return mLength;
     830             :   }
     831             : 
     832             :   /**
     833             :    * Get a pointer to the string's internal buffer, optionally resizing
     834             :    * the buffer first.  If size_type(-1) is passed for newLen, then the
     835             :    * current length of the string is used.  The caller MAY modify the
     836             :    * characters at the returned address (up to but not exceeding the
     837             :    * length of the string).
     838             :    *
     839             :    * @returns The length of the buffer in characters or 0 if unable to
     840             :    * satisfy the request due to low-memory conditions.
     841             :    */
     842           6 :   size_type GetMutableData(char_type** aData, size_type aNewLen = size_type(-1))
     843             :   {
     844           6 :     if (!EnsureMutable(aNewLen)) {
     845           0 :       AllocFailed(aNewLen == size_type(-1) ? mLength : aNewLen);
     846             :     }
     847             : 
     848           6 :     *aData = mData;
     849           6 :     return mLength;
     850             :   }
     851             : 
     852           0 :   size_type GetMutableData(char_type** aData, size_type aNewLen, const fallible_t&)
     853             :   {
     854           0 :     if (!EnsureMutable(aNewLen)) {
     855           0 :       *aData = nullptr;
     856           0 :       return 0;
     857             :     }
     858             : 
     859           0 :     *aData = mData;
     860           0 :     return mLength;
     861             :   }
     862             : 
     863             : #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
     864             :   size_type GetMutableData(wchar_t** aData, size_type aNewLen = size_type(-1))
     865             :   {
     866             :     return GetMutableData(reinterpret_cast<char16_t**>(aData), aNewLen);
     867             :   }
     868             : 
     869             :   size_type GetMutableData(wchar_t** aData, size_type aNewLen,
     870             :                            const fallible_t& aFallible)
     871             :   {
     872             :     return GetMutableData(reinterpret_cast<char16_t**>(aData), aNewLen,
     873             :                           aFallible);
     874             :   }
     875             : #endif
     876             : 
     877             :   /**
     878             :    * Span integration
     879             :    */
     880             : 
     881           2 :   operator mozilla::Span<char_type>()
     882             :   {
     883           2 :     return mozilla::MakeSpan(BeginWriting(), Length());
     884             :   }
     885             : 
     886         226 :   operator mozilla::Span<const char_type>() const
     887             :   {
     888         226 :     return mozilla::MakeSpan(BeginReading(), Length());
     889             :   }
     890             : 
     891             :   void Append(mozilla::Span<const char_type> aSpan)
     892             :   {
     893             :     auto len = aSpan.Length();
     894             :     MOZ_RELEASE_ASSERT(len <= mozilla::MaxValue<size_type>::value);
     895             :     Append(aSpan.Elements(), len);
     896             :   }
     897             : 
     898             :   MOZ_MUST_USE bool Append(mozilla::Span<const char_type> aSpan,
     899             :                            const fallible_t& aFallible)
     900             :   {
     901             :     auto len = aSpan.Length();
     902             :     if (len > mozilla::MaxValue<size_type>::value) {
     903             :       return false;
     904             :     }
     905             :     return Append(aSpan.Elements(), len, aFallible);
     906             :   }
     907             : 
     908             : #if !defined(CharT_is_PRUnichar)
     909           0 :   operator mozilla::Span<uint8_t>()
     910             :   {
     911           0 :     return mozilla::MakeSpan(reinterpret_cast<uint8_t*>(BeginWriting()),
     912           0 :                              Length());
     913             :   }
     914             : 
     915          78 :   operator mozilla::Span<const uint8_t>() const
     916             :   {
     917          78 :     return mozilla::MakeSpan(reinterpret_cast<const uint8_t*>(BeginReading()),
     918         156 :                              Length());
     919             :   }
     920             : 
     921             :   void Append(mozilla::Span<const uint8_t> aSpan)
     922             :   {
     923             :     auto len = aSpan.Length();
     924             :     MOZ_RELEASE_ASSERT(len <= mozilla::MaxValue<size_type>::value);
     925             :     Append(reinterpret_cast<const char*>(aSpan.Elements()), len);
     926             :   }
     927             : 
     928             :   MOZ_MUST_USE bool Append(mozilla::Span<const uint8_t> aSpan,
     929             :                            const fallible_t& aFallible)
     930             :   {
     931             :     auto len = aSpan.Length();
     932             :     if (len > mozilla::MaxValue<size_type>::value) {
     933             :       return false;
     934             :     }
     935             :     return Append(
     936             :       reinterpret_cast<const char*>(aSpan.Elements()), len, aFallible);
     937             :   }
     938             : #endif
     939             : 
     940             :   /**
     941             :    * string data is never null, but can be marked void.  if true, the
     942             :    * string will be truncated.  @see nsTSubstring::IsVoid
     943             :    */
     944             : 
     945             :   void NS_FASTCALL SetIsVoid(bool);
     946             : 
     947             :   /**
     948             :    *  This method is used to remove all occurrences of aChar from this
     949             :    * string.
     950             :    *
     951             :    *  @param  aChar -- char to be stripped
     952             :    */
     953             : 
     954             :   void StripChar(char_type aChar);
     955             : 
     956             :   /**
     957             :    *  This method is used to remove all occurrences of aChars from this
     958             :    * string.
     959             :    *
     960             :    *  @param  aChars -- chars to be stripped
     961             :    */
     962             : 
     963             :   void StripChars(const char_type* aChars);
     964             : 
     965             :   /**
     966             :    * This method is used to remove all occurrences of some characters this
     967             :    * from this string.  The characters removed have the corresponding
     968             :    * entries in the bool array set to true; we retain all characters
     969             :    * with code beyond 127.
     970             :    * THE CALLER IS RESPONSIBLE for making sure the complete boolean
     971             :    * array, 128 entries, is properly initialized.
     972             :    *
     973             :    * See also: ASCIIMask class.
     974             :    *
     975             :    *  @param  aToStrip -- Array where each entry is true if the
     976             :    *          corresponding ASCII character is to be stripped.  All
     977             :    *          characters beyond code 127 are retained.  Note that this
     978             :    *          parameter is of ASCIIMaskArray type, but we expand the typedef
     979             :    *          to avoid having to include nsASCIIMask.h in this include file
     980             :    *          as it brings other includes.
     981             :    */
     982             :   void StripTaggedASCII(const std::array<bool, 128>& aToStrip);
     983             : 
     984             :   /**
     985             :    * A shortcut to strip \r and \n.
     986             :    */
     987             :   void StripCRLF();
     988             : 
     989             :   /**
     990             :    * If the string uses a shared buffer, this method
     991             :    * clears the pointer without releasing the buffer.
     992             :    */
     993          12 :   void ForgetSharedBuffer()
     994             :   {
     995          12 :     if (mDataFlags & DataFlags::SHARED) {
     996          12 :       mData = char_traits::sEmptyBuffer;
     997          12 :       mLength = 0;
     998          12 :       mDataFlags = DataFlags::TERMINATED;
     999             :     }
    1000          12 :   }
    1001             : 
    1002             : public:
    1003             : 
    1004             :   /**
    1005             :    * this is public to support automatic conversion of tuple to string
    1006             :    * base type, which helps avoid converting to nsTAString.
    1007             :    */
    1008         322 :   MOZ_IMPLICIT nsTSubstring_CharT(const substring_tuple_type& aTuple)
    1009         322 :     : nsTStringRepr_CharT(nullptr, 0, DataFlags(0), ClassFlags(0))
    1010             :   {
    1011         322 :     Assign(aTuple);
    1012         322 :   }
    1013             : 
    1014             :   size_t SizeOfExcludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf)
    1015             :   const;
    1016             :   size_t SizeOfIncludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf)
    1017             :   const;
    1018             : 
    1019             :   /**
    1020             :    * WARNING: Only use these functions if you really know what you are
    1021             :    * doing, because they can easily lead to double-counting strings.  If
    1022             :    * you do use them, please explain clearly in a comment why it's safe
    1023             :    * and won't lead to double-counting.
    1024             :    */
    1025             :   size_t SizeOfExcludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf)
    1026             :   const;
    1027             :   size_t SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf)
    1028             :   const;
    1029             : 
    1030             :   template<class T>
    1031             :   void NS_ABORT_OOM(T)
    1032             :   {
    1033             :     struct never {}; // a compiler-friendly way to do static_assert(false)
    1034             :     static_assert(mozilla::IsSame<T, never>::value,
    1035             :       "In string classes, use AllocFailed to account for sizeof(char_type). "
    1036             :       "Use the global ::NS_ABORT_OOM if you really have a count of bytes.");
    1037             :   }
    1038             : 
    1039           0 :   MOZ_ALWAYS_INLINE void AllocFailed(size_t aLength)
    1040             :   {
    1041           0 :     ::NS_ABORT_OOM(aLength * sizeof(char_type));
    1042           0 :   }
    1043             : 
    1044             : protected:
    1045             : 
    1046             :   // default initialization
    1047      398928 :   nsTSubstring_CharT()
    1048      398928 :     : nsTStringRepr_CharT(char_traits::sEmptyBuffer, 0, DataFlags::TERMINATED,
    1049      398928 :                           ClassFlags(0))
    1050             :   {
    1051      398929 :   }
    1052             : 
    1053             :   // copy-constructor, constructs as dependent on given object
    1054             :   // (NOTE: this is for internal use only)
    1055           3 :   nsTSubstring_CharT(const self_type& aStr)
    1056           6 :     : nsTStringRepr_CharT(aStr.mData, aStr.mLength,
    1057      705198 :                           aStr.mDataFlags & (DataFlags::TERMINATED | DataFlags::VOIDED),
    1058           6 :                           ClassFlags(0))
    1059             :   {
    1060           3 :   }
    1061             : 
    1062             :  /**
    1063             :    * allows for direct initialization of a nsTSubstring object.
    1064             :    */
    1065             :   nsTSubstring_CharT(char_type* aData, size_type aLength,
    1066             :                      DataFlags aDataFlags, ClassFlags aClassFlags)
    1067             : // XXXbz or can I just include nscore.h and use NS_BUILD_REFCNT_LOGGING?
    1068             : #if defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING)
    1069             : #define XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
    1070             :     ;
    1071             : #else
    1072             : #undef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
    1073             :     : nsTStringRepr_CharT(aData, aLength, aDataFlags, aClassFlags)
    1074             :   {
    1075             :     MOZ_RELEASE_ASSERT(CheckCapacity(aLength), "String is too large.");
    1076             :   }
    1077             : #endif /* DEBUG || FORCE_BUILD_REFCNT_LOGGING */
    1078             : 
    1079             :   /**
    1080             :    * this function releases mData and does not change the value of
    1081             :    * any of its member variables.  in other words, this function acts
    1082             :    * like a destructor.
    1083             :    */
    1084             :   void NS_FASTCALL Finalize();
    1085             : 
    1086             :   /**
    1087             :    * this function prepares mData to be mutated.
    1088             :    *
    1089             :    * @param aCapacity    specifies the required capacity of mData
    1090             :    * @param aOldData     returns null or the old value of mData
    1091             :    * @param aOldFlags    returns 0 or the old value of mDataFlags
    1092             :    *
    1093             :    * if mData is already mutable and of sufficient capacity, then this
    1094             :    * function will return immediately.  otherwise, it will either resize
    1095             :    * mData or allocate a new shared buffer.  if it needs to allocate a
    1096             :    * new buffer, then it will return the old buffer and the corresponding
    1097             :    * flags.  this allows the caller to decide when to free the old data.
    1098             :    *
    1099             :    * this function returns false if is unable to allocate sufficient
    1100             :    * memory.
    1101             :    *
    1102             :    * XXX we should expose a way for subclasses to free old_data.
    1103             :    */
    1104             :   bool NS_FASTCALL MutatePrep(size_type aCapacity,
    1105             :                               char_type** aOldData, DataFlags* aOldDataFlags);
    1106             : 
    1107             :   /**
    1108             :    * this function prepares a section of mData to be modified.  if
    1109             :    * necessary, this function will reallocate mData and possibly move
    1110             :    * existing data to open up the specified section.
    1111             :    *
    1112             :    * @param aCutStart    specifies the starting offset of the section
    1113             :    * @param aCutLength   specifies the length of the section to be replaced
    1114             :    * @param aNewLength   specifies the length of the new section
    1115             :    *
    1116             :    * for example, suppose mData contains the string "abcdef" then
    1117             :    *
    1118             :    *   ReplacePrep(2, 3, 4);
    1119             :    *
    1120             :    * would cause mData to look like "ab____f" where the characters
    1121             :    * indicated by '_' have an unspecified value and can be freely
    1122             :    * modified.  this function will null-terminate mData upon return.
    1123             :    *
    1124             :    * this function returns false if is unable to allocate sufficient
    1125             :    * memory.
    1126             :    */
    1127             :   MOZ_MUST_USE bool ReplacePrep(index_type aCutStart,
    1128             :                                 size_type aCutLength,
    1129             :                                 size_type aNewLength);
    1130             : 
    1131             :   MOZ_MUST_USE bool NS_FASTCALL ReplacePrepInternal(
    1132             :     index_type aCutStart,
    1133             :     size_type aCutLength,
    1134             :     size_type aNewFragLength,
    1135             :     size_type aNewTotalLength);
    1136             : 
    1137             :   /**
    1138             :    * returns the number of writable storage units starting at mData.
    1139             :    * the value does not include space for the null-terminator character.
    1140             :    *
    1141             :    * NOTE: this function returns 0 if mData is immutable (or the buffer
    1142             :    *       is 0-sized).
    1143             :    */
    1144             :   size_type NS_FASTCALL Capacity() const;
    1145             : 
    1146             :   /**
    1147             :    * this helper function can be called prior to directly manipulating
    1148             :    * the contents of mData.  see, for example, BeginWriting.
    1149             :    */
    1150             :   MOZ_MUST_USE bool NS_FASTCALL EnsureMutable(
    1151             :     size_type aNewLen = size_type(-1));
    1152             : 
    1153             :   /**
    1154             :    * Checks if the given capacity is valid for this string type.
    1155             :    */
    1156      572747 :   static MOZ_MUST_USE bool CheckCapacity(size_type aCapacity) {
    1157      572747 :     if (aCapacity > kMaxCapacity) {
    1158             :       // Also assert for |aCapacity| equal to |size_type(-1)|, since we used to
    1159             :       // use that value to flag immutability.
    1160           0 :       NS_ASSERTION(aCapacity != size_type(-1), "Bogus capacity");
    1161           0 :       return false;
    1162             :     }
    1163             : 
    1164      572747 :     return true;
    1165             :   }
    1166             : 
    1167             :   void NS_FASTCALL ReplaceLiteral(index_type aCutStart, size_type aCutLength,
    1168             :                                   const char_type* aData, size_type aLength);
    1169             : 
    1170             :   static const size_type kMaxCapacity;
    1171             : public:
    1172             : 
    1173             :   // NOTE: this method is declared public _only_ for convenience for
    1174             :   // callers who don't have access to the original nsLiteralString_CharT.
    1175             :   void NS_FASTCALL AssignLiteral(const char_type* aData, size_type aLength);
    1176             : };
    1177             : 
    1178             : static_assert(sizeof(nsTSubstring_CharT) ==
    1179             :               sizeof(mozilla::detail::nsTStringRepr_CharT),
    1180             :               "Don't add new data fields to nsTSubstring_CharT. "
    1181             :               "Add to nsTStringRepr_CharT instead.");
    1182             : 
    1183             : int NS_FASTCALL
    1184             : Compare(const nsTSubstring_CharT::base_string_type& aLhs,
    1185             :         const nsTSubstring_CharT::base_string_type& aRhs,
    1186             :         const nsTStringComparator_CharT& = nsTDefaultStringComparator_CharT());
    1187             : 
    1188             : 
    1189             : inline bool
    1190        1414 : operator!=(const nsTSubstring_CharT::base_string_type& aLhs,
    1191             :            const nsTSubstring_CharT::base_string_type& aRhs)
    1192             : {
    1193        1414 :   return !aLhs.Equals(aRhs);
    1194             : }
    1195             : 
    1196             : inline bool
    1197           0 : operator!=(const nsTSubstring_CharT::base_string_type& aLhs,
    1198             :            const nsTSubstring_CharT::char_type* aRhs)
    1199             : {
    1200           0 :   return !aLhs.Equals(aRhs);
    1201             : }
    1202             : 
    1203             : inline bool
    1204        1955 : operator<(const nsTSubstring_CharT::base_string_type& aLhs,
    1205             :           const nsTSubstring_CharT::base_string_type& aRhs)
    1206             : {
    1207        1955 :   return Compare(aLhs, aRhs) < 0;
    1208             : }
    1209             : 
    1210             : inline bool
    1211           0 : operator<=(const nsTSubstring_CharT::base_string_type& aLhs,
    1212             :            const nsTSubstring_CharT::base_string_type& aRhs)
    1213             : {
    1214           0 :   return Compare(aLhs, aRhs) <= 0;
    1215             : }
    1216             : 
    1217             : inline bool
    1218        6107 : operator==(const nsTSubstring_CharT::base_string_type& aLhs,
    1219             :            const nsTSubstring_CharT::base_string_type& aRhs)
    1220             : {
    1221        6107 :   return aLhs.Equals(aRhs);
    1222             : }
    1223             : 
    1224             : inline bool
    1225           0 : operator==(const nsTSubstring_CharT::base_string_type& aLhs,
    1226             :            const nsTSubstring_CharT::char_type* aRhs)
    1227             : {
    1228           0 :   return aLhs.Equals(aRhs);
    1229             : }
    1230             : 
    1231             : 
    1232             : inline bool
    1233             : operator>=(const nsTSubstring_CharT::base_string_type& aLhs,
    1234             :            const nsTSubstring_CharT::base_string_type& aRhs)
    1235             : {
    1236             :   return Compare(aLhs, aRhs) >= 0;
    1237             : }
    1238             : 
    1239             : inline bool
    1240             : operator>(const nsTSubstring_CharT::base_string_type& aLhs,
    1241             :           const nsTSubstring_CharT::base_string_type& aRhs)
    1242             : {
    1243             :   return Compare(aLhs, aRhs) > 0;
    1244             : }
    1245             : 
    1246             : // You should not need to instantiate this class directly.
    1247             : // Use nsTSubstring::Split instead.
    1248           5 : class nsTSubstringSplitter_CharT
    1249             : {
    1250             :   typedef nsTSubstring_CharT::size_type size_type;
    1251             :   typedef nsTSubstring_CharT::char_type char_type;
    1252             : 
    1253             :   class nsTSubstringSplit_Iter
    1254             :   {
    1255             :   public:
    1256          10 :     nsTSubstringSplit_Iter(const nsTSubstringSplitter_CharT& aObj,
    1257             :                            size_type aPos)
    1258          10 :       : mObj(aObj)
    1259          10 :       , mPos(aPos)
    1260             :     {
    1261          10 :     }
    1262             : 
    1263          17 :     bool operator!=(const nsTSubstringSplit_Iter& other) const
    1264             :     {
    1265          17 :       return mPos != other.mPos;
    1266             :     }
    1267             : 
    1268             :     const nsTDependentSubstring_CharT& operator*() const;
    1269             : 
    1270          12 :     const nsTSubstringSplit_Iter& operator++()
    1271             :     {
    1272          12 :       ++mPos;
    1273          12 :       return *this;
    1274             :     }
    1275             : 
    1276             :   private:
    1277             :     const nsTSubstringSplitter_CharT& mObj;
    1278             :     size_type mPos;
    1279             :   };
    1280             : 
    1281             : private:
    1282             :   const nsTSubstring_CharT* const mStr;
    1283             :   mozilla::UniquePtr<nsTDependentSubstring_CharT[]> mArray;
    1284             :   size_type mArraySize;
    1285             :   const char_type mDelim;
    1286             : 
    1287             : public:
    1288             :   nsTSubstringSplitter_CharT(const nsTSubstring_CharT* aStr, char_type aDelim);
    1289             : 
    1290           5 :   nsTSubstringSplit_Iter begin() const
    1291             :   {
    1292           5 :     return nsTSubstringSplit_Iter(*this, 0);
    1293             :   }
    1294             : 
    1295           5 :   nsTSubstringSplit_Iter end() const
    1296             :   {
    1297           5 :     return nsTSubstringSplit_Iter(*this, mArraySize);
    1298             :   }
    1299             : 
    1300          12 :   const nsTDependentSubstring_CharT& Get(const size_type index) const
    1301             :   {
    1302          12 :     MOZ_ASSERT(index < mArraySize);
    1303          12 :     return mArray[index];
    1304             :   }
    1305             : };
    1306             : 
    1307             : /**
    1308             :  * Span integration
    1309             :  */
    1310             : namespace mozilla {
    1311             : 
    1312             : inline Span<CharT>
    1313           0 : MakeSpan(nsTSubstring_CharT& aString)
    1314             : {
    1315           0 :   return aString;
    1316             : }
    1317             : 
    1318             : inline Span<const CharT>
    1319           0 : MakeSpan(const nsTSubstring_CharT& aString)
    1320             : {
    1321           0 :   return aString;
    1322             : }
    1323             : 
    1324             : } // namespace mozilla

Generated by: LCOV version 1.13