Back to index

lightning-sunbird  0.9+nobinonly
nsTSubstring.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* vim:set ts=2 sw=2 sts=2 et cindent: */
00003 /* ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is Mozilla.
00017  *
00018  * The Initial Developer of the Original Code is IBM Corporation.
00019  * Portions created by IBM Corporation are Copyright (C) 2003
00020  * IBM Corporation. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Darin Fisher <darin@meer.net>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 
00055 class nsTSubstring_CharT : public nsTAString_CharT
00056   {
00057     public:
00058 
00059       typedef nsTSubstring_CharT    self_type;
00060       typedef nsTString_CharT       string_type;
00061 
00062       typedef char_type*            char_iterator;
00063       typedef const char_type*      const_char_iterator;
00064 
00065 #ifdef MOZ_V1_STRING_ABI
00066       typedef nsTAString_CharT      base_string_type;
00067 #else
00068       typedef nsTSubstring_CharT    base_string_type;
00069 #endif
00070 
00071     public:
00072 
00073 #ifndef MOZ_V1_STRING_ABI
00074         // this acts like a virtual destructor
00075       NS_COM NS_FASTCALL ~nsTSubstring_CharT();
00076 #endif
00077 
00082       const_char_iterator BeginReading() const { return mData; }
00083       const_char_iterator EndReading() const { return mData + mLength; }
00084 
00089       const_iterator& BeginReading( const_iterator& iter ) const
00090         {
00091           iter.mStart = mData;
00092           iter.mEnd = mData + mLength;
00093           iter.mPosition = iter.mStart;
00094           return iter;
00095         }
00096 
00097       const_iterator& EndReading( const_iterator& iter ) const
00098         {
00099           iter.mStart = mData;
00100           iter.mEnd = mData + mLength;
00101           iter.mPosition = iter.mEnd;
00102           return iter;
00103         }
00104 
00105       const_char_iterator& BeginReading( const_char_iterator& iter ) const
00106         {
00107           return iter = mData;
00108         }
00109 
00110       const_char_iterator& EndReading( const_char_iterator& iter ) const
00111         {
00112           return iter = mData + mLength;
00113         }
00114 
00115 
00120       char_iterator BeginWriting() { EnsureMutable(); return mData; }
00121       char_iterator EndWriting() { EnsureMutable(); return mData + mLength; }
00122 
00127       iterator& BeginWriting( iterator& iter )
00128         {
00129           EnsureMutable();
00130           iter.mStart = mData;
00131           iter.mEnd = mData + mLength;
00132           iter.mPosition = iter.mStart;
00133           return iter;
00134         }
00135 
00136       iterator& EndWriting( iterator& iter )
00137         {
00138           EnsureMutable();
00139           iter.mStart = mData;
00140           iter.mEnd = mData + mLength;
00141           iter.mPosition = iter.mEnd;
00142           return iter;
00143         }
00144 
00145       char_iterator& BeginWriting( char_iterator& iter )
00146         {
00147           EnsureMutable();
00148           return iter = mData;
00149         }
00150 
00151       char_iterator& EndWriting( char_iterator& iter )
00152         {
00153           EnsureMutable();
00154           return iter = mData + mLength;
00155         }
00156 
00157 
00162         // returns pointer to string data (not necessarily null-terminated)
00163       const char_type *Data() const
00164         {
00165           return mData;
00166         }
00167 
00168       size_type Length() const
00169         {
00170           return mLength;
00171         }
00172 
00173       PRBool IsEmpty() const
00174         {
00175           return mLength == 0;
00176         }
00177 
00178       PRBool IsVoid() const
00179         {
00180           return mFlags & F_VOIDED;
00181         }
00182 
00183       PRBool IsTerminated() const
00184         {
00185           return mFlags & F_TERMINATED;
00186         }
00187 
00188       char_type CharAt( index_type i ) const
00189         {
00190           NS_ASSERTION(i < mLength, "index exceeds allowable range");
00191           return mData[i];
00192         }
00193 
00194       char_type operator[]( index_type i ) const
00195         {
00196           return CharAt(i);
00197         }
00198 
00199       char_type First() const
00200         {
00201           NS_ASSERTION(mLength > 0, "|First()| called on an empty string");
00202           return mData[0];
00203         }
00204 
00205       inline
00206       char_type Last() const
00207         {
00208           NS_ASSERTION(mLength > 0, "|Last()| called on an empty string");
00209           return mData[mLength - 1];
00210         }
00211 
00212       NS_COM size_type NS_FASTCALL CountChar( char_type ) const;
00213       NS_COM PRInt32 NS_FASTCALL FindChar( char_type, index_type offset = 0 ) const;
00214 
00215 
00220       NS_COM PRBool NS_FASTCALL Equals( const self_type& ) const;
00221       NS_COM PRBool NS_FASTCALL Equals( const self_type&, const comparator_type& ) const;
00222 
00223 #ifdef MOZ_V1_STRING_ABI
00224       NS_COM PRBool NS_FASTCALL Equals( const abstract_string_type& readable ) const;
00225       NS_COM PRBool NS_FASTCALL Equals( const abstract_string_type& readable, const comparator_type& comp ) const;
00226 #endif
00227 
00228       NS_COM PRBool NS_FASTCALL Equals( const char_type* data ) const;
00229       NS_COM PRBool NS_FASTCALL Equals( const char_type* data, const comparator_type& comp ) const;
00230 
00236       NS_COM PRBool NS_FASTCALL EqualsASCII( const char* data, size_type len ) const;
00242       NS_COM PRBool NS_FASTCALL EqualsASCII( const char* data ) const;
00243 
00244     // EqualsLiteral must ONLY be applied to an actual literal string.
00245     // Do not attempt to use it with a regular char* pointer, or with a char
00246     // array variable.
00247     // The template trick to acquire the array length at compile time without
00248     // using a macro is due to Corey Kosak, with much thanks.
00249 #ifdef NS_DISABLE_LITERAL_TEMPLATE
00250       inline PRBool EqualsLiteral( const char* str ) const
00251         {
00252           return EqualsASCII(str);
00253         }
00254 #else
00255       template<int N>
00256       inline PRBool EqualsLiteral( const char (&str)[N] ) const
00257         {
00258           return EqualsASCII(str, N-1);
00259         }
00260       template<int N>
00261       inline PRBool EqualsLiteral( char (&str)[N] ) const
00262         {
00263           const char* s = str;
00264           return EqualsASCII(s, N-1);
00265         }
00266 #endif
00267 
00268     // The LowerCaseEquals methods compare the lower case version of
00269     // this string to some ASCII/Literal string. The ASCII string is
00270     // *not* lowercased for you. If you compare to an ASCII or literal
00271     // string that contains an uppercase character, it is guaranteed to
00272     // return false. We will throw assertions too.
00273       NS_COM PRBool NS_FASTCALL LowerCaseEqualsASCII( const char* data, size_type len ) const;
00274       NS_COM PRBool NS_FASTCALL LowerCaseEqualsASCII( const char* data ) const;
00275 
00276     // LowerCaseEqualsLiteral must ONLY be applied to an actual
00277     // literal string.  Do not attempt to use it with a regular char*
00278     // pointer, or with a char array variable. Use
00279     // LowerCaseEqualsASCII for them.
00280 #ifdef NS_DISABLE_LITERAL_TEMPLATE
00281       inline PRBool LowerCaseEqualsLiteral( const char* str ) const
00282         {
00283           return LowerCaseEqualsASCII(str);
00284         }
00285 #else
00286       template<int N>
00287       inline PRBool LowerCaseEqualsLiteral( const char (&str)[N] ) const
00288         {
00289           return LowerCaseEqualsASCII(str, N-1);
00290         }
00291       template<int N>
00292       inline PRBool LowerCaseEqualsLiteral( char (&str)[N] ) const
00293         {
00294           const char* s = str;
00295           return LowerCaseEqualsASCII(s, N-1);
00296         }
00297 #endif
00298 
00303       void Assign( char_type c )                                                                { Assign(&c, 1); }
00304       NS_COM void NS_FASTCALL Assign( const char_type* data, size_type length = size_type(-1) );
00305       NS_COM void NS_FASTCALL Assign( const self_type& );
00306       NS_COM void NS_FASTCALL Assign( const substring_tuple_type& );
00307 #ifdef MOZ_V1_STRING_ABI
00308       NS_COM void NS_FASTCALL Assign( const abstract_string_type& );
00309 #endif
00310 
00311       NS_COM void NS_FASTCALL AssignASCII( const char* data, size_type length );
00312       NS_COM void NS_FASTCALL AssignASCII( const char* data );
00313 
00314     // AssignLiteral must ONLY be applied to an actual literal string.
00315     // Do not attempt to use it with a regular char* pointer, or with a char
00316     // array variable. Use AssignASCII for those.
00317 #ifdef NS_DISABLE_LITERAL_TEMPLATE
00318       void AssignLiteral( const char* str )
00319                   { AssignASCII(str); }
00320 #else
00321       template<int N>
00322       void AssignLiteral( const char (&str)[N] )
00323                   { AssignASCII(str, N-1); }
00324       template<int N>
00325       void AssignLiteral( char (&str)[N] )
00326                   { AssignASCII(str, N-1); }
00327 #endif
00328 
00329       self_type& operator=( char_type c )                                                       { Assign(c);        return *this; }
00330       self_type& operator=( const char_type* data )                                             { Assign(data);     return *this; }
00331       self_type& operator=( const self_type& str )                                              { Assign(str);      return *this; }
00332       self_type& operator=( const substring_tuple_type& tuple )                                 { Assign(tuple);    return *this; }
00333 #ifdef MOZ_V1_STRING_ABI
00334       self_type& operator=( const abstract_string_type& readable )                              { Assign(readable); return *this; }
00335 #endif
00336 
00337       NS_COM void NS_FASTCALL Adopt( char_type* data, size_type length = size_type(-1) );
00338 
00339 
00344              void Replace( index_type cutStart, size_type cutLength, char_type c )               { Replace(cutStart, cutLength, &c, 1); }
00345       NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length = size_type(-1) );
00346              void Replace( index_type cutStart, size_type cutLength, const self_type& str )      { Replace(cutStart, cutLength, str.Data(), str.Length()); }
00347       NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& tuple );
00348 #ifdef MOZ_V1_STRING_ABI
00349       NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const abstract_string_type& readable );
00350 #endif
00351 
00352       NS_COM void NS_FASTCALL ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) );
00353 
00354       void Append( char_type c )                                                                 { Replace(mLength, 0, c); }
00355       void Append( const char_type* data, size_type length = size_type(-1) )                     { Replace(mLength, 0, data, length); }
00356       void Append( const self_type& str )                                                        { Replace(mLength, 0, str); }
00357       void Append( const substring_tuple_type& tuple )                                           { Replace(mLength, 0, tuple); }
00358 #ifdef MOZ_V1_STRING_ABI
00359       void Append( const abstract_string_type& readable )                                        { Replace(mLength, 0, readable); }
00360 #endif
00361 
00362       void AppendASCII( const char* data, size_type length = size_type(-1) )                     { ReplaceASCII(mLength, 0, data, length); }
00363 
00364     // AppendLiteral must ONLY be applied to an actual literal string.
00365     // Do not attempt to use it with a regular char* pointer, or with a char
00366     // array variable. Use AppendASCII for those.
00367 #ifdef NS_DISABLE_LITERAL_TEMPLATE
00368       void AppendLiteral( const char* str )
00369                   { AppendASCII(str); }
00370 #else
00371       template<int N>
00372       void AppendLiteral( const char (&str)[N] )
00373                   { AppendASCII(str, N-1); }
00374       template<int N>
00375       void AppendLiteral( char (&str)[N] )
00376                   { AppendASCII(str, N-1); }
00377 #endif
00378 
00379       self_type& operator+=( char_type c )                                                       { Append(c);        return *this; }
00380       self_type& operator+=( const char_type* data )                                             { Append(data);     return *this; }
00381       self_type& operator+=( const self_type& str )                                              { Append(str);      return *this; }
00382       self_type& operator+=( const substring_tuple_type& tuple )                                 { Append(tuple);    return *this; }
00383 #ifdef MOZ_V1_STRING_ABI
00384       self_type& operator+=( const abstract_string_type& readable )                              { Append(readable); return *this; }
00385 #endif
00386 
00387       void Insert( char_type c, index_type pos )                                                 { Replace(pos, 0, c); }
00388       void Insert( const char_type* data, index_type pos, size_type length = size_type(-1) )     { Replace(pos, 0, data, length); }
00389       void Insert( const self_type& str, index_type pos )                                        { Replace(pos, 0, str); }
00390       void Insert( const substring_tuple_type& tuple, index_type pos )                           { Replace(pos, 0, tuple); }
00391 #ifdef MOZ_V1_STRING_ABI
00392       void Insert( const abstract_string_type& readable, index_type pos )                        { Replace(pos, 0, readable); }
00393 #endif
00394 
00395       void Cut( index_type cutStart, size_type cutLength )                                       { Replace(cutStart, cutLength, char_traits::sEmptyBuffer, 0); }
00396 
00397 
00402       NS_COM void NS_FASTCALL SetCapacity( size_type capacity );
00403 
00404       NS_COM void NS_FASTCALL SetLength( size_type );
00405 
00406       void Truncate( size_type newLength = 0 )
00407         {
00408           NS_ASSERTION(newLength <= mLength, "Truncate cannot make string longer");
00409           SetLength(newLength);
00410         }
00411 
00412 
00418       NS_COM void NS_FASTCALL SetIsVoid( PRBool );
00419 
00428       NS_COM void StripChar( char_type aChar, PRInt32 aOffset=0 );
00429 
00430 
00431     public:
00432 
00437       nsTSubstring_CharT(const substring_tuple_type& tuple)
00438 #ifdef MOZ_V1_STRING_ABI
00439         : abstract_string_type(nsnull, 0, F_NONE)
00440 #else
00441         : mData(nsnull),
00442           mLength(0),
00443           mFlags(F_NONE)
00444 #endif
00445         {
00446           Assign(tuple);
00447         }
00448 
00455       nsTSubstring_CharT( char_type *data, size_type length, PRUint32 flags )
00456 #ifdef MOZ_V1_STRING_ABI
00457         : abstract_string_type(data, length, flags) {}
00458 #else
00459         : mData(data),
00460           mLength(length),
00461           mFlags(flags) {}
00462 #endif
00463 
00464 
00465     protected:
00466 
00467       friend class nsTObsoleteAStringThunk_CharT;
00468       friend class nsTAString_CharT;
00469       friend class nsTSubstringTuple_CharT;
00470 
00471       // XXX GCC 3.4 needs this :-(
00472       friend class nsTPromiseFlatString_CharT;
00473 
00474 #ifndef MOZ_V1_STRING_ABI
00475       char_type*  mData;
00476       size_type   mLength;
00477       PRUint32    mFlags;
00478 #endif
00479 
00480         // default initialization 
00481       nsTSubstring_CharT()
00482 #ifdef MOZ_V1_STRING_ABI
00483         : abstract_string_type(
00484               NS_CONST_CAST(char_type*, char_traits::sEmptyBuffer), 0, F_TERMINATED) {}
00485 #else
00486         : mData(NS_CONST_CAST(char_type*, char_traits::sEmptyBuffer)),
00487           mLength(0),
00488           mFlags(F_TERMINATED) {}
00489 #endif
00490 
00491         // version of constructor that leaves mData and mLength uninitialized
00492       explicit
00493       nsTSubstring_CharT( PRUint32 flags )
00494 #ifdef MOZ_V1_STRING_ABI
00495         : abstract_string_type(flags) {}
00496 #else
00497         : mFlags(flags) {}
00498 #endif
00499 
00500         // copy-constructor, constructs as dependent on given object
00501         // (NOTE: this is for internal use only)
00502       nsTSubstring_CharT( const self_type& str )
00503 #ifdef MOZ_V1_STRING_ABI
00504         : abstract_string_type(str.mData, str.mLength, str.mFlags & (F_TERMINATED | F_VOIDED)) {}
00505 #else
00506         : mData(str.mData),
00507           mLength(str.mLength),
00508           mFlags(str.mFlags & (F_TERMINATED | F_VOIDED)) {}
00509 #endif
00510 
00516       void NS_FASTCALL Finalize();
00517 
00536       PRBool NS_FASTCALL MutatePrep( size_type capacity, char_type** old_data, PRUint32* old_flags );
00537 
00558       PRBool NS_FASTCALL ReplacePrep( index_type cutStart, size_type cutLength, size_type newLength );
00559 
00566       size_type NS_FASTCALL Capacity() const;
00567 
00572       NS_COM void NS_FASTCALL EnsureMutable();
00573 
00577       PRBool IsDependentOn( const char_type *start, const char_type *end ) const
00578         {
00587           return ( start < (mData + mLength) && end > mData );
00588         }
00589 
00593       void SetDataFlags(PRUint32 dataFlags)
00594         {
00595           NS_ASSERTION((dataFlags & 0xFFFF0000) == 0, "bad flags");
00596           mFlags = dataFlags | (mFlags & 0xFFFF0000);
00597         }
00598 
00599     public:
00600 
00601       // mFlags is a bitwise combination of the following flags.  the meaning
00602       // and interpretation of these flags is an implementation detail.
00603       // 
00604       // NOTE: these flags are declared public _only_ for convenience inside
00605       // the string implementation.
00606       
00607       enum
00608         {
00609           F_NONE         = 0,       // no flags
00610 
00611           // data flags are in the lower 16-bits
00612           F_TERMINATED   = 1 << 0,  // IsTerminated returns true
00613           F_VOIDED       = 1 << 1,  // IsVoid returns true
00614           F_SHARED       = 1 << 2,  // mData points to a heap-allocated, shared buffer
00615           F_OWNED        = 1 << 3,  // mData points to a heap-allocated, raw buffer
00616           F_FIXED        = 1 << 4,  // mData points to a fixed-size writable, dependent buffer
00617 
00618           // class flags are in the upper 16-bits
00619           F_CLASS_FIXED  = 1 << 16   // indicates that |this| is of type nsTFixedString
00620         };
00621 
00622       //
00623       // Some terminology:
00624       //
00625       //   "dependent buffer"    A dependent buffer is one that the string class
00626       //                         does not own.  The string class relies on some
00627       //                         external code to ensure the lifetime of the
00628       //                         dependent buffer.
00629       //
00630       //   "shared buffer"       A shared buffer is one that the string class
00631       //                         allocates.  When it allocates a shared string
00632       //                         buffer, it allocates some additional space at
00633       //                         the beginning of the buffer for additional 
00634       //                         fields, including a reference count and a 
00635       //                         buffer length.  See nsStringHeader.
00636       //                         
00637       //   "adopted buffer"      An adopted buffer is a raw string buffer
00638       //                         allocated on the heap (using nsMemory::Alloc)
00639       //                         of which the string class subsumes ownership.
00640       //
00641       // Some comments about the string flags:
00642       //
00643       //   F_SHARED, F_OWNED, and F_FIXED are all mutually exlusive.  They
00644       //   indicate the allocation type of mData.  If none of these flags
00645       //   are set, then the string buffer is dependent.
00646       //
00647       //   F_SHARED, F_OWNED, or F_FIXED imply F_TERMINATED.  This is because
00648       //   the string classes always allocate null-terminated buffers, and
00649       //   non-terminated substrings are always dependent.
00650       //
00651       //   F_VOIDED implies F_TERMINATED, and moreover it implies that mData
00652       //   points to char_traits::sEmptyBuffer.  Therefore, F_VOIDED is
00653       //   mutually exclusive with F_SHARED, F_OWNED, and F_FIXED.
00654       //
00655   };
00656 
00657 NS_COM
00658 int NS_FASTCALL Compare( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs, const nsTStringComparator_CharT& = nsTDefaultStringComparator_CharT() );
00659 
00660 
00661 inline
00662 PRBool operator!=( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
00663   {
00664     return !lhs.Equals(rhs);
00665   }
00666 
00667 inline
00668 PRBool operator< ( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
00669   {
00670     return Compare(lhs, rhs)< 0;
00671   }
00672 
00673 inline
00674 PRBool operator<=( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
00675   {
00676     return Compare(lhs, rhs)<=0;
00677   }
00678 
00679 inline
00680 PRBool operator==( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
00681   {
00682     return lhs.Equals(rhs);
00683   }
00684 
00685 inline
00686 PRBool operator>=( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
00687   {
00688     return Compare(lhs, rhs)>=0;
00689   }
00690 
00691 inline
00692 PRBool operator> ( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
00693   {
00694     return Compare(lhs, rhs)> 0;
00695   }