Bug 452317 - FeedConverter.js: QueryInterface should throw NS_ERROR_NO_INTERFACE...
[wine-gecko.git] / xpcom / string / public / nsTSubstring.h
blobbc4fa05c85033626fb41c90a25e8c1dee8ac4e95
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 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is Mozilla.
18 * The Initial Developer of the Original Code is IBM Corporation.
19 * Portions created by IBM Corporation are Copyright (C) 2003
20 * IBM Corporation. All Rights Reserved.
22 * Contributor(s):
23 * Darin Fisher <darin@meer.net>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #ifndef MOZILLA_INTERNAL_API
40 #error Cannot use internal string classes without MOZILLA_INTERNAL_API defined. Use the frozen header nsStringAPI.h instead.
41 #endif
43 /**
44 * The base for string comparators
46 class NS_COM nsTStringComparator_CharT
48 public:
49 typedef CharT char_type;
51 nsTStringComparator_CharT() {}
53 virtual int operator()( const char_type*, const char_type*, PRUint32 length ) const = 0;
54 virtual int operator()( char_type, char_type ) const = 0;
58 /**
59 * The default string comparator (case-sensitive comparision)
61 class NS_COM nsTDefaultStringComparator_CharT
62 : public nsTStringComparator_CharT
64 public:
65 typedef CharT char_type;
67 nsTDefaultStringComparator_CharT() {}
69 virtual int operator()( const char_type*, const char_type*, PRUint32 length ) const;
70 virtual int operator()( char_type, char_type ) const;
73 /**
74 * nsTSubstring is the most abstract class in the string hierarchy. It
75 * represents a single contiguous array of characters, which may or may not
76 * be null-terminated. This type is not instantiated directly. A sub-class
77 * is instantiated instead. For example, see nsTString.
79 * NAMES:
80 * nsAString for wide characters
81 * nsACString for narrow characters
83 * Many of the accessors on nsTSubstring are inlined as an optimization.
85 class nsTSubstring_CharT
87 public:
88 typedef CharT char_type;
90 typedef nsCharTraits<char_type> char_traits;
91 typedef char_traits::incompatible_char_type incompatible_char_type;
93 typedef nsTSubstring_CharT self_type;
94 typedef self_type abstract_string_type;
95 typedef self_type base_string_type;
97 typedef self_type substring_type;
98 typedef nsTSubstringTuple_CharT substring_tuple_type;
99 typedef nsTString_CharT string_type;
101 typedef nsReadingIterator<char_type> const_iterator;
102 typedef nsWritingIterator<char_type> iterator;
104 typedef nsTStringComparator_CharT comparator_type;
106 typedef char_type* char_iterator;
107 typedef const char_type* const_char_iterator;
109 typedef PRUint32 size_type;
110 typedef PRUint32 index_type;
112 public:
114 // this acts like a virtual destructor
115 NS_COM NS_CONSTRUCTOR_FASTCALL ~nsTSubstring_CharT();
118 * reading iterators
121 const_char_iterator BeginReading() const { return mData; }
122 const_char_iterator EndReading() const { return mData + mLength; }
125 * deprecated reading iterators
128 const_iterator& BeginReading( const_iterator& iter ) const
130 iter.mStart = mData;
131 iter.mEnd = mData + mLength;
132 iter.mPosition = iter.mStart;
133 return iter;
136 const_iterator& EndReading( const_iterator& iter ) const
138 iter.mStart = mData;
139 iter.mEnd = mData + mLength;
140 iter.mPosition = iter.mEnd;
141 return iter;
144 const_char_iterator& BeginReading( const_char_iterator& iter ) const
146 return iter = mData;
149 const_char_iterator& EndReading( const_char_iterator& iter ) const
151 return iter = mData + mLength;
156 * writing iterators
159 char_iterator BeginWriting()
161 return EnsureMutable() ? mData : char_iterator(0);
164 char_iterator EndWriting()
166 return EnsureMutable() ? (mData + mLength) : char_iterator(0);
171 * deprecated writing iterators
174 iterator& BeginWriting( iterator& iter )
176 char_type *data = EnsureMutable() ? mData : nsnull;
177 iter.mStart = data;
178 iter.mEnd = data + mLength;
179 iter.mPosition = iter.mStart;
180 return iter;
183 iterator& EndWriting( iterator& iter )
185 char_type *data = EnsureMutable() ? mData : nsnull;
186 iter.mStart = data;
187 iter.mEnd = data + mLength;
188 iter.mPosition = iter.mEnd;
189 return iter;
192 char_iterator& BeginWriting( char_iterator& iter )
194 return iter = EnsureMutable() ? mData : char_iterator(0);
197 char_iterator& EndWriting( char_iterator& iter )
199 return iter = EnsureMutable() ? (mData + mLength) : char_iterator(0);
204 * accessors
207 // returns pointer to string data (not necessarily null-terminated)
208 const char_type *Data() const
210 return mData;
213 size_type Length() const
215 return mLength;
218 PRBool IsEmpty() const
220 return mLength == 0;
223 PRBool IsVoid() const
225 return (mFlags & F_VOIDED) != 0;
228 PRBool IsTerminated() const
230 return (mFlags & F_TERMINATED) != 0;
233 char_type CharAt( index_type i ) const
235 NS_ASSERTION(i < mLength, "index exceeds allowable range");
236 return mData[i];
239 char_type operator[]( index_type i ) const
241 return CharAt(i);
244 char_type First() const
246 NS_ASSERTION(mLength > 0, "|First()| called on an empty string");
247 return mData[0];
250 inline
251 char_type Last() const
253 NS_ASSERTION(mLength > 0, "|Last()| called on an empty string");
254 return mData[mLength - 1];
257 NS_COM size_type NS_FASTCALL CountChar( char_type ) const;
258 NS_COM PRInt32 NS_FASTCALL FindChar( char_type, index_type offset = 0 ) const;
262 * equality
265 NS_COM PRBool NS_FASTCALL Equals( const self_type& ) const;
266 NS_COM PRBool NS_FASTCALL Equals( const self_type&, const comparator_type& ) const;
268 NS_COM PRBool NS_FASTCALL Equals( const char_type* data ) const;
269 NS_COM PRBool NS_FASTCALL Equals( const char_type* data, const comparator_type& comp ) const;
272 * An efficient comparison with ASCII that can be used even
273 * for wide strings. Call this version when you know the
274 * length of 'data'.
276 NS_COM PRBool NS_FASTCALL EqualsASCII( const char* data, size_type len ) const;
278 * An efficient comparison with ASCII that can be used even
279 * for wide strings. Call this version when 'data' is
280 * null-terminated.
282 NS_COM PRBool NS_FASTCALL EqualsASCII( const char* data ) const;
284 // EqualsLiteral must ONLY be applied to an actual literal string.
285 // Do not attempt to use it with a regular char* pointer, or with a char
286 // array variable.
287 // The template trick to acquire the array length at compile time without
288 // using a macro is due to Corey Kosak, with much thanks.
289 #ifdef NS_DISABLE_LITERAL_TEMPLATE
290 inline PRBool EqualsLiteral( const char* str ) const
292 return EqualsASCII(str);
294 #else
295 template<int N>
296 inline PRBool EqualsLiteral( const char (&str)[N] ) const
298 return EqualsASCII(str, N-1);
300 template<int N>
301 inline PRBool EqualsLiteral( char (&str)[N] ) const
303 const char* s = str;
304 return EqualsASCII(s, N-1);
306 #endif
308 // The LowerCaseEquals methods compare the lower case version of
309 // this string to some ASCII/Literal string. The ASCII string is
310 // *not* lowercased for you. If you compare to an ASCII or literal
311 // string that contains an uppercase character, it is guaranteed to
312 // return false. We will throw assertions too.
313 NS_COM PRBool NS_FASTCALL LowerCaseEqualsASCII( const char* data, size_type len ) const;
314 NS_COM PRBool NS_FASTCALL LowerCaseEqualsASCII( const char* data ) const;
316 // LowerCaseEqualsLiteral must ONLY be applied to an actual
317 // literal string. Do not attempt to use it with a regular char*
318 // pointer, or with a char array variable. Use
319 // LowerCaseEqualsASCII for them.
320 #ifdef NS_DISABLE_LITERAL_TEMPLATE
321 inline PRBool LowerCaseEqualsLiteral( const char* str ) const
323 return LowerCaseEqualsASCII(str);
325 #else
326 template<int N>
327 inline PRBool LowerCaseEqualsLiteral( const char (&str)[N] ) const
329 return LowerCaseEqualsASCII(str, N-1);
331 template<int N>
332 inline PRBool LowerCaseEqualsLiteral( char (&str)[N] ) const
334 const char* s = str;
335 return LowerCaseEqualsASCII(s, N-1);
337 #endif
340 * assignment
343 NS_COM void NS_FASTCALL Assign( char_type c );
344 NS_COM void NS_FASTCALL Assign( const char_type* data, size_type length = size_type(-1) );
345 NS_COM void NS_FASTCALL Assign( const self_type& );
346 NS_COM void NS_FASTCALL Assign( const substring_tuple_type& );
348 NS_COM void NS_FASTCALL AssignASCII( const char* data, size_type length );
349 NS_COM void NS_FASTCALL AssignASCII( const char* data );
351 // AssignLiteral must ONLY be applied to an actual literal string.
352 // Do not attempt to use it with a regular char* pointer, or with a char
353 // array variable. Use AssignASCII for those.
354 #ifdef NS_DISABLE_LITERAL_TEMPLATE
355 void AssignLiteral( const char* str )
356 { AssignASCII(str); }
357 #else
358 template<int N>
359 void AssignLiteral( const char (&str)[N] )
360 { AssignASCII(str, N-1); }
361 template<int N>
362 void AssignLiteral( char (&str)[N] )
363 { AssignASCII(str, N-1); }
364 #endif
366 self_type& operator=( char_type c ) { Assign(c); return *this; }
367 self_type& operator=( const char_type* data ) { Assign(data); return *this; }
368 self_type& operator=( const self_type& str ) { Assign(str); return *this; }
369 self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; }
371 NS_COM void NS_FASTCALL Adopt( char_type* data, size_type length = size_type(-1) );
375 * buffer manipulation
378 NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, char_type c );
379 NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length = size_type(-1) );
380 void Replace( index_type cutStart, size_type cutLength, const self_type& str ) { Replace(cutStart, cutLength, str.Data(), str.Length()); }
381 NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& tuple );
383 NS_COM void NS_FASTCALL ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) );
385 void Append( char_type c ) { Replace(mLength, 0, c); }
386 void Append( const char_type* data, size_type length = size_type(-1) ) { Replace(mLength, 0, data, length); }
387 void Append( const self_type& str ) { Replace(mLength, 0, str); }
388 void Append( const substring_tuple_type& tuple ) { Replace(mLength, 0, tuple); }
390 void AppendASCII( const char* data, size_type length = size_type(-1) ) { ReplaceASCII(mLength, 0, data, length); }
392 // AppendLiteral must ONLY be applied to an actual literal string.
393 // Do not attempt to use it with a regular char* pointer, or with a char
394 // array variable. Use AppendASCII for those.
395 #ifdef NS_DISABLE_LITERAL_TEMPLATE
396 void AppendLiteral( const char* str )
397 { AppendASCII(str); }
398 #else
399 template<int N>
400 void AppendLiteral( const char (&str)[N] )
401 { AppendASCII(str, N-1); }
402 template<int N>
403 void AppendLiteral( char (&str)[N] )
404 { AppendASCII(str, N-1); }
405 #endif
407 self_type& operator+=( char_type c ) { Append(c); return *this; }
408 self_type& operator+=( const char_type* data ) { Append(data); return *this; }
409 self_type& operator+=( const self_type& str ) { Append(str); return *this; }
410 self_type& operator+=( const substring_tuple_type& tuple ) { Append(tuple); return *this; }
412 void Insert( char_type c, index_type pos ) { Replace(pos, 0, c); }
413 void Insert( const char_type* data, index_type pos, size_type length = size_type(-1) ) { Replace(pos, 0, data, length); }
414 void Insert( const self_type& str, index_type pos ) { Replace(pos, 0, str); }
415 void Insert( const substring_tuple_type& tuple, index_type pos ) { Replace(pos, 0, tuple); }
417 void Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, char_traits::sEmptyBuffer, 0); }
421 * buffer sizing
424 NS_COM void NS_FASTCALL SetCapacity( size_type newCapacity );
426 NS_COM void NS_FASTCALL SetLength( size_type newLength );
428 void Truncate( size_type newLength = 0 )
430 NS_ASSERTION(newLength <= mLength, "Truncate cannot make string longer");
431 SetLength(newLength);
436 * buffer access
441 * Get a const pointer to the string's internal buffer. The caller
442 * MUST NOT modify the characters at the returned address.
444 * @returns The length of the buffer in characters.
446 inline size_type GetData( const char_type** data ) const
448 *data = mData;
449 return mLength;
453 * Get a pointer to the string's internal buffer, optionally resizing
454 * the buffer first. If size_type(-1) is passed for newLen, then the
455 * current length of the string is used. The caller MAY modify the
456 * characters at the returned address (up to but not exceeding the
457 * length of the string).
459 * @returns The length of the buffer in characters or 0 if unable to
460 * satisfy the request due to low-memory conditions.
462 inline size_type GetMutableData( char_type** data, size_type newLen = size_type(-1) )
464 if (!EnsureMutable(newLen))
466 *data = nsnull;
467 return 0;
470 *data = mData;
471 return mLength;
476 * string data is never null, but can be marked void. if true, the
477 * string will be truncated. @see nsTSubstring::IsVoid
480 NS_COM void NS_FASTCALL SetIsVoid( PRBool );
483 * This method is used to remove all occurrences of aChar from this
484 * string.
486 * @param aChar -- char to be stripped
487 * @param aOffset -- where in this string to start stripping chars
490 NS_COM void StripChar( char_type aChar, PRInt32 aOffset=0 );
493 public:
496 * this is public to support automatic conversion of tuple to string
497 * base type, which helps avoid converting to nsTAString.
499 NS_COM nsTSubstring_CharT(const substring_tuple_type& tuple);
502 * allows for direct initialization of a nsTSubstring object.
504 * NOTE: this constructor is declared public _only_ for convenience
505 * inside the string implementation.
507 #ifdef XP_OS2 /* Workaround for GCC 3.3.x bug. */
508 nsTSubstring_CharT( char_type *data, size_type length, PRUint32 flags ) NS_COM;
509 #else
510 NS_COM nsTSubstring_CharT( char_type *data, size_type length, PRUint32 flags );
511 #endif
512 protected:
514 friend class nsTObsoleteAStringThunk_CharT;
515 friend class nsTSubstringTuple_CharT;
517 // XXX GCC 3.4 needs this :-(
518 friend class nsTPromiseFlatString_CharT;
520 char_type* mData;
521 size_type mLength;
522 PRUint32 mFlags;
524 // default initialization
525 NS_COM nsTSubstring_CharT();
527 // version of constructor that leaves mData and mLength uninitialized
528 explicit
529 NS_COM nsTSubstring_CharT( PRUint32 flags );
531 // copy-constructor, constructs as dependent on given object
532 // (NOTE: this is for internal use only)
533 NS_COM nsTSubstring_CharT( const self_type& str );
536 * this function releases mData and does not change the value of
537 * any of it's member variables. in other words, this function acts
538 * like a destructor.
540 void NS_FASTCALL Finalize();
543 * this function prepares mData to be mutated.
545 * @param capacity specifies the required capacity of mData
546 * @param old_data returns null or the old value of mData
547 * @param old_flags returns 0 or the old value of mFlags
549 * if mData is already mutable and of sufficient capacity, then this
550 * function will return immediately. otherwise, it will either resize
551 * mData or allocate a new shared buffer. if it needs to allocate a
552 * new buffer, then it will return the old buffer and the corresponding
553 * flags. this allows the caller to decide when to free the old data.
555 * this function returns false if is unable to allocate sufficient
556 * memory.
558 * XXX we should expose a way for subclasses to free old_data.
560 PRBool NS_FASTCALL MutatePrep( size_type capacity, char_type** old_data, PRUint32* old_flags );
563 * this function prepares a section of mData to be modified. if
564 * necessary, this function will reallocate mData and possibly move
565 * existing data to open up the specified section.
567 * @param cutStart specifies the starting offset of the section
568 * @param cutLength specifies the length of the section to be replaced
569 * @param newLength specifies the length of the new section
571 * for example, suppose mData contains the string "abcdef" then
573 * ReplacePrep(2, 3, 4);
575 * would cause mData to look like "ab____f" where the characters
576 * indicated by '_' have an unspecified value and can be freely
577 * modified. this function will null-terminate mData upon return.
579 * this function returns false if is unable to allocate sufficient
580 * memory.
582 PRBool NS_FASTCALL ReplacePrep( index_type cutStart, size_type cutLength, size_type newLength );
585 * returns the number of writable storage units starting at mData.
586 * the value does not include space for the null-terminator character.
588 * NOTE: this function returns size_type(-1) if mData is immutable.
590 size_type NS_FASTCALL Capacity() const;
593 * this helper function can be called prior to directly manipulating
594 * the contents of mData. see, for example, BeginWriting.
596 NS_COM PRBool NS_FASTCALL EnsureMutable( size_type newLen = size_type(-1) );
599 * returns true if this string overlaps with the given string fragment.
601 PRBool IsDependentOn( const char_type *start, const char_type *end ) const
604 * if it _isn't_ the case that one fragment starts after the other ends,
605 * or ends before the other starts, then, they conflict:
607 * !(f2.begin >= f1.end || f2.end <= f1.begin)
609 * Simplified, that gives us:
611 return ( start < (mData + mLength) && end > mData );
615 * this helper function stores the specified dataFlags in mFlags
617 void SetDataFlags(PRUint32 dataFlags)
619 NS_ASSERTION((dataFlags & 0xFFFF0000) == 0, "bad flags");
620 mFlags = dataFlags | (mFlags & 0xFFFF0000);
623 public:
625 // mFlags is a bitwise combination of the following flags. the meaning
626 // and interpretation of these flags is an implementation detail.
628 // NOTE: these flags are declared public _only_ for convenience inside
629 // the string implementation.
631 enum
633 F_NONE = 0, // no flags
635 // data flags are in the lower 16-bits
636 F_TERMINATED = 1 << 0, // IsTerminated returns true
637 F_VOIDED = 1 << 1, // IsVoid returns true
638 F_SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
639 F_OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
640 F_FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer
642 // class flags are in the upper 16-bits
643 F_CLASS_FIXED = 1 << 16 // indicates that |this| is of type nsTFixedString
647 // Some terminology:
649 // "dependent buffer" A dependent buffer is one that the string class
650 // does not own. The string class relies on some
651 // external code to ensure the lifetime of the
652 // dependent buffer.
654 // "shared buffer" A shared buffer is one that the string class
655 // allocates. When it allocates a shared string
656 // buffer, it allocates some additional space at
657 // the beginning of the buffer for additional
658 // fields, including a reference count and a
659 // buffer length. See nsStringHeader.
661 // "adopted buffer" An adopted buffer is a raw string buffer
662 // allocated on the heap (using nsMemory::Alloc)
663 // of which the string class subsumes ownership.
665 // Some comments about the string flags:
667 // F_SHARED, F_OWNED, and F_FIXED are all mutually exlusive. They
668 // indicate the allocation type of mData. If none of these flags
669 // are set, then the string buffer is dependent.
671 // F_SHARED, F_OWNED, or F_FIXED imply F_TERMINATED. This is because
672 // the string classes always allocate null-terminated buffers, and
673 // non-terminated substrings are always dependent.
675 // F_VOIDED implies F_TERMINATED, and moreover it implies that mData
676 // points to char_traits::sEmptyBuffer. Therefore, F_VOIDED is
677 // mutually exclusive with F_SHARED, F_OWNED, and F_FIXED.
681 NS_COM
682 int NS_FASTCALL Compare( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs, const nsTStringComparator_CharT& = nsTDefaultStringComparator_CharT() );
685 inline
686 PRBool operator!=( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
688 return !lhs.Equals(rhs);
691 inline
692 PRBool operator< ( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
694 return Compare(lhs, rhs)< 0;
697 inline
698 PRBool operator<=( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
700 return Compare(lhs, rhs)<=0;
703 inline
704 PRBool operator==( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
706 return lhs.Equals(rhs);
709 inline
710 PRBool operator>=( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
712 return Compare(lhs, rhs)>=0;
715 inline
716 PRBool operator> ( const nsTSubstring_CharT::base_string_type& lhs, const nsTSubstring_CharT::base_string_type& rhs )
718 return Compare(lhs, rhs)> 0;