Bumping manifests a=b2g-bump
[gecko.git] / xpcom / string / nsTSubstring.h
blob959eb954e42373b450a387ac37d16d139fa3c7b5
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.
13 #endif
15 /**
16 * The base for string comparators
18 class nsTStringComparator_CharT
20 public:
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;
32 /**
33 * The default string comparator (case-sensitive comparision)
35 class nsTDefaultStringComparator_CharT
36 : public nsTStringComparator_CharT
38 public:
39 typedef CharT char_type;
41 nsTDefaultStringComparator_CharT()
45 virtual int operator()(const char_type*, const char_type*,
46 uint32_t, uint32_t) const;
49 /**
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.
55 * NAMES:
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
63 public:
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;
90 public:
92 // this acts like a virtual destructor
93 ~nsTSubstring_CharT()
95 Finalize();
98 /**
99 * reading iterators
102 const_char_iterator BeginReading() const
104 return mData;
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;
120 return aIter;
123 const_iterator& EndReading(const_iterator& aIter) const
125 aIter.mStart = mData;
126 aIter.mEnd = mData + mLength;
127 aIter.mPosition = aIter.mEnd;
128 return aIter;
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;
143 * writing iterators
146 char_iterator BeginWriting()
148 if (!EnsureMutable()) {
149 NS_ABORT_OOM(mLength);
152 return mData;
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();
201 aIter.mStart = data;
202 aIter.mEnd = data + mLength;
203 aIter.mPosition = aIter.mStart;
204 return aIter;
207 iterator& EndWriting(iterator& aIter)
209 char_type* data = BeginWriting();
210 aIter.mStart = data;
211 aIter.mEnd = data + mLength;
212 aIter.mPosition = aIter.mEnd;
213 return aIter;
217 * accessors
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
223 #else
224 const char_type* Data() const
225 #endif
227 return mData;
230 size_type Length() const
232 return mLength;
235 uint32_t Flags() const
237 return mFlags;
240 bool IsEmpty() const
242 return mLength == 0;
245 bool IsLiteral() const
247 return (mFlags & F_LITERAL) != 0;
250 bool IsVoid() const
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");
274 return mData[0];
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;
288 * equality
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);
307 #endif
310 * An efficient comparison with ASCII that can be used even
311 * for wide strings. Call this version when you know the
312 * length of 'data'.
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
318 * null-terminated.
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.
328 template<int N>
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.
349 template<int N>
350 inline bool LowerCaseEqualsLiteral(const char (&aStr)[N]) const
352 return LowerCaseEqualsASCII(aStr, N - 1);
356 * assignment
359 void NS_FASTCALL Assign(char_type aChar);
360 NS_WARN_UNUSED_RESULT bool NS_FASTCALL Assign(char_type aChar,
361 const fallible_t&);
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,
366 size_type aLength,
367 const fallible_t&);
369 void NS_FASTCALL Assign(const self_type&);
370 NS_WARN_UNUSED_RESULT bool NS_FASTCALL Assign(const self_type&,
371 const fallible_t&);
373 void NS_FASTCALL Assign(const substring_tuple_type&);
374 NS_WARN_UNUSED_RESULT bool NS_FASTCALL Assign(const substring_tuple_type&,
375 const fallible_t&);
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,
394 const fallible_t&)
396 return Assign(static_cast<const char16_t*>(aData), aLength, fallible_t());
398 #endif
400 void NS_FASTCALL AssignASCII(const char* aData, size_type aLength);
401 NS_WARN_UNUSED_RESULT bool NS_FASTCALL AssignASCII(const char* aData,
402 size_type aLength,
403 const fallible_t&);
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,
410 const fallible_t&)
412 return AssignASCII(aData,
413 mozilla::AssertedCast<size_type, size_t>(strlen(aData)),
414 fallible_t());
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.
423 template<int N>
424 void AssignLiteral(const char_type (&aStr)[N])
426 AssignLiteral(aStr, N - 1);
428 #ifdef CharT_is_PRUnichar
429 template<int N>
430 void AssignLiteral(const char (&aStr)[N])
432 AssignASCII(aStr, N - 1);
434 #endif
436 self_type& operator=(char_type aChar)
438 Assign(aChar);
439 return *this;
441 self_type& operator=(const char_type* aData)
443 Assign(aData);
444 return *this;
446 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
447 self_type& operator=(char16ptr_t aData)
449 Assign(aData);
450 return *this;
452 #endif
453 self_type& operator=(const self_type& aStr)
455 Assign(aStr);
456 return *this;
458 self_type& operator=(const substring_tuple_type& aTuple)
460 Assign(aTuple);
461 return *this;
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,
472 char_type aChar);
473 NS_WARN_UNUSED_RESULT bool NS_FASTCALL Replace(index_type aCutStart,
474 size_type aCutLength,
475 char_type aChar,
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,
483 size_type aLength,
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,
502 const char* aData,
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.
508 template<int N>
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);
539 #endif
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);
603 public:
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.
608 template<int N>
609 void AppendLiteral(const char_type (&aStr)[N])
611 ReplaceLiteral(mLength, 0, aStr, N - 1);
613 #ifdef CharT_is_PRUnichar
614 template<int N>
615 void AppendLiteral(const char (&aStr)[N])
617 AppendASCII(aStr, N - 1);
619 #endif
621 self_type& operator+=(char_type aChar)
623 Append(aChar);
624 return *this;
626 self_type& operator+=(const char_type* aData)
628 Append(aData);
629 return *this;
631 #if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
632 self_type& operator+=(char16ptr_t aData)
634 Append(aData);
635 return *this;
637 #endif
638 self_type& operator+=(const self_type& aStr)
640 Append(aStr);
641 return *this;
643 self_type& operator+=(const substring_tuple_type& aTuple)
645 Append(aTuple);
646 return *this;
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);
664 #endif
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.
677 template<int N>
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);
690 * buffer sizing
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,
702 const fallible_t&);
704 void NS_FASTCALL SetLength(size_type aNewLength);
705 NS_WARN_UNUSED_RESULT bool NS_FASTCALL SetLength(size_type aNewLength,
706 const fallible_t&);
708 void Truncate(size_type aNewLength = 0)
710 NS_ASSERTION(aNewLength <= mLength, "Truncate cannot make string longer");
711 SetLength(aNewLength);
716 * buffer access
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
728 *aData = mData;
729 return mLength;
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);
748 *aData = mData;
749 return mLength;
752 size_type GetMutableData(char_type** aData, size_type aNewLen, const fallible_t&)
754 if (!EnsureMutable(aNewLen)) {
755 *aData = nullptr;
756 return 0;
759 *aData = mData;
760 return mLength;
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,
772 fallible_t());
774 #endif
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
786 * string.
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
796 * string.
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;
812 mLength = 0;
813 mFlags = F_TERMINATED;
817 public:
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)
824 : mData(nullptr)
825 , mLength(0)
826 , mFlags(F_NONE)
828 Assign(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);
841 #else
842 #undef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
843 nsTSubstring_CharT(char_type* aData, size_type aLength, uint32_t aFlags)
844 : mData(aData)
845 , mLength(aLength)
846 , mFlags(aFlags)
849 #endif /* DEBUG || FORCE_BUILD_REFCNT_LOGGING */
851 size_t SizeOfExcludingThisMustBeUnshared(mozilla::MallocSizeOf aMallocSizeOf)
852 const;
853 size_t SizeOfIncludingThisMustBeUnshared(mozilla::MallocSizeOf aMallocSizeOf)
854 const;
856 size_t SizeOfExcludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf)
857 const;
858 size_t SizeOfIncludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf)
859 const;
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)
868 const;
869 size_t SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf)
870 const;
872 protected:
874 friend class nsTObsoleteAStringThunk_CharT;
875 friend class nsTSubstringTuple_CharT;
877 // XXX GCC 3.4 needs this :-(
878 friend class nsTPromiseFlatString_CharT;
880 char_type* mData;
881 size_type mLength;
882 uint32_t mFlags;
884 // default initialization
885 nsTSubstring_CharT()
886 : mData(char_traits::sEmptyBuffer)
887 , mLength(0)
888 , mFlags(F_TERMINATED)
892 // version of constructor that leaves mData and mLength uninitialized
893 explicit
894 nsTSubstring_CharT(uint32_t aFlags)
895 : mFlags(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)
902 : mData(aStr.mData)
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
911 * like a destructor.
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
929 * memory.
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
954 * memory.
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) {
963 mFlags &= ~F_VOIDED;
964 mData[newTotalLen] = char_type(0);
965 mLength = newTotalLen;
966 return true;
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
982 * is 0-sized).
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);
1023 public:
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.
1035 enum
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.
1086 int NS_FASTCALL
1087 Compare(const nsTSubstring_CharT::base_string_type& aLhs,
1088 const nsTSubstring_CharT::base_string_type& aRhs,
1089 const nsTStringComparator_CharT& = nsTDefaultStringComparator_CharT());
1092 inline bool
1093 operator!=(const nsTSubstring_CharT::base_string_type& aLhs,
1094 const nsTSubstring_CharT::base_string_type& aRhs)
1096 return !aLhs.Equals(aRhs);
1099 inline bool
1100 operator<(const nsTSubstring_CharT::base_string_type& aLhs,
1101 const nsTSubstring_CharT::base_string_type& aRhs)
1103 return Compare(aLhs, aRhs) < 0;
1106 inline bool
1107 operator<=(const nsTSubstring_CharT::base_string_type& aLhs,
1108 const nsTSubstring_CharT::base_string_type& aRhs)
1110 return Compare(aLhs, aRhs) <= 0;
1113 inline bool
1114 operator==(const nsTSubstring_CharT::base_string_type& aLhs,
1115 const nsTSubstring_CharT::base_string_type& aRhs)
1117 return aLhs.Equals(aRhs);
1120 inline bool
1121 operator==(const nsTSubstring_CharT::base_string_type& aLhs,
1122 const nsTSubstring_CharT::char_type* aRhs)
1124 return aLhs.Equals(aRhs);
1128 inline bool
1129 operator>=(const nsTSubstring_CharT::base_string_type& aLhs,
1130 const nsTSubstring_CharT::base_string_type& aRhs)
1132 return Compare(aLhs, aRhs) >= 0;
1135 inline bool
1136 operator>(const nsTSubstring_CharT::base_string_type& aLhs,
1137 const nsTSubstring_CharT::base_string_type& aRhs)
1139 return Compare(aLhs, aRhs) > 0;