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"
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.
16 * The base for string comparators
18 class nsTStringComparator_CharT
21 typedef CharT char_type
;
23 nsTStringComparator_CharT()
27 virtual int operator()(const char_type
*, const char_type
*,
28 uint32_t, uint32_t) const = 0;
33 * The default string comparator (case-sensitive comparision)
35 class nsTDefaultStringComparator_CharT
36 : public nsTStringComparator_CharT
39 typedef CharT char_type
;
41 nsTDefaultStringComparator_CharT()
45 virtual int operator()(const char_type
*, const char_type
*,
46 uint32_t, uint32_t) const;
50 * nsTSubstring is the most abstract class in the string hierarchy. It
51 * represents a single contiguous array of characters, which may or may not
52 * be null-terminated. This type is not instantiated directly. A sub-class
53 * is instantiated instead. For example, see nsTString.
56 * nsAString for wide characters
57 * nsACString for narrow characters
59 * Many of the accessors on nsTSubstring are inlined as an optimization.
61 class nsTSubstring_CharT
64 typedef mozilla::fallible_t fallible_t
;
66 typedef CharT char_type
;
68 typedef nsCharTraits
<char_type
> char_traits
;
69 typedef char_traits::incompatible_char_type incompatible_char_type
;
71 typedef nsTSubstring_CharT self_type
;
72 typedef self_type abstract_string_type
;
73 typedef self_type base_string_type
;
75 typedef self_type substring_type
;
76 typedef nsTSubstringTuple_CharT substring_tuple_type
;
77 typedef nsTString_CharT string_type
;
79 typedef nsReadingIterator
<char_type
> const_iterator
;
80 typedef nsWritingIterator
<char_type
> iterator
;
82 typedef nsTStringComparator_CharT comparator_type
;
84 typedef char_type
* char_iterator
;
85 typedef const char_type
* const_char_iterator
;
87 typedef uint32_t size_type
;
88 typedef uint32_t index_type
;
92 // this acts like a virtual destructor
102 const_char_iterator
BeginReading() const
106 const_char_iterator
EndReading() const
108 return mData
+ mLength
;
112 * deprecated reading iterators
115 const_iterator
& BeginReading(const_iterator
& aIter
) const
117 aIter
.mStart
= mData
;
118 aIter
.mEnd
= mData
+ mLength
;
119 aIter
.mPosition
= aIter
.mStart
;
123 const_iterator
& EndReading(const_iterator
& aIter
) const
125 aIter
.mStart
= mData
;
126 aIter
.mEnd
= mData
+ mLength
;
127 aIter
.mPosition
= aIter
.mEnd
;
131 const_char_iterator
& BeginReading(const_char_iterator
& aIter
) const
133 return aIter
= mData
;
136 const_char_iterator
& EndReading(const_char_iterator
& aIter
) const
138 return aIter
= mData
+ mLength
;
146 char_iterator
BeginWriting()
148 if (!EnsureMutable()) {
149 NS_ABORT_OOM(mLength
);
155 char_iterator
BeginWriting(const fallible_t
&)
157 return EnsureMutable() ? mData
: char_iterator(0);
160 char_iterator
EndWriting()
162 if (!EnsureMutable()) {
163 NS_ABORT_OOM(mLength
);
166 return mData
+ mLength
;
169 char_iterator
EndWriting(const fallible_t
&)
171 return EnsureMutable() ? (mData
+ mLength
) : char_iterator(0);
174 char_iterator
& BeginWriting(char_iterator
& aIter
)
176 return aIter
= BeginWriting();
179 char_iterator
& BeginWriting(char_iterator
& aIter
, const fallible_t
&)
181 return aIter
= BeginWriting(fallible_t());
184 char_iterator
& EndWriting(char_iterator
& aIter
)
186 return aIter
= EndWriting();
189 char_iterator
& EndWriting(char_iterator
& aIter
, const fallible_t
&)
191 return aIter
= EndWriting(fallible_t());
195 * deprecated writing iterators
198 iterator
& BeginWriting(iterator
& aIter
)
200 char_type
* data
= BeginWriting();
202 aIter
.mEnd
= data
+ mLength
;
203 aIter
.mPosition
= aIter
.mStart
;
207 iterator
& EndWriting(iterator
& aIter
)
209 char_type
* data
= BeginWriting();
211 aIter
.mEnd
= data
+ mLength
;
212 aIter
.mPosition
= aIter
.mEnd
;
220 // returns pointer to string data (not necessarily null-terminated)
221 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
222 char16ptr_t
Data() const
224 const char_type
* Data() const
230 size_type
Length() const
235 uint32_t Flags() const
245 bool IsLiteral() const
247 return (mFlags
& F_LITERAL
) != 0;
252 return (mFlags
& F_VOIDED
) != 0;
255 bool IsTerminated() const
257 return (mFlags
& F_TERMINATED
) != 0;
260 char_type
CharAt(index_type aIndex
) const
262 NS_ASSERTION(aIndex
< mLength
, "index exceeds allowable range");
263 return mData
[aIndex
];
266 char_type
operator[](index_type aIndex
) const
268 return CharAt(aIndex
);
271 char_type
First() const
273 NS_ASSERTION(mLength
> 0, "|First()| called on an empty string");
277 inline char_type
Last() const
279 NS_ASSERTION(mLength
> 0, "|Last()| called on an empty string");
280 return mData
[mLength
- 1];
283 size_type NS_FASTCALL
CountChar(char_type
) const;
284 int32_t NS_FASTCALL
FindChar(char_type
, index_type aOffset
= 0) const;
291 bool NS_FASTCALL
Equals(const self_type
&) const;
292 bool NS_FASTCALL
Equals(const self_type
&, const comparator_type
&) const;
294 bool NS_FASTCALL
Equals(const char_type
* aData
) const;
295 bool NS_FASTCALL
Equals(const char_type
* aData
,
296 const comparator_type
& aComp
) const;
298 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
299 bool NS_FASTCALL
Equals(char16ptr_t aData
) const
301 return Equals(static_cast<const char16_t
*>(aData
));
303 bool NS_FASTCALL
Equals(char16ptr_t aData
, const comparator_type
& aComp
) const
305 return Equals(static_cast<const char16_t
*>(aData
), aComp
);
310 * An efficient comparison with ASCII that can be used even
311 * for wide strings. Call this version when you know the
314 bool NS_FASTCALL
EqualsASCII(const char* aData
, size_type aLen
) const;
316 * An efficient comparison with ASCII that can be used even
317 * for wide strings. Call this version when 'data' is
320 bool NS_FASTCALL
EqualsASCII(const char* aData
) const;
322 // EqualsLiteral must ONLY be applied to an actual literal string, or
323 // a char array *constant* declared without an explicit size.
324 // Do not attempt to use it with a regular char* pointer, or with a
325 // non-constant char array variable. Use EqualsASCII for them.
326 // The template trick to acquire the array length at compile time without
327 // using a macro is due to Corey Kosak, with much thanks.
329 inline bool EqualsLiteral(const char (&aStr
)[N
]) const
331 return EqualsASCII(aStr
, N
- 1);
334 // The LowerCaseEquals methods compare the ASCII-lowercase version of
335 // this string (lowercasing only ASCII uppercase characters) to some
336 // ASCII/Literal string. The ASCII string is *not* lowercased for
337 // you. If you compare to an ASCII or literal string that contains an
338 // uppercase character, it is guaranteed to return false. We will
339 // throw assertions too.
340 bool NS_FASTCALL
LowerCaseEqualsASCII(const char* aData
,
341 size_type aLen
) const;
342 bool NS_FASTCALL
LowerCaseEqualsASCII(const char* aData
) const;
344 // LowerCaseEqualsLiteral must ONLY be applied to an actual
345 // literal string, or a char array *constant* declared without an
346 // explicit size. Do not attempt to use it with a regular char*
347 // pointer, or with a non-constant char array variable. Use
348 // LowerCaseEqualsASCII for them.
350 inline bool LowerCaseEqualsLiteral(const char (&aStr
)[N
]) const
352 return LowerCaseEqualsASCII(aStr
, N
- 1);
359 void NS_FASTCALL
Assign(char_type aChar
);
360 NS_WARN_UNUSED_RESULT
bool NS_FASTCALL
Assign(char_type aChar
,
363 void NS_FASTCALL
Assign(const char_type
* aData
);
364 void NS_FASTCALL
Assign(const char_type
* aData
, size_type aLength
);
365 NS_WARN_UNUSED_RESULT
bool NS_FASTCALL
Assign(const char_type
* aData
,
369 void NS_FASTCALL
Assign(const self_type
&);
370 NS_WARN_UNUSED_RESULT
bool NS_FASTCALL
Assign(const self_type
&,
373 void NS_FASTCALL
Assign(const substring_tuple_type
&);
374 NS_WARN_UNUSED_RESULT
bool NS_FASTCALL
Assign(const substring_tuple_type
&,
377 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
378 void Assign(char16ptr_t aData
)
380 Assign(static_cast<const char16_t
*>(aData
));
383 NS_WARN_UNUSED_RESULT
bool Assign(char16ptr_t aData
, const fallible_t
&)
385 return Assign(static_cast<const char16_t
*>(aData
), fallible_t());
388 void Assign(char16ptr_t aData
, size_type aLength
)
390 Assign(static_cast<const char16_t
*>(aData
), aLength
);
393 NS_WARN_UNUSED_RESULT
bool Assign(char16ptr_t aData
, size_type aLength
,
396 return Assign(static_cast<const char16_t
*>(aData
), aLength
, fallible_t());
400 void NS_FASTCALL
AssignASCII(const char* aData
, size_type aLength
);
401 NS_WARN_UNUSED_RESULT
bool NS_FASTCALL
AssignASCII(const char* aData
,
405 void NS_FASTCALL
AssignASCII(const char* aData
)
407 AssignASCII(aData
, mozilla::AssertedCast
<size_type
, size_t>(strlen(aData
)));
409 NS_WARN_UNUSED_RESULT
bool NS_FASTCALL
AssignASCII(const char* aData
,
412 return AssignASCII(aData
,
413 mozilla::AssertedCast
<size_type
, size_t>(strlen(aData
)),
417 // AssignLiteral must ONLY be applied to an actual literal string, or
418 // a char array *constant* declared without an explicit size.
419 // Do not attempt to use it with a regular char* pointer, or with a
420 // non-constant char array variable. Use AssignASCII for those.
421 // There are not fallible version of these methods because they only really
422 // apply to small allocations that we wouldn't want to check anyway.
424 void AssignLiteral(const char_type (&aStr
)[N
])
426 AssignLiteral(aStr
, N
- 1);
428 #ifdef CharT_is_PRUnichar
430 void AssignLiteral(const char (&aStr
)[N
])
432 AssignASCII(aStr
, N
- 1);
436 self_type
& operator=(char_type aChar
)
441 self_type
& operator=(const char_type
* aData
)
446 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
447 self_type
& operator=(char16ptr_t aData
)
453 self_type
& operator=(const self_type
& aStr
)
458 self_type
& operator=(const substring_tuple_type
& aTuple
)
464 void NS_FASTCALL
Adopt(char_type
* aData
, size_type aLength
= size_type(-1));
468 * buffer manipulation
471 void NS_FASTCALL
Replace(index_type aCutStart
, size_type aCutLength
,
473 NS_WARN_UNUSED_RESULT
bool NS_FASTCALL
Replace(index_type aCutStart
,
474 size_type aCutLength
,
476 const mozilla::fallible_t
&);
477 void NS_FASTCALL
Replace(index_type aCutStart
, size_type aCutLength
,
478 const char_type
* aData
,
479 size_type aLength
= size_type(-1));
480 NS_WARN_UNUSED_RESULT
bool NS_FASTCALL
Replace(index_type aCutStart
,
481 size_type aCutLength
,
482 const char_type
* aData
,
484 const mozilla::fallible_t
&);
485 void Replace(index_type aCutStart
, size_type aCutLength
,
486 const self_type
& aStr
)
488 Replace(aCutStart
, aCutLength
, aStr
.Data(), aStr
.Length());
490 NS_WARN_UNUSED_RESULT
bool Replace(index_type aCutStart
,
491 size_type aCutLength
,
492 const self_type
& aStr
,
493 const mozilla::fallible_t
&)
495 return Replace(aCutStart
, aCutLength
, aStr
.Data(), aStr
.Length(),
496 mozilla::fallible_t());
498 void NS_FASTCALL
Replace(index_type aCutStart
, size_type aCutLength
,
499 const substring_tuple_type
& aTuple
);
501 void NS_FASTCALL
ReplaceASCII(index_type aCutStart
, size_type aCutLength
,
503 size_type aLength
= size_type(-1));
505 // ReplaceLiteral must ONLY be applied to an actual literal string.
506 // Do not attempt to use it with a regular char* pointer, or with a char
507 // array variable. Use Replace or ReplaceASCII for those.
509 void ReplaceLiteral(index_type aCutStart
, size_type aCutLength
,
510 const char_type (&aStr
)[N
])
512 ReplaceLiteral(aCutStart
, aCutLength
, aStr
, N
- 1);
515 void Append(char_type aChar
)
517 Replace(mLength
, 0, aChar
);
519 NS_WARN_UNUSED_RESULT
bool Append(char_type aChar
,
520 const mozilla::fallible_t
&)
522 return Replace(mLength
, 0, aChar
, mozilla::fallible_t());
524 void Append(const char_type
* aData
, size_type aLength
= size_type(-1))
526 Replace(mLength
, 0, aData
, aLength
);
528 NS_WARN_UNUSED_RESULT
bool Append(const char_type
* aData
, size_type aLength
,
529 const mozilla::fallible_t
&)
531 return Replace(mLength
, 0, aData
, aLength
, mozilla::fallible_t());
534 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
535 void Append(char16ptr_t aData
, size_type aLength
= size_type(-1))
537 Append(static_cast<const char16_t
*>(aData
), aLength
);
541 void Append(const self_type
& aStr
)
543 Replace(mLength
, 0, aStr
);
545 void Append(const substring_tuple_type
& aTuple
)
547 Replace(mLength
, 0, aTuple
);
550 void AppendASCII(const char* aData
, size_type aLength
= size_type(-1))
552 ReplaceASCII(mLength
, 0, aData
, aLength
);
556 * Append a formatted string to the current string. Uses the format
557 * codes documented in prprf.h
559 void AppendPrintf(const char* aFormat
, ...);
560 void AppendPrintf(const char* aFormat
, va_list aAp
);
561 void AppendInt(int32_t aInteger
)
563 AppendPrintf("%d", aInteger
);
565 void AppendInt(int32_t aInteger
, int aRadix
)
567 const char* fmt
= aRadix
== 10 ? "%d" : aRadix
== 8 ? "%o" : "%x";
568 AppendPrintf(fmt
, aInteger
);
570 void AppendInt(uint32_t aInteger
)
572 AppendPrintf("%u", aInteger
);
574 void AppendInt(uint32_t aInteger
, int aRadix
)
576 const char* fmt
= aRadix
== 10 ? "%u" : aRadix
== 8 ? "%o" : "%x";
577 AppendPrintf(fmt
, aInteger
);
579 void AppendInt(int64_t aInteger
)
581 AppendPrintf("%lld", aInteger
);
583 void AppendInt(int64_t aInteger
, int aRadix
)
585 const char* fmt
= aRadix
== 10 ? "%lld" : aRadix
== 8 ? "%llo" : "%llx";
586 AppendPrintf(fmt
, aInteger
);
588 void AppendInt(uint64_t aInteger
)
590 AppendPrintf("%llu", aInteger
);
592 void AppendInt(uint64_t aInteger
, int aRadix
)
594 const char* fmt
= aRadix
== 10 ? "%llu" : aRadix
== 8 ? "%llo" : "%llx";
595 AppendPrintf(fmt
, aInteger
);
599 * Append the given float to this string
601 void NS_FASTCALL
AppendFloat(float aFloat
);
602 void NS_FASTCALL
AppendFloat(double aFloat
);
605 // AppendLiteral must ONLY be applied to an actual literal string.
606 // Do not attempt to use it with a regular char* pointer, or with a char
607 // array variable. Use Append or AppendASCII for those.
609 void AppendLiteral(const char_type (&aStr
)[N
])
611 ReplaceLiteral(mLength
, 0, aStr
, N
- 1);
613 #ifdef CharT_is_PRUnichar
615 void AppendLiteral(const char (&aStr
)[N
])
617 AppendASCII(aStr
, N
- 1);
621 self_type
& operator+=(char_type aChar
)
626 self_type
& operator+=(const char_type
* aData
)
631 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
632 self_type
& operator+=(char16ptr_t aData
)
638 self_type
& operator+=(const self_type
& aStr
)
643 self_type
& operator+=(const substring_tuple_type
& aTuple
)
649 void Insert(char_type aChar
, index_type aPos
)
651 Replace(aPos
, 0, aChar
);
653 void Insert(const char_type
* aData
, index_type aPos
,
654 size_type aLength
= size_type(-1))
656 Replace(aPos
, 0, aData
, aLength
);
658 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
659 void Insert(char16ptr_t aData
, index_type aPos
,
660 size_type aLength
= size_type(-1))
662 Insert(static_cast<const char16_t
*>(aData
), aPos
, aLength
);
665 void Insert(const self_type
& aStr
, index_type aPos
)
667 Replace(aPos
, 0, aStr
);
669 void Insert(const substring_tuple_type
& aTuple
, index_type aPos
)
671 Replace(aPos
, 0, aTuple
);
674 // InsertLiteral must ONLY be applied to an actual literal string.
675 // Do not attempt to use it with a regular char* pointer, or with a char
676 // array variable. Use Insert for those.
678 void InsertLiteral(const char_type (&aStr
)[N
], index_type aPos
)
680 ReplaceLiteral(aPos
, 0, aStr
, N
- 1);
683 void Cut(index_type aCutStart
, size_type aCutLength
)
685 Replace(aCutStart
, aCutLength
, char_traits::sEmptyBuffer
, 0);
694 * Attempts to set the capacity to the given size in number of
695 * characters, without affecting the length of the string.
696 * There is no need to include room for the null terminator: it is
697 * the job of the string class.
698 * Also ensures that the buffer is mutable.
700 void NS_FASTCALL
SetCapacity(size_type aNewCapacity
);
701 NS_WARN_UNUSED_RESULT
bool NS_FASTCALL
SetCapacity(size_type aNewCapacity
,
704 void NS_FASTCALL
SetLength(size_type aNewLength
);
705 NS_WARN_UNUSED_RESULT
bool NS_FASTCALL
SetLength(size_type aNewLength
,
708 void Truncate(size_type aNewLength
= 0)
710 NS_ASSERTION(aNewLength
<= mLength
, "Truncate cannot make string longer");
711 SetLength(aNewLength
);
721 * Get a const pointer to the string's internal buffer. The caller
722 * MUST NOT modify the characters at the returned address.
724 * @returns The length of the buffer in characters.
726 inline size_type
GetData(const char_type
** aData
) const
733 * Get a pointer to the string's internal buffer, optionally resizing
734 * the buffer first. If size_type(-1) is passed for newLen, then the
735 * current length of the string is used. The caller MAY modify the
736 * characters at the returned address (up to but not exceeding the
737 * length of the string).
739 * @returns The length of the buffer in characters or 0 if unable to
740 * satisfy the request due to low-memory conditions.
742 size_type
GetMutableData(char_type
** aData
, size_type aNewLen
= size_type(-1))
744 if (!EnsureMutable(aNewLen
)) {
745 NS_ABORT_OOM(aNewLen
== size_type(-1) ? mLength
: aNewLen
);
752 size_type
GetMutableData(char_type
** aData
, size_type aNewLen
, const fallible_t
&)
754 if (!EnsureMutable(aNewLen
)) {
763 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
764 size_type
GetMutableData(wchar_t** aData
, size_type aNewLen
= size_type(-1))
766 return GetMutableData(reinterpret_cast<char16_t
**>(aData
), aNewLen
);
769 size_type
GetMutableData(wchar_t** aData
, size_type aNewLen
, const fallible_t
&)
771 return GetMutableData(reinterpret_cast<char16_t
**>(aData
), aNewLen
,
778 * string data is never null, but can be marked void. if true, the
779 * string will be truncated. @see nsTSubstring::IsVoid
782 void NS_FASTCALL
SetIsVoid(bool);
785 * This method is used to remove all occurrences of aChar from this
788 * @param aChar -- char to be stripped
789 * @param aOffset -- where in this string to start stripping chars
792 void StripChar(char_type aChar
, int32_t aOffset
= 0);
795 * This method is used to remove all occurrences of aChars from this
798 * @param aChars -- chars to be stripped
799 * @param aOffset -- where in this string to start stripping chars
802 void StripChars(const char_type
* aChars
, uint32_t aOffset
= 0);
805 * If the string uses a shared buffer, this method
806 * clears the pointer without releasing the buffer.
808 void ForgetSharedBuffer()
810 if (mFlags
& nsSubstring::F_SHARED
) {
811 mData
= char_traits::sEmptyBuffer
;
813 mFlags
= F_TERMINATED
;
820 * this is public to support automatic conversion of tuple to string
821 * base type, which helps avoid converting to nsTAString.
823 MOZ_IMPLICIT
nsTSubstring_CharT(const substring_tuple_type
& aTuple
)
832 * allows for direct initialization of a nsTSubstring object.
834 * NOTE: this constructor is declared public _only_ for convenience
835 * inside the string implementation.
837 // XXXbz or can I just include nscore.h and use NS_BUILD_REFCNT_LOGGING?
838 #if defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING)
839 #define XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
840 nsTSubstring_CharT(char_type
* aData
, size_type aLength
, uint32_t aFlags
);
842 #undef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
843 nsTSubstring_CharT(char_type
* aData
, size_type aLength
, uint32_t aFlags
)
849 #endif /* DEBUG || FORCE_BUILD_REFCNT_LOGGING */
851 size_t SizeOfExcludingThisMustBeUnshared(mozilla::MallocSizeOf aMallocSizeOf
)
853 size_t SizeOfIncludingThisMustBeUnshared(mozilla::MallocSizeOf aMallocSizeOf
)
856 size_t SizeOfExcludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf
)
858 size_t SizeOfIncludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf
)
862 * WARNING: Only use these functions if you really know what you are
863 * doing, because they can easily lead to double-counting strings. If
864 * you do use them, please explain clearly in a comment why it's safe
865 * and won't lead to double-counting.
867 size_t SizeOfExcludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf
)
869 size_t SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf
)
874 friend class nsTObsoleteAStringThunk_CharT
;
875 friend class nsTSubstringTuple_CharT
;
877 // XXX GCC 3.4 needs this :-(
878 friend class nsTPromiseFlatString_CharT
;
884 // default initialization
886 : mData(char_traits::sEmptyBuffer
)
888 , mFlags(F_TERMINATED
)
892 // version of constructor that leaves mData and mLength uninitialized
894 nsTSubstring_CharT(uint32_t aFlags
)
899 // copy-constructor, constructs as dependent on given object
900 // (NOTE: this is for internal use only)
901 nsTSubstring_CharT(const self_type
& aStr
)
903 , mLength(aStr
.mLength
)
904 , mFlags(aStr
.mFlags
& (F_TERMINATED
| F_VOIDED
))
909 * this function releases mData and does not change the value of
910 * any of its member variables. in other words, this function acts
913 void NS_FASTCALL
Finalize();
916 * this function prepares mData to be mutated.
918 * @param aCapacity specifies the required capacity of mData
919 * @param aOldData returns null or the old value of mData
920 * @param aOldFlags returns 0 or the old value of mFlags
922 * if mData is already mutable and of sufficient capacity, then this
923 * function will return immediately. otherwise, it will either resize
924 * mData or allocate a new shared buffer. if it needs to allocate a
925 * new buffer, then it will return the old buffer and the corresponding
926 * flags. this allows the caller to decide when to free the old data.
928 * this function returns false if is unable to allocate sufficient
931 * XXX we should expose a way for subclasses to free old_data.
933 bool NS_FASTCALL
MutatePrep(size_type aCapacity
,
934 char_type
** aOldData
, uint32_t* aOldFlags
);
937 * this function prepares a section of mData to be modified. if
938 * necessary, this function will reallocate mData and possibly move
939 * existing data to open up the specified section.
941 * @param aCutStart specifies the starting offset of the section
942 * @param aCutLength specifies the length of the section to be replaced
943 * @param aNewLength specifies the length of the new section
945 * for example, suppose mData contains the string "abcdef" then
947 * ReplacePrep(2, 3, 4);
949 * would cause mData to look like "ab____f" where the characters
950 * indicated by '_' have an unspecified value and can be freely
951 * modified. this function will null-terminate mData upon return.
953 * this function returns false if is unable to allocate sufficient
956 NS_WARN_UNUSED_RESULT
bool ReplacePrep(index_type aCutStart
,
957 size_type aCutLength
,
958 size_type aNewLength
)
960 aCutLength
= XPCOM_MIN(aCutLength
, mLength
- aCutStart
);
961 uint32_t newTotalLen
= mLength
- aCutLength
+ aNewLength
;
962 if (aCutStart
== mLength
&& Capacity() > newTotalLen
) {
964 mData
[newTotalLen
] = char_type(0);
965 mLength
= newTotalLen
;
968 return ReplacePrepInternal(aCutStart
, aCutLength
, aNewLength
, newTotalLen
);
971 NS_WARN_UNUSED_RESULT
bool NS_FASTCALL
ReplacePrepInternal(
972 index_type aCutStart
,
973 size_type aCutLength
,
974 size_type aNewFragLength
,
975 size_type aNewTotalLength
);
978 * returns the number of writable storage units starting at mData.
979 * the value does not include space for the null-terminator character.
981 * NOTE: this function returns 0 if mData is immutable (or the buffer
984 size_type NS_FASTCALL
Capacity() const;
987 * this helper function can be called prior to directly manipulating
988 * the contents of mData. see, for example, BeginWriting.
990 NS_WARN_UNUSED_RESULT
bool NS_FASTCALL
EnsureMutable(
991 size_type aNewLen
= size_type(-1));
994 * returns true if this string overlaps with the given string fragment.
996 bool IsDependentOn(const char_type
* aStart
, const char_type
* aEnd
) const
999 * if it _isn't_ the case that one fragment starts after the other ends,
1000 * or ends before the other starts, then, they conflict:
1002 * !(f2.begin >= f1.aEnd || f2.aEnd <= f1.begin)
1004 * Simplified, that gives us:
1006 return (aStart
< (mData
+ mLength
) && aEnd
> mData
);
1010 * this helper function stores the specified dataFlags in mFlags
1012 void SetDataFlags(uint32_t aDataFlags
)
1014 NS_ASSERTION((aDataFlags
& 0xFFFF0000) == 0, "bad flags");
1015 mFlags
= aDataFlags
| (mFlags
& 0xFFFF0000);
1018 void NS_FASTCALL
ReplaceLiteral(index_type aCutStart
, size_type aCutLength
,
1019 const char_type
* aData
, size_type aLength
);
1021 static int AppendFunc(void* aArg
, const char* aStr
, uint32_t aLen
);
1025 // NOTE: this method is declared public _only_ for convenience for
1026 // callers who don't have access to the original nsLiteralString_CharT.
1027 void NS_FASTCALL
AssignLiteral(const char_type
* aData
, size_type aLength
);
1029 // mFlags is a bitwise combination of the following flags. the meaning
1030 // and interpretation of these flags is an implementation detail.
1032 // NOTE: these flags are declared public _only_ for convenience inside
1033 // the string implementation.
1037 F_NONE
= 0, // no flags
1039 // data flags are in the lower 16-bits
1040 F_TERMINATED
= 1 << 0, // IsTerminated returns true
1041 F_VOIDED
= 1 << 1, // IsVoid returns true
1042 F_SHARED
= 1 << 2, // mData points to a heap-allocated, shared buffer
1043 F_OWNED
= 1 << 3, // mData points to a heap-allocated, raw buffer
1044 F_FIXED
= 1 << 4, // mData points to a fixed-size writable, dependent buffer
1045 F_LITERAL
= 1 << 5, // mData points to a string literal; F_TERMINATED will also be set
1047 // class flags are in the upper 16-bits
1048 F_CLASS_FIXED
= 1 << 16 // indicates that |this| is of type nsTFixedString
1052 // Some terminology:
1054 // "dependent buffer" A dependent buffer is one that the string class
1055 // does not own. The string class relies on some
1056 // external code to ensure the lifetime of the
1057 // dependent buffer.
1059 // "shared buffer" A shared buffer is one that the string class
1060 // allocates. When it allocates a shared string
1061 // buffer, it allocates some additional space at
1062 // the beginning of the buffer for additional
1063 // fields, including a reference count and a
1064 // buffer length. See nsStringHeader.
1066 // "adopted buffer" An adopted buffer is a raw string buffer
1067 // allocated on the heap (using nsMemory::Alloc)
1068 // of which the string class subsumes ownership.
1070 // Some comments about the string flags:
1072 // F_SHARED, F_OWNED, and F_FIXED are all mutually exlusive. They
1073 // indicate the allocation type of mData. If none of these flags
1074 // are set, then the string buffer is dependent.
1076 // F_SHARED, F_OWNED, or F_FIXED imply F_TERMINATED. This is because
1077 // the string classes always allocate null-terminated buffers, and
1078 // non-terminated substrings are always dependent.
1080 // F_VOIDED implies F_TERMINATED, and moreover it implies that mData
1081 // points to char_traits::sEmptyBuffer. Therefore, F_VOIDED is
1082 // mutually exclusive with F_SHARED, F_OWNED, and F_FIXED.
1087 Compare(const nsTSubstring_CharT::base_string_type
& aLhs
,
1088 const nsTSubstring_CharT::base_string_type
& aRhs
,
1089 const nsTStringComparator_CharT
& = nsTDefaultStringComparator_CharT());
1093 operator!=(const nsTSubstring_CharT::base_string_type
& aLhs
,
1094 const nsTSubstring_CharT::base_string_type
& aRhs
)
1096 return !aLhs
.Equals(aRhs
);
1100 operator<(const nsTSubstring_CharT::base_string_type
& aLhs
,
1101 const nsTSubstring_CharT::base_string_type
& aRhs
)
1103 return Compare(aLhs
, aRhs
) < 0;
1107 operator<=(const nsTSubstring_CharT::base_string_type
& aLhs
,
1108 const nsTSubstring_CharT::base_string_type
& aRhs
)
1110 return Compare(aLhs
, aRhs
) <= 0;
1114 operator==(const nsTSubstring_CharT::base_string_type
& aLhs
,
1115 const nsTSubstring_CharT::base_string_type
& aRhs
)
1117 return aLhs
.Equals(aRhs
);
1121 operator==(const nsTSubstring_CharT::base_string_type
& aLhs
,
1122 const nsTSubstring_CharT::char_type
* aRhs
)
1124 return aLhs
.Equals(aRhs
);
1129 operator>=(const nsTSubstring_CharT::base_string_type
& aLhs
,
1130 const nsTSubstring_CharT::base_string_type
& aRhs
)
1132 return Compare(aLhs
, aRhs
) >= 0;
1136 operator>(const nsTSubstring_CharT::base_string_type
& aLhs
,
1137 const nsTSubstring_CharT::base_string_type
& aRhs
)
1139 return Compare(aLhs
, aRhs
) > 0;