xpcom/string/public/nsTSubstring.h

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

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

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

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 // IWYU pragma: private, include "nsString.h"
     8 #include "mozilla/Casting.h"
     9 #include "mozilla/MemoryReporting.h"
    11 #ifndef MOZILLA_INTERNAL_API
    12 #error Cannot use internal string classes without MOZILLA_INTERNAL_API defined. Use the frozen header nsStringAPI.h instead.
    13 #endif
    15   /**
    16    * The base for string comparators
    17    */
    18 class nsTStringComparator_CharT
    19   {
    20     public:
    21       typedef CharT char_type;
    23       nsTStringComparator_CharT() {}
    25       virtual int operator()( const char_type*, const char_type*, uint32_t, uint32_t ) const = 0;
    26   };
    29   /**
    30    * The default string comparator (case-sensitive comparision)
    31    */
    32 class nsTDefaultStringComparator_CharT
    33     : public nsTStringComparator_CharT
    34   {
    35     public:
    36       typedef CharT char_type;
    38       nsTDefaultStringComparator_CharT() {}
    40       virtual int operator()( const char_type*, const char_type*, uint32_t, uint32_t ) const;
    41   };
    43   /**
    44    * nsTSubstring is the most abstract class in the string hierarchy. It
    45    * represents a single contiguous array of characters, which may or may not
    46    * be null-terminated. This type is not instantiated directly.  A sub-class
    47    * is instantiated instead.  For example, see nsTString.
    48    *
    49    * NAMES:
    50    *   nsAString for wide characters
    51    *   nsACString for narrow characters
    52    *
    53    * Many of the accessors on nsTSubstring are inlined as an optimization.
    54    */
    55 class nsTSubstring_CharT
    56   {
    57     public:
    58       typedef mozilla::fallible_t                 fallible_t;
    60       typedef CharT                               char_type;
    62       typedef nsCharTraits<char_type>             char_traits;
    63       typedef char_traits::incompatible_char_type incompatible_char_type;
    65       typedef nsTSubstring_CharT                  self_type;
    66       typedef self_type                           abstract_string_type;
    67       typedef self_type                           base_string_type;
    69       typedef self_type                           substring_type;
    70       typedef nsTSubstringTuple_CharT             substring_tuple_type;
    71       typedef nsTString_CharT                     string_type;
    73       typedef nsReadingIterator<char_type>        const_iterator;
    74       typedef nsWritingIterator<char_type>        iterator;
    76       typedef nsTStringComparator_CharT           comparator_type;
    78       typedef char_type*                          char_iterator;
    79       typedef const char_type*                    const_char_iterator;
    81       typedef uint32_t                            size_type;
    82       typedef uint32_t                            index_type;
    84     public:
    86         // this acts like a virtual destructor
    87       ~nsTSubstring_CharT() { Finalize(); }
    89         /**
    90          * reading iterators
    91          */
    93       const_char_iterator BeginReading() const { return mData; }
    94       const_char_iterator EndReading() const { return mData + mLength; }
    96         /**
    97          * deprecated reading iterators
    98          */
   100       const_iterator& BeginReading( const_iterator& iter ) const
   101         {
   102           iter.mStart = mData;
   103           iter.mEnd = mData + mLength;
   104           iter.mPosition = iter.mStart;
   105           return iter;
   106         }
   108       const_iterator& EndReading( const_iterator& iter ) const
   109         {
   110           iter.mStart = mData;
   111           iter.mEnd = mData + mLength;
   112           iter.mPosition = iter.mEnd;
   113           return iter;
   114         }
   116       const_char_iterator& BeginReading( const_char_iterator& iter ) const
   117         {
   118           return iter = mData;
   119         }
   121       const_char_iterator& EndReading( const_char_iterator& iter ) const
   122         {
   123           return iter = mData + mLength;
   124         }
   127         /**
   128          * writing iterators
   129          */
   131       char_iterator BeginWriting()
   132         {
   133           if (!EnsureMutable())
   134             NS_ABORT_OOM(mLength);
   136           return mData;
   137         }
   139       char_iterator BeginWriting( const fallible_t& )
   140         {
   141           return EnsureMutable() ? mData : char_iterator(0);
   142         }
   144       char_iterator EndWriting()
   145         {
   146           if (!EnsureMutable())
   147             NS_ABORT_OOM(mLength);
   149           return mData + mLength;
   150         }
   152       char_iterator EndWriting( const fallible_t& )
   153         {
   154           return EnsureMutable() ? (mData + mLength) : char_iterator(0);
   155         }
   157       char_iterator& BeginWriting( char_iterator& iter )
   158         {
   159           return iter = BeginWriting();
   160         }
   162       char_iterator& BeginWriting( char_iterator& iter, const fallible_t& )
   163         {
   164           return iter = BeginWriting(fallible_t());
   165         }
   167       char_iterator& EndWriting( char_iterator& iter )
   168         {
   169           return iter = EndWriting();
   170         }
   172       char_iterator& EndWriting( char_iterator& iter, const fallible_t& )
   173         {
   174           return iter = EndWriting(fallible_t());
   175         }
   177         /**
   178          * deprecated writing iterators
   179          */
   181       iterator& BeginWriting( iterator& iter )
   182         {
   183           char_type *data = BeginWriting();
   184           iter.mStart = data;
   185           iter.mEnd = data + mLength;
   186           iter.mPosition = iter.mStart;
   187           return iter;
   188         }
   190       iterator& EndWriting( iterator& iter )
   191         {
   192           char_type *data = BeginWriting();
   193           iter.mStart = data;
   194           iter.mEnd = data + mLength;
   195           iter.mPosition = iter.mEnd;
   196           return iter;
   197         }
   199         /**
   200          * accessors
   201          */
   203         // returns pointer to string data (not necessarily null-terminated)
   204 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
   205       char16ptr_t Data() const
   206 #else
   207       const char_type *Data() const
   208 #endif
   209         {
   210           return mData;
   211         }
   213       size_type Length() const
   214         {
   215           return mLength;
   216         }
   218       uint32_t Flags() const
   219         {
   220           return mFlags;
   221         }
   223       bool IsEmpty() const
   224         {
   225           return mLength == 0;
   226         }
   228       bool IsLiteral() const
   229         {
   230           return (mFlags & F_LITERAL) != 0;
   231         }
   233       bool IsVoid() const
   234         {
   235           return (mFlags & F_VOIDED) != 0;
   236         }
   238       bool IsTerminated() const
   239         {
   240           return (mFlags & F_TERMINATED) != 0;
   241         }
   243       char_type CharAt( index_type i ) const
   244         {
   245           NS_ASSERTION(i < mLength, "index exceeds allowable range");
   246           return mData[i];
   247         }
   249       char_type operator[]( index_type i ) const
   250         {
   251           return CharAt(i);
   252         }
   254       char_type First() const
   255         {
   256           NS_ASSERTION(mLength > 0, "|First()| called on an empty string");
   257           return mData[0];
   258         }
   260       inline
   261       char_type Last() const
   262         {
   263           NS_ASSERTION(mLength > 0, "|Last()| called on an empty string");
   264           return mData[mLength - 1];
   265         }
   267       size_type NS_FASTCALL CountChar( char_type ) const;
   268       int32_t NS_FASTCALL FindChar( char_type, index_type offset = 0 ) const;
   271         /**
   272          * equality
   273          */
   275       bool NS_FASTCALL Equals( const self_type& ) const;
   276       bool NS_FASTCALL Equals( const self_type&, const comparator_type& ) const;
   278       bool NS_FASTCALL Equals( const char_type* data ) const;
   279       bool NS_FASTCALL Equals( const char_type* data, const comparator_type& comp ) const;
   281 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
   282       bool NS_FASTCALL Equals( char16ptr_t data ) const
   283         {
   284           return Equals(static_cast<const char16_t*>(data));
   285         }
   286       bool NS_FASTCALL Equals( char16ptr_t data, const comparator_type& comp ) const
   287         {
   288           return Equals(static_cast<const char16_t*>(data), comp);
   289         }
   290 #endif
   292         /**
   293          * An efficient comparison with ASCII that can be used even
   294          * for wide strings. Call this version when you know the
   295          * length of 'data'.
   296          */
   297       bool NS_FASTCALL EqualsASCII( const char* data, size_type len ) const;
   298         /**
   299          * An efficient comparison with ASCII that can be used even
   300          * for wide strings. Call this version when 'data' is
   301          * null-terminated.
   302          */
   303       bool NS_FASTCALL EqualsASCII( const char* data ) const;
   305     // EqualsLiteral must ONLY be applied to an actual literal string, or
   306     // a char array *constant* declared without an explicit size.
   307     // Do not attempt to use it with a regular char* pointer, or with a
   308     // non-constant char array variable. Use EqualsASCII for them.
   309     // The template trick to acquire the array length at compile time without
   310     // using a macro is due to Corey Kosak, with much thanks.
   311       template<int N>
   312       inline bool EqualsLiteral( const char (&str)[N] ) const
   313         {
   314           return EqualsASCII(str, N-1);
   315         }
   317     // The LowerCaseEquals methods compare the ASCII-lowercase version of
   318     // this string (lowercasing only ASCII uppercase characters) to some
   319     // ASCII/Literal string. The ASCII string is *not* lowercased for
   320     // you. If you compare to an ASCII or literal string that contains an
   321     // uppercase character, it is guaranteed to return false. We will
   322     // throw assertions too.
   323       bool NS_FASTCALL LowerCaseEqualsASCII( const char* data, size_type len ) const;
   324       bool NS_FASTCALL LowerCaseEqualsASCII( const char* data ) const;
   326     // LowerCaseEqualsLiteral must ONLY be applied to an actual
   327     // literal string, or a char array *constant* declared without an 
   328     // explicit size.  Do not attempt to use it with a regular char*
   329     // pointer, or with a non-constant char array variable. Use
   330     // LowerCaseEqualsASCII for them.
   331       template<int N>
   332       inline bool LowerCaseEqualsLiteral( const char (&str)[N] ) const
   333         {
   334           return LowerCaseEqualsASCII(str, N-1);
   335         }
   337         /**
   338          * assignment
   339          */
   341       void NS_FASTCALL Assign( char_type c );
   342       bool NS_FASTCALL Assign( char_type c, const fallible_t& ) NS_WARN_UNUSED_RESULT;
   344       void NS_FASTCALL Assign( const char_type* data );
   345       void NS_FASTCALL Assign( const char_type* data, size_type length );
   346       bool NS_FASTCALL Assign( const char_type* data, size_type length, const fallible_t& ) NS_WARN_UNUSED_RESULT;
   348       void NS_FASTCALL Assign( const self_type& );
   349       bool NS_FASTCALL Assign( const self_type&, const fallible_t& ) NS_WARN_UNUSED_RESULT;
   351       void NS_FASTCALL Assign( const substring_tuple_type& );
   352       bool NS_FASTCALL Assign( const substring_tuple_type&, const fallible_t& ) NS_WARN_UNUSED_RESULT;
   354 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
   355       void Assign (char16ptr_t data)
   356         {
   357           Assign(static_cast<const char16_t*>(data));
   358         }
   360       bool Assign(char16ptr_t data, const fallible_t&) NS_WARN_UNUSED_RESULT
   361         {
   362           return Assign(static_cast<const char16_t*>(data), fallible_t());
   363         }
   365       void Assign (char16ptr_t data, size_type length)
   366         {
   367           Assign(static_cast<const char16_t*>(data), length);
   368         }
   370       bool Assign(char16ptr_t data, size_type length, const fallible_t&) NS_WARN_UNUSED_RESULT
   371         {
   372           return Assign(static_cast<const char16_t*>(data), length, fallible_t());
   373         }
   374 #endif
   376       void NS_FASTCALL AssignASCII( const char* data, size_type length );
   377       bool NS_FASTCALL AssignASCII( const char* data, size_type length, const fallible_t& ) NS_WARN_UNUSED_RESULT;
   379       void NS_FASTCALL AssignASCII( const char* data )
   380         {
   381           AssignASCII(data, mozilla::SafeCast<size_type, size_t>(strlen(data)));
   382         }
   383       bool NS_FASTCALL AssignASCII( const char* data, const fallible_t& ) NS_WARN_UNUSED_RESULT
   384         {
   385           return AssignASCII(data, mozilla::SafeCast<size_type, size_t>(strlen(data)), fallible_t());
   386         }
   388     // AssignLiteral must ONLY be applied to an actual literal string, or
   389     // a char array *constant* declared without an explicit size.
   390     // Do not attempt to use it with a regular char* pointer, or with a 
   391     // non-constant char array variable. Use AssignASCII for those.
   392     // There are not fallible version of these methods because they only really
   393     // apply to small allocations that we wouldn't want to check anyway.
   394       template<int N>
   395       void AssignLiteral( const char_type (&str)[N] )
   396                   { AssignLiteral(str, N - 1); }
   397 #ifdef CharT_is_PRUnichar
   398       template<int N>
   399       void AssignLiteral( const char (&str)[N] )
   400                   { AssignASCII(str, N-1); }
   401 #endif
   403       self_type& operator=( char_type c )                                                       { Assign(c);        return *this; }
   404       self_type& operator=( const char_type* data )                                             { Assign(data);     return *this; }
   405 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
   406       self_type& operator=( char16ptr_t data )                                                  { Assign(data);     return *this; }
   407 #endif
   408       self_type& operator=( const self_type& str )                                              { Assign(str);      return *this; }
   409       self_type& operator=( const substring_tuple_type& tuple )                                 { Assign(tuple);    return *this; }
   411       void NS_FASTCALL Adopt( char_type* data, size_type length = size_type(-1) );
   414         /**
   415          * buffer manipulation
   416          */
   418       void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, char_type c );
   419       bool NS_FASTCALL Replace( index_type cutStart, size_type cutLength, char_type c, const mozilla::fallible_t&) NS_WARN_UNUSED_RESULT;
   420       void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length = size_type(-1) );
   421       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;
   422       void Replace( index_type cutStart, size_type cutLength, const self_type& str )      { Replace(cutStart, cutLength, str.Data(), str.Length()); }
   423       bool Replace( index_type cutStart, size_type cutLength, const self_type& str, const mozilla::fallible_t&) NS_WARN_UNUSED_RESULT
   424                  { return Replace(cutStart, cutLength, str.Data(), str.Length(), mozilla::fallible_t()); }
   425       void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& tuple );
   427       void NS_FASTCALL ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) );
   429     // ReplaceLiteral must ONLY be applied to an actual literal string.
   430     // Do not attempt to use it with a regular char* pointer, or with a char
   431     // array variable. Use Replace or ReplaceASCII for those.
   432       template<int N>
   433       void ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type (&str)[N] ) { ReplaceLiteral(cutStart, cutLength, str, N - 1); }
   435       void Append( char_type c )                                                                 { Replace(mLength, 0, c); }
   436       bool Append( char_type c, const mozilla::fallible_t&) NS_WARN_UNUSED_RESULT                { return Replace(mLength, 0, c, mozilla::fallible_t()); }
   437       void Append( const char_type* data, size_type length = size_type(-1) )                     { Replace(mLength, 0, data, length); }
   438       bool Append( const char_type* data, size_type length, const mozilla::fallible_t&) NS_WARN_UNUSED_RESULT
   439                  { return Replace(mLength, 0, data, length, mozilla::fallible_t()); }
   441 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
   442     void Append( char16ptr_t data, size_type length = size_type(-1) )                            { Append(static_cast<const char16_t*>(data), length); }
   443 #endif
   445       void Append( const self_type& str )                                                        { Replace(mLength, 0, str); }
   446       void Append( const substring_tuple_type& tuple )                                           { Replace(mLength, 0, tuple); }
   448       void AppendASCII( const char* data, size_type length = size_type(-1) )                     { ReplaceASCII(mLength, 0, data, length); }
   450       /**
   451        * Append a formatted string to the current string. Uses the format
   452        * codes documented in prprf.h
   453        */
   454       void AppendPrintf( const char* format, ... );
   455       void AppendPrintf( const char* format, va_list ap );
   456       void AppendInt( int32_t aInteger )
   457                  { AppendPrintf( "%d", aInteger ); }
   458       void AppendInt( int32_t aInteger, int aRadix )
   459         {
   460           const char *fmt = aRadix == 10 ? "%d" : aRadix == 8 ? "%o" : "%x";
   461           AppendPrintf( fmt, aInteger );
   462         }
   463       void AppendInt( uint32_t aInteger )
   464                  { AppendPrintf( "%u", aInteger ); }
   465       void AppendInt( uint32_t aInteger, int aRadix )
   466         {
   467           const char *fmt = aRadix == 10 ? "%u" : aRadix == 8 ? "%o" : "%x";
   468           AppendPrintf( fmt, aInteger );
   469         }
   470       void AppendInt( int64_t aInteger )
   471                  { AppendPrintf( "%lld", aInteger ); }
   472       void AppendInt( int64_t aInteger, int aRadix )
   473         {
   474           const char *fmt = aRadix == 10 ? "%lld" : aRadix == 8 ? "%llo" : "%llx";
   475           AppendPrintf( fmt, aInteger );
   476         }
   477       void AppendInt( uint64_t aInteger )
   478                  { AppendPrintf( "%llu", aInteger ); }
   479       void AppendInt( uint64_t aInteger, int aRadix )
   480         {
   481           const char *fmt = aRadix == 10 ? "%llu" : aRadix == 8 ? "%llo" : "%llx";
   482           AppendPrintf( fmt, aInteger );
   483         }
   485       /**
   486        * Append the given float to this string 
   487        */
   488       void NS_FASTCALL AppendFloat( float aFloat );
   489       void NS_FASTCALL AppendFloat( double aFloat );
   490   public:
   492     // AppendLiteral must ONLY be applied to an actual literal string.
   493     // Do not attempt to use it with a regular char* pointer, or with a char
   494     // array variable. Use Append or AppendASCII for those.
   495       template<int N>
   496       void AppendLiteral( const char_type (&str)[N] )                                             { ReplaceLiteral(mLength, 0, str, N - 1); }
   497 #ifdef CharT_is_PRUnichar
   498       template<int N>
   499       void AppendLiteral( const char (&str)[N] )
   500                   { AppendASCII(str, N-1); }
   501 #endif
   503       self_type& operator+=( char_type c )                                                       { Append(c);        return *this; }
   504       self_type& operator+=( const char_type* data )                                             { Append(data);     return *this; }
   505 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
   506       self_type& operator+=( char16ptr_t data )                                                  { Append(data);     return *this; }
   507 #endif
   508       self_type& operator+=( const self_type& str )                                              { Append(str);      return *this; }
   509       self_type& operator+=( const substring_tuple_type& tuple )                                 { Append(tuple);    return *this; }
   511       void Insert( char_type c, index_type pos )                                                 { Replace(pos, 0, c); }
   512       void Insert( const char_type* data, index_type pos, size_type length = size_type(-1) )     { Replace(pos, 0, data, length); }
   513 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
   514       void Insert( char16ptr_t data, index_type pos, size_type length = size_type(-1) )
   515         { Insert(static_cast<const char16_t*>(data), pos, length); }
   516 #endif
   517       void Insert( const self_type& str, index_type pos )                                        { Replace(pos, 0, str); }
   518       void Insert( const substring_tuple_type& tuple, index_type pos )                           { Replace(pos, 0, tuple); }
   520     // InsertLiteral must ONLY be applied to an actual literal string.
   521     // Do not attempt to use it with a regular char* pointer, or with a char
   522     // array variable. Use Insert for those.
   523       template<int N>
   524       void InsertLiteral( const char_type (&str)[N], index_type pos )                            { ReplaceLiteral(pos, 0, str, N - 1); }
   526       void Cut( index_type cutStart, size_type cutLength )                                       { Replace(cutStart, cutLength, char_traits::sEmptyBuffer, 0); }
   529         /**
   530          * buffer sizing
   531          */
   533         /**
   534          * Attempts to set the capacity to the given size in number of 
   535          * characters, without affecting the length of the string.
   536          * There is no need to include room for the null terminator: it is
   537          * the job of the string class.
   538          * Also ensures that the buffer is mutable.
   539          */
   540       void NS_FASTCALL SetCapacity( size_type newCapacity );
   541       bool NS_FASTCALL SetCapacity( size_type newCapacity, const fallible_t& ) NS_WARN_UNUSED_RESULT;
   543       void NS_FASTCALL SetLength( size_type newLength );
   544       bool NS_FASTCALL SetLength( size_type newLength, const fallible_t& ) NS_WARN_UNUSED_RESULT;
   546       void Truncate( size_type newLength = 0 )
   547         {
   548           NS_ASSERTION(newLength <= mLength, "Truncate cannot make string longer");
   549           SetLength(newLength);
   550         }
   553         /**
   554          * buffer access
   555          */
   558         /**
   559          * Get a const pointer to the string's internal buffer.  The caller
   560          * MUST NOT modify the characters at the returned address.
   561          *
   562          * @returns The length of the buffer in characters.
   563          */
   564       inline size_type GetData( const char_type** data ) const
   565         {
   566           *data = mData;
   567           return mLength;
   568         }
   570         /**
   571          * Get a pointer to the string's internal buffer, optionally resizing
   572          * the buffer first.  If size_type(-1) is passed for newLen, then the
   573          * current length of the string is used.  The caller MAY modify the
   574          * characters at the returned address (up to but not exceeding the
   575          * length of the string).
   576          *
   577          * @returns The length of the buffer in characters or 0 if unable to
   578          * satisfy the request due to low-memory conditions.
   579          */
   580       size_type GetMutableData( char_type** data, size_type newLen = size_type(-1) )
   581         {
   582           if (!EnsureMutable(newLen))
   583             NS_ABORT_OOM(newLen == size_type(-1) ? mLength : newLen);
   585           *data = mData;
   586           return mLength;
   587         }
   589       size_type GetMutableData( char_type** data, size_type newLen, const fallible_t& )
   590         {
   591           if (!EnsureMutable(newLen))
   592             {
   593               *data = nullptr;
   594               return 0;
   595             }
   597           *data = mData;
   598           return mLength;
   599         }
   601 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
   602       size_type GetMutableData( wchar_t** data, size_type newLen = size_type(-1) )
   603         {
   604           return GetMutableData(reinterpret_cast<char16_t**>(data), newLen);
   605         }
   607       size_type GetMutableData( wchar_t** data, size_type newLen, const fallible_t& )
   608         {
   609     return GetMutableData(reinterpret_cast<char16_t**>(data), newLen, fallible_t());
   610         }
   611 #endif
   614         /**
   615          * string data is never null, but can be marked void.  if true, the
   616          * string will be truncated.  @see nsTSubstring::IsVoid
   617          */
   619       void NS_FASTCALL SetIsVoid( bool );
   621         /**
   622          *  This method is used to remove all occurrences of aChar from this
   623          * string.
   624          *  
   625          *  @param  aChar -- char to be stripped
   626          *  @param  aOffset -- where in this string to start stripping chars
   627          */
   629       void StripChar( char_type aChar, int32_t aOffset=0 );
   631         /**
   632          *  This method is used to remove all occurrences of aChars from this
   633          * string.
   634          *
   635          *  @param  aChars -- chars to be stripped
   636          *  @param  aOffset -- where in this string to start stripping chars
   637          */
   639       void StripChars( const char_type* aChars, uint32_t aOffset=0 );
   641         /**
   642          * If the string uses a shared buffer, this method
   643          * clears the pointer without releasing the buffer.
   644          */
   645       void ForgetSharedBuffer()
   646       {
   647         if (mFlags & nsSubstring::F_SHARED)
   648           {
   649             mData = char_traits::sEmptyBuffer;
   650             mLength = 0;
   651             mFlags = F_TERMINATED;
   652           }
   653       }
   655     public:
   657         /**
   658          * this is public to support automatic conversion of tuple to string
   659          * base type, which helps avoid converting to nsTAString.
   660          */
   661       nsTSubstring_CharT(const substring_tuple_type& tuple)
   662         : mData(nullptr),
   663           mLength(0),
   664           mFlags(F_NONE)
   665         {
   666           Assign(tuple);
   667         }
   669         /**
   670          * allows for direct initialization of a nsTSubstring object. 
   671          *
   672          * NOTE: this constructor is declared public _only_ for convenience
   673          * inside the string implementation.
   674          */
   675         // XXXbz or can I just include nscore.h and use NS_BUILD_REFCNT_LOGGING?
   676 #if defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING)
   677 #define XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
   678       nsTSubstring_CharT( char_type *data, size_type length, uint32_t flags );
   679 #else
   680 #undef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
   681       nsTSubstring_CharT( char_type *data, size_type length, uint32_t flags )
   682         : mData(data),
   683           mLength(length),
   684           mFlags(flags) {}
   685 #endif /* DEBUG || FORCE_BUILD_REFCNT_LOGGING */
   687       size_t SizeOfExcludingThisMustBeUnshared(mozilla::MallocSizeOf mallocSizeOf)
   688         const;
   689       size_t SizeOfIncludingThisMustBeUnshared(mozilla::MallocSizeOf mallocSizeOf)
   690         const;
   692       size_t SizeOfExcludingThisIfUnshared(mozilla::MallocSizeOf mallocSizeOf)
   693         const;
   694       size_t SizeOfIncludingThisIfUnshared(mozilla::MallocSizeOf mallocSizeOf)
   695         const;
   697         /**
   698          * WARNING: Only use these functions if you really know what you are
   699          * doing, because they can easily lead to double-counting strings.  If
   700          * you do use them, please explain clearly in a comment why it's safe
   701          * and won't lead to double-counting.
   702          */
   703       size_t SizeOfExcludingThisEvenIfShared(mozilla::MallocSizeOf mallocSizeOf)
   704         const;
   705       size_t SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf mallocSizeOf)
   706         const;
   708     protected:
   710       friend class nsTObsoleteAStringThunk_CharT;
   711       friend class nsTSubstringTuple_CharT;
   713       // XXX GCC 3.4 needs this :-(
   714       friend class nsTPromiseFlatString_CharT;
   716       char_type*  mData;
   717       size_type   mLength;
   718       uint32_t    mFlags;
   720         // default initialization 
   721       nsTSubstring_CharT()
   722         : mData(char_traits::sEmptyBuffer),
   723           mLength(0),
   724           mFlags(F_TERMINATED) {}
   726         // version of constructor that leaves mData and mLength uninitialized
   727       explicit
   728       nsTSubstring_CharT( uint32_t flags )
   729         : mFlags(flags) {}
   731         // copy-constructor, constructs as dependent on given object
   732         // (NOTE: this is for internal use only)
   733       nsTSubstring_CharT( const self_type& str )
   734         : mData(str.mData),
   735           mLength(str.mLength),
   736           mFlags(str.mFlags & (F_TERMINATED | F_VOIDED)) {}
   738         /**
   739          * this function releases mData and does not change the value of
   740          * any of its member variables.  in other words, this function acts
   741          * like a destructor.
   742          */
   743       void NS_FASTCALL Finalize();
   745         /**
   746          * this function prepares mData to be mutated.
   747          *
   748          * @param capacity     specifies the required capacity of mData  
   749          * @param old_data     returns null or the old value of mData
   750          * @param old_flags    returns 0 or the old value of mFlags
   751          *
   752          * if mData is already mutable and of sufficient capacity, then this
   753          * function will return immediately.  otherwise, it will either resize
   754          * mData or allocate a new shared buffer.  if it needs to allocate a
   755          * new buffer, then it will return the old buffer and the corresponding
   756          * flags.  this allows the caller to decide when to free the old data.
   757          *
   758          * this function returns false if is unable to allocate sufficient
   759          * memory.
   760          *
   761          * XXX we should expose a way for subclasses to free old_data.
   762          */
   763       bool NS_FASTCALL MutatePrep( size_type capacity, char_type** old_data, uint32_t* old_flags );
   765         /**
   766          * this function prepares a section of mData to be modified.  if
   767          * necessary, this function will reallocate mData and possibly move
   768          * existing data to open up the specified section.
   769          *
   770          * @param cutStart     specifies the starting offset of the section
   771          * @param cutLength    specifies the length of the section to be replaced
   772          * @param newLength    specifies the length of the new section
   773          *
   774          * for example, suppose mData contains the string "abcdef" then
   775          * 
   776          *   ReplacePrep(2, 3, 4);
   777          *
   778          * would cause mData to look like "ab____f" where the characters
   779          * indicated by '_' have an unspecified value and can be freely
   780          * modified.  this function will null-terminate mData upon return.
   781          * 
   782          * this function returns false if is unable to allocate sufficient
   783          * memory.
   784          */
   785       bool ReplacePrep(index_type cutStart, size_type cutLength,
   786                        size_type newLength) NS_WARN_UNUSED_RESULT
   787       {
   788         cutLength = XPCOM_MIN(cutLength, mLength - cutStart);
   789         uint32_t newTotalLen = mLength - cutLength + newLength;
   790         if (cutStart == mLength && Capacity() > newTotalLen) {
   791           mFlags &= ~F_VOIDED;
   792           mData[newTotalLen] = char_type(0);
   793           mLength = newTotalLen;
   794           return true;
   795         }
   796         return ReplacePrepInternal(cutStart, cutLength, newLength, newTotalLen);
   797       }
   799       bool NS_FASTCALL ReplacePrepInternal(index_type cutStart,
   800                                            size_type cutLength,
   801                                            size_type newFragLength,
   802                                            size_type newTotalLength)
   803         NS_WARN_UNUSED_RESULT;
   805         /**
   806          * returns the number of writable storage units starting at mData.
   807          * the value does not include space for the null-terminator character.
   808          *
   809          * NOTE: this function returns 0 if mData is immutable (or the buffer
   810          *       is 0-sized).
   811          */
   812       size_type NS_FASTCALL Capacity() const;
   814         /**
   815          * this helper function can be called prior to directly manipulating
   816          * the contents of mData.  see, for example, BeginWriting.
   817          */
   818       bool NS_FASTCALL EnsureMutable( size_type newLen = size_type(-1) ) NS_WARN_UNUSED_RESULT;
   820         /**
   821          * returns true if this string overlaps with the given string fragment.
   822          */
   823       bool IsDependentOn( const char_type *start, const char_type *end ) const
   824         {
   825           /**
   826            * if it _isn't_ the case that one fragment starts after the other ends,
   827            * or ends before the other starts, then, they conflict:
   828            * 
   829            *   !(f2.begin >= f1.end || f2.end <= f1.begin)
   830            * 
   831            * Simplified, that gives us:
   832            */
   833           return ( start < (mData + mLength) && end > mData );
   834         }
   836         /**
   837          * this helper function stores the specified dataFlags in mFlags
   838          */
   839       void SetDataFlags(uint32_t dataFlags)
   840         {
   841           NS_ASSERTION((dataFlags & 0xFFFF0000) == 0, "bad flags");
   842           mFlags = dataFlags | (mFlags & 0xFFFF0000);
   843         }
   845       void NS_FASTCALL ReplaceLiteral( index_type cutStart, size_type cutLength, const char_type* data, size_type length );
   847       static int AppendFunc( void* arg, const char* s, uint32_t len);
   849     public:
   851       // NOTE: this method is declared public _only_ for convenience for
   852       // callers who don't have access to the original nsLiteralString_CharT.
   853       void NS_FASTCALL AssignLiteral( const char_type* data, size_type length );
   855       // mFlags is a bitwise combination of the following flags.  the meaning
   856       // and interpretation of these flags is an implementation detail.
   857       // 
   858       // NOTE: these flags are declared public _only_ for convenience inside
   859       // the string implementation.
   861       enum
   862         {
   863           F_NONE         = 0,       // no flags
   865           // data flags are in the lower 16-bits
   866           F_TERMINATED   = 1 << 0,  // IsTerminated returns true
   867           F_VOIDED       = 1 << 1,  // IsVoid returns true
   868           F_SHARED       = 1 << 2,  // mData points to a heap-allocated, shared buffer
   869           F_OWNED        = 1 << 3,  // mData points to a heap-allocated, raw buffer
   870           F_FIXED        = 1 << 4,  // mData points to a fixed-size writable, dependent buffer
   871           F_LITERAL      = 1 << 5,  // mData points to a string literal; F_TERMINATED will also be set
   873           // class flags are in the upper 16-bits
   874           F_CLASS_FIXED  = 1 << 16   // indicates that |this| is of type nsTFixedString
   875         };
   877       //
   878       // Some terminology:
   879       //
   880       //   "dependent buffer"    A dependent buffer is one that the string class
   881       //                         does not own.  The string class relies on some
   882       //                         external code to ensure the lifetime of the
   883       //                         dependent buffer.
   884       //
   885       //   "shared buffer"       A shared buffer is one that the string class
   886       //                         allocates.  When it allocates a shared string
   887       //                         buffer, it allocates some additional space at
   888       //                         the beginning of the buffer for additional 
   889       //                         fields, including a reference count and a 
   890       //                         buffer length.  See nsStringHeader.
   891       //                         
   892       //   "adopted buffer"      An adopted buffer is a raw string buffer
   893       //                         allocated on the heap (using nsMemory::Alloc)
   894       //                         of which the string class subsumes ownership.
   895       //
   896       // Some comments about the string flags:
   897       //
   898       //   F_SHARED, F_OWNED, and F_FIXED are all mutually exlusive.  They
   899       //   indicate the allocation type of mData.  If none of these flags
   900       //   are set, then the string buffer is dependent.
   901       //
   902       //   F_SHARED, F_OWNED, or F_FIXED imply F_TERMINATED.  This is because
   903       //   the string classes always allocate null-terminated buffers, and
   904       //   non-terminated substrings are always dependent.
   905       //
   906       //   F_VOIDED implies F_TERMINATED, and moreover it implies that mData
   907       //   points to char_traits::sEmptyBuffer.  Therefore, F_VOIDED is
   908       //   mutually exclusive with F_SHARED, F_OWNED, and F_FIXED.
   909       //
   910   };
   912 int NS_FASTCALL Compare( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs, const nsTStringComparator_CharT& = nsTDefaultStringComparator_CharT() );
   915 inline
   916 bool operator!=( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
   917   {
   918     return !lhs.Equals(rhs);
   919   }
   921 inline
   922 bool operator< ( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
   923   {
   924     return Compare(lhs, rhs)< 0;
   925   }
   927 inline
   928 bool operator<=( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
   929   {
   930     return Compare(lhs, rhs)<=0;
   931   }
   933 inline
   934 bool operator==( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
   935   {
   936     return lhs.Equals(rhs);
   937   }
   939 inline
   940 bool operator==( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::char_type* rhs )
   941   {
   942     return lhs.Equals(rhs);
   943   }
   946 inline
   947 bool operator>=( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
   948   {
   949     return Compare(lhs, rhs)>=0;
   950   }
   952 inline
   953 bool operator> ( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
   954   {
   955     return Compare(lhs, rhs)> 0;
   956   }

mercurial