зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1393230 - Part 3: Convert the xpcom string classes to be templated on char type. r=njn, r=fitzgen, r=sfink
This removes the double-include macro hackery that we use to define two separate string types (nsAString and nsACString) in favor of a templated solution. Annotations for Valgrind and the JS hazard analysis are updated as well as the rust binding generations for string code. --HG-- extra : rebase_source : 63ab2c4620cfcd4b764d42d654c82f30f984d016 extra : source : 9115364cd4aa078c49bba7911069f8178e55166f
This commit is contained in:
Родитель
0617c21c24
Коммит
030b39d813
|
@ -15,7 +15,7 @@
|
|||
PR_SetEnv requires its argument to be leaked, but does not appear on stacks. (See bug 793549.)
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZL13SaveWordToEnvPKcRK10nsACString
|
||||
fun:_ZL13SaveWordToEnvPKcRK12nsTSubstringIcE
|
||||
...
|
||||
}
|
||||
{
|
||||
|
|
|
@ -445,17 +445,17 @@ function ignoreContents(entry)
|
|||
/nsTArray_base.*?::EnsureCapacity/,
|
||||
/nsTArray_base.*?::ShiftData/,
|
||||
/AutoTArray.*?::Init/,
|
||||
/nsAC?String::SetCapacity/,
|
||||
/nsAC?String::SetLength/,
|
||||
/nsAC?String::Assign/,
|
||||
/nsAC?String::Append/,
|
||||
/nsAC?String::Replace/,
|
||||
/nsAC?String::Trim/,
|
||||
/nsAC?String::Truncate/,
|
||||
/nsAString::StripTaggedASCII/,
|
||||
/nsAC?String::operator=/,
|
||||
/nsAutoString::nsAutoString/,
|
||||
/nsFixedCString::nsFixedCString/,
|
||||
/nsTSubstring<T>::SetCapacity/,
|
||||
/nsTSubstring<T>::SetLength/,
|
||||
/nsTSubstring<T>::Assign/,
|
||||
/nsTSubstring<T>::Append/,
|
||||
/nsTSubstring<T>::Replace/,
|
||||
/nsTSubstring<T>::Trim/,
|
||||
/nsTSubstring<T>::Truncate/,
|
||||
/nsTSubstring<T>::StripTaggedASCII/,
|
||||
/nsTSubstring<T>::operator=/,
|
||||
/nsTAutoStringN<T, N>::nsTAutoStringN/,
|
||||
/nsTFixedString<T>::nsTFixedString/,
|
||||
|
||||
// Similar for some other data structures
|
||||
/nsCOMArray_base::SetCapacity/,
|
||||
|
|
|
@ -343,7 +343,8 @@ mapped-generic-types = [
|
|||
{ generic = false, gecko = "ServoStyleContextStrong", servo = "::gecko_bindings::sugar::ownership::Strong<::properties::ComputedValues>" },
|
||||
]
|
||||
fixups = [
|
||||
{ pat = "root::nsString", rep = "::nsstring::nsStringRepr" },
|
||||
{ pat = "\\broot::nsString\\b", rep = "::nsstring::nsStringRepr" },
|
||||
{ pat = "\\broot::nsTString<u16>", rep = "::nsstring::nsStringRepr" },
|
||||
]
|
||||
|
||||
[bindings]
|
||||
|
@ -541,6 +542,8 @@ servo-borrow-types = [
|
|||
"RawGeckoStyleChildrenIterator",
|
||||
]
|
||||
fixups = [
|
||||
# Remap the templated string type to the helper type
|
||||
{ pat = "\\bnsTString<u16>", rep = "nsString" },
|
||||
# hack for gecko-owned string
|
||||
{ pat = "<nsString", rep = "<nsStringRepr" },
|
||||
{ pat = "\\b<nsString\\b", rep = "<nsStringRepr" },
|
||||
]
|
||||
|
|
|
@ -19,6 +19,7 @@ EXPORTS += [
|
|||
'nsReadableUtils.h',
|
||||
'nsString.h',
|
||||
'nsStringBuffer.h',
|
||||
'nsStringFlags.h',
|
||||
'nsStringFwd.h',
|
||||
'nsStringIterator.h',
|
||||
'nsSubstring.h',
|
||||
|
@ -29,12 +30,10 @@ EXPORTS += [
|
|||
'nsTLiteralString.h',
|
||||
'nsTPromiseFlatString.h',
|
||||
'nsTString.h',
|
||||
'nsTStringRepr.h',
|
||||
'nsTSubstring.h',
|
||||
'nsTSubstringTuple.h',
|
||||
'nsUTF8Utils.h',
|
||||
'string-template-def-char.h',
|
||||
'string-template-def-unichar.h',
|
||||
'string-template-undef.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
|
@ -49,6 +48,7 @@ UNIFIED_SOURCES += [
|
|||
'nsSubstring.cpp',
|
||||
'nsSubstringTuple.cpp',
|
||||
'nsTextFormatter.cpp',
|
||||
'precompiled_templates.cpp',
|
||||
]
|
||||
|
||||
# Are we targeting x86 or x86-64? If so, compile the SSE2 functions for
|
||||
|
|
|
@ -17,79 +17,9 @@
|
|||
|
||||
#define kNotFound -1
|
||||
|
||||
namespace mozilla {
|
||||
namespace detail {
|
||||
// NOTE: these flags are declared public _only_ for convenience inside
|
||||
// the string implementation. And they are outside of the string
|
||||
// class so that the type is the same for both narrow and wide
|
||||
// strings.
|
||||
|
||||
// bits for mDataFlags
|
||||
enum class StringDataFlags : uint16_t
|
||||
{
|
||||
// Some terminology:
|
||||
//
|
||||
// "dependent buffer" A dependent buffer is one that the string class
|
||||
// does not own. The string class relies on some
|
||||
// external code to ensure the lifetime of the
|
||||
// dependent buffer.
|
||||
//
|
||||
// "shared buffer" A shared buffer is one that the string class
|
||||
// allocates. When it allocates a shared string
|
||||
// buffer, it allocates some additional space at
|
||||
// the beginning of the buffer for additional
|
||||
// fields, including a reference count and a
|
||||
// buffer length. See nsStringHeader.
|
||||
//
|
||||
// "adopted buffer" An adopted buffer is a raw string buffer
|
||||
// allocated on the heap (using moz_xmalloc)
|
||||
// of which the string class subsumes ownership.
|
||||
//
|
||||
// Some comments about the string data flags:
|
||||
//
|
||||
// SHARED, OWNED, and FIXED are all mutually exlusive. They
|
||||
// indicate the allocation type of mData. If none of these flags
|
||||
// are set, then the string buffer is dependent.
|
||||
//
|
||||
// SHARED, OWNED, or FIXED imply TERMINATED. This is because
|
||||
// the string classes always allocate null-terminated buffers, and
|
||||
// non-terminated substrings are always dependent.
|
||||
//
|
||||
// VOIDED implies TERMINATED, and moreover it implies that mData
|
||||
// points to char_traits::sEmptyBuffer. Therefore, VOIDED is
|
||||
// mutually exclusive with SHARED, OWNED, and FIXED.
|
||||
|
||||
TERMINATED = 1 << 0, // IsTerminated returns true
|
||||
VOIDED = 1 << 1, // IsVoid returns true
|
||||
SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
|
||||
OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
|
||||
FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer
|
||||
LITERAL = 1 << 5 // mData points to a string literal; DataFlags::TERMINATED will also be set
|
||||
};
|
||||
|
||||
// bits for mClassFlags
|
||||
enum class StringClassFlags : uint16_t
|
||||
{
|
||||
FIXED = 1 << 0, // |this| is of type nsTFixedString
|
||||
NULL_TERMINATED = 1 << 1 // |this| requires its buffer is null-terminated
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StringDataFlags)
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StringClassFlags)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mozilla
|
||||
|
||||
// declare nsAString
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsStringFlags.h"
|
||||
#include "nsTStringRepr.h"
|
||||
#include "nsTSubstring.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// declare nsACString
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTSubstring.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
|
||||
/**
|
||||
* ASCII case-insensitive comparator. (for Unicode case-insensitive
|
||||
|
|
|
@ -7,12 +7,4 @@
|
|||
#include "nsDependentString.h"
|
||||
#include "nsAlgorithm.h"
|
||||
|
||||
// define nsDependentString
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTDependentString.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// define nsDependentCString
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTDependentString.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
|
|
@ -10,14 +10,7 @@
|
|||
#include "nsString.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
// declare nsDependentString
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTDependentString.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// declare nsDependentCString
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTDependentString.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
#endif /* !defined(nsDependentString_h___) */
|
||||
|
|
|
@ -7,12 +7,4 @@
|
|||
#include "nsDependentSubstring.h"
|
||||
#include "nsAlgorithm.h"
|
||||
|
||||
// define nsDependentSubstring
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTDependentSubstring.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// define nsDependentCSubstring
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTDependentSubstring.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
|
|
@ -8,15 +8,6 @@
|
|||
#define nsDependentSubstring_h___
|
||||
|
||||
#include "nsSubstring.h"
|
||||
|
||||
// declare nsDependentSubstring
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTDependentSubstring.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// declare nsDependentCSubstring
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTDependentSubstring.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
#endif /* !defined(nsDependentSubstring_h___) */
|
||||
|
|
|
@ -10,15 +10,7 @@
|
|||
#include "nscore.h"
|
||||
#include "nsString.h"
|
||||
|
||||
// declare nsLiteralString
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTLiteralString.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// declare nsLiteralCString
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTLiteralString.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
#include "mozilla/Char16.h"
|
||||
|
||||
|
|
|
@ -6,12 +6,4 @@
|
|||
|
||||
#include "nsPromiseFlatString.h"
|
||||
|
||||
// define nsPromiseFlatString
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTPromiseFlatString.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// define nsPromiseFlatCString
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTPromiseFlatString.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
|
|
@ -9,14 +9,6 @@
|
|||
|
||||
#include "nsString.h"
|
||||
|
||||
// declare nsPromiseFlatString
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTPromiseFlatString.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// declare nsPromiseFlatCString
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTPromiseFlatString.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
#endif /* !defined(nsPromiseFlatString_h___) */
|
||||
|
|
|
@ -6,12 +6,4 @@
|
|||
|
||||
#include "nsString.h"
|
||||
|
||||
// define nsString
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTString.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// define nsCString
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTString.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "nsStringFwd.h"
|
||||
|
||||
#include "nsSubstring.h"
|
||||
#include "nsDependentSubstring.h"
|
||||
#include "nsReadableUtils.h"
|
||||
|
@ -27,16 +29,7 @@
|
|||
#define kAutoDetect (100)
|
||||
#endif
|
||||
|
||||
|
||||
// declare nsString, et. al.
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTString.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// declare nsCString, et. al.
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTString.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
static_assert(sizeof(char16_t) == 2, "size of char16_t must be 2");
|
||||
static_assert(sizeof(nsString::char_type) == 2,
|
||||
|
@ -46,6 +39,14 @@ static_assert(nsString::char_type(-1) > nsString::char_type(0),
|
|||
static_assert(sizeof(nsCString::char_type) == 1,
|
||||
"size of nsCString::char_type must be 1");
|
||||
|
||||
static_assert(sizeof(nsTLiteralString<char>) == sizeof(nsTString<char>),
|
||||
"nsLiteralCString can masquerade as nsCString, "
|
||||
"so they must have identical layout");
|
||||
|
||||
static_assert(sizeof(nsTLiteralString<char16_t>) == sizeof(nsTString<char16_t>),
|
||||
"nsTLiteralString can masquerade as nsString, "
|
||||
"so they must have identical layout");
|
||||
|
||||
|
||||
/**
|
||||
* A helper class that converts a UTF-16 string to ASCII in a lossy manner
|
||||
|
@ -60,7 +61,7 @@ public:
|
|||
|
||||
NS_LossyConvertUTF16toASCII(const char16ptr_t aString, uint32_t aLength)
|
||||
{
|
||||
LossyAppendUTF16toASCII(Substring(aString, aLength), *this);
|
||||
LossyAppendUTF16toASCII(Substring(static_cast<const char16_t*>(aString), aLength), *this);
|
||||
}
|
||||
|
||||
explicit NS_LossyConvertUTF16toASCII(const nsAString& aString)
|
||||
|
@ -111,7 +112,7 @@ public:
|
|||
|
||||
NS_ConvertUTF16toUTF8(const char16ptr_t aString, uint32_t aLength)
|
||||
{
|
||||
AppendUTF16toUTF8(Substring(aString, aLength), *this);
|
||||
AppendUTF16toUTF8(Substring(static_cast<const char16_t*>(aString), aLength), *this);
|
||||
}
|
||||
|
||||
explicit NS_ConvertUTF16toUTF8(const nsAString& aString)
|
||||
|
|
|
@ -8,16 +8,7 @@
|
|||
#include "nsAString.h"
|
||||
#include "plstr.h"
|
||||
|
||||
|
||||
// define nsStringComparator
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTStringComparator.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// define nsCStringComparator
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTStringComparator.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
|
||||
int
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsStringFlags_h
|
||||
#define nsStringFlags_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace detail {
|
||||
// NOTE: these flags are declared public _only_ for convenience inside
|
||||
// the string implementation. And they are outside of the string
|
||||
// class so that the type is the same for both narrow and wide
|
||||
// strings.
|
||||
|
||||
// bits for mDataFlags
|
||||
enum class StringDataFlags : uint16_t
|
||||
{
|
||||
// Some terminology:
|
||||
//
|
||||
// "dependent buffer" A dependent buffer is one that the string class
|
||||
// does not own. The string class relies on some
|
||||
// external code to ensure the lifetime of the
|
||||
// dependent buffer.
|
||||
//
|
||||
// "shared buffer" A shared buffer is one that the string class
|
||||
// allocates. When it allocates a shared string
|
||||
// buffer, it allocates some additional space at
|
||||
// the beginning of the buffer for additional
|
||||
// fields, including a reference count and a
|
||||
// buffer length. See nsStringHeader.
|
||||
//
|
||||
// "adopted buffer" An adopted buffer is a raw string buffer
|
||||
// allocated on the heap (using moz_xmalloc)
|
||||
// of which the string class subsumes ownership.
|
||||
//
|
||||
// Some comments about the string data flags:
|
||||
//
|
||||
// SHARED, OWNED, and FIXED are all mutually exlusive. They
|
||||
// indicate the allocation type of mData. If none of these flags
|
||||
// are set, then the string buffer is dependent.
|
||||
//
|
||||
// SHARED, OWNED, or FIXED imply TERMINATED. This is because
|
||||
// the string classes always allocate null-terminated buffers, and
|
||||
// non-terminated substrings are always dependent.
|
||||
//
|
||||
// VOIDED implies TERMINATED, and moreover it implies that mData
|
||||
// points to char_traits::sEmptyBuffer. Therefore, VOIDED is
|
||||
// mutually exclusive with SHARED, OWNED, and FIXED.
|
||||
|
||||
TERMINATED = 1 << 0, // IsTerminated returns true
|
||||
VOIDED = 1 << 1, // IsVoid returns true
|
||||
SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
|
||||
OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
|
||||
FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer
|
||||
LITERAL = 1 << 5 // mData points to a string literal; DataFlags::TERMINATED will also be set
|
||||
};
|
||||
|
||||
// bits for mClassFlags
|
||||
enum class StringClassFlags : uint16_t
|
||||
{
|
||||
FIXED = 1 << 0, // |this| is of type nsTFixedString
|
||||
NULL_TERMINATED = 1 << 1 // |this| requires its buffer is null-terminated
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StringDataFlags)
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(StringClassFlags)
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -14,36 +14,62 @@
|
|||
namespace mozilla {
|
||||
namespace detail {
|
||||
|
||||
class nsStringRepr;
|
||||
class nsCStringRepr;
|
||||
template <typename T> class nsTStringRepr;
|
||||
|
||||
using nsStringRepr = nsTStringRepr<char16_t>;
|
||||
using nsCStringRepr = nsTStringRepr<char>;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mozilla
|
||||
|
||||
static const size_t AutoStringDefaultStorageSize = 64;
|
||||
|
||||
template <typename T> class nsTSubstring;
|
||||
template <typename T> class nsTSubstringTuple;
|
||||
template <typename T> class nsTString;
|
||||
template <typename T, size_t N> class nsTAutoStringN;
|
||||
template <typename T> class nsTDependentString;
|
||||
template <typename T> class nsTDependentSubstring;
|
||||
template <typename T> class nsTPromiseFlatString;
|
||||
template <typename T> class nsTStringComparator;
|
||||
template <typename T> class nsTDefaultStringComparator;
|
||||
template <typename T> class nsTLiteralString;
|
||||
template <typename T> class nsTFixedString;
|
||||
|
||||
// We define this version without a size param instead of providing a
|
||||
// default value for N so that so there is a default typename that doesn't
|
||||
// require angle brackets.
|
||||
template <typename T> using nsTAutoString = nsTAutoStringN<T, AutoStringDefaultStorageSize>;
|
||||
|
||||
|
||||
// Double-byte (char16_t) string types.
|
||||
class nsAString;
|
||||
class nsSubstringTuple;
|
||||
class nsString;
|
||||
template<size_t N> class nsAutoStringN;
|
||||
using nsAutoString = nsAutoStringN<AutoStringDefaultStorageSize>;
|
||||
class nsDependentString;
|
||||
class nsDependentSubstring;
|
||||
class nsPromiseFlatString;
|
||||
class nsStringComparator;
|
||||
class nsDefaultStringComparator;
|
||||
|
||||
using nsAString = nsTSubstring<char16_t>;
|
||||
using nsSubstringTuple = nsTSubstringTuple<char16_t>;
|
||||
using nsString = nsTString<char16_t>;
|
||||
using nsAutoString = nsTAutoString<char16_t>;
|
||||
template <size_t N> using nsAutoStringN = nsTAutoStringN<char16_t, N>;
|
||||
using nsDependentString = nsTDependentString<char16_t>;
|
||||
using nsDependentSubstring = nsTDependentSubstring<char16_t>;
|
||||
using nsPromiseFlatString = nsTPromiseFlatString<char16_t>;
|
||||
using nsStringComparator = nsTStringComparator<char16_t>;
|
||||
using nsDefaultStringComparator = nsTDefaultStringComparator<char16_t>;
|
||||
using nsLiteralString = nsTLiteralString<char16_t>;
|
||||
using nsFixedString = nsTFixedString<char16_t>;
|
||||
|
||||
// Single-byte (char) string types.
|
||||
class nsACString;
|
||||
class nsCSubstringTuple;
|
||||
class nsCString;
|
||||
template<size_t N> class nsAutoCStringN;
|
||||
using nsAutoCString = nsAutoCStringN<AutoStringDefaultStorageSize>;
|
||||
class nsDependentCString;
|
||||
class nsDependentCSubstring;
|
||||
class nsPromiseFlatCString;
|
||||
class nsCStringComparator;
|
||||
class nsDefaultCStringComparator;
|
||||
|
||||
using nsACString = nsTSubstring<char>;
|
||||
using nsCSubstringTuple = nsTSubstringTuple<char>;
|
||||
using nsCString = nsTString<char>;
|
||||
using nsAutoCString = nsTAutoString<char>;
|
||||
template <size_t N> using nsAutoCStringN = nsTAutoStringN<char, N>;
|
||||
using nsDependentCString = nsTDependentString<char>;
|
||||
using nsDependentCSubstring = nsTDependentSubstring<char>;
|
||||
using nsPromiseFlatCString = nsTPromiseFlatString<char>;
|
||||
using nsCStringComparator = nsTStringComparator<char>;
|
||||
using nsDefaultCStringComparator = nsTDefaultStringComparator<char>;
|
||||
using nsLiteralCString = nsTLiteralString<char>;
|
||||
using nsFixedCString = nsTFixedString<char>;
|
||||
|
||||
#endif /* !defined(nsStringFwd_h) */
|
||||
|
|
|
@ -27,8 +27,7 @@ public:
|
|||
typedef const CharT& reference;
|
||||
|
||||
private:
|
||||
friend class mozilla::detail::nsStringRepr;
|
||||
friend class mozilla::detail::nsCStringRepr;
|
||||
friend class mozilla::detail::nsTStringRepr<CharT>;
|
||||
|
||||
// unfortunately, the API for nsReadingIterator requires that the
|
||||
// iterator know its start and end positions. this was needed when
|
||||
|
@ -130,8 +129,7 @@ public:
|
|||
typedef CharT& reference;
|
||||
|
||||
private:
|
||||
friend class nsAString;
|
||||
friend class nsACString;
|
||||
friend class nsTSubstring<CharT>;
|
||||
|
||||
// unfortunately, the API for nsWritingIterator requires that the
|
||||
// iterator know its start and end positions. this was needed when
|
||||
|
|
|
@ -849,78 +849,86 @@ RFind_ComputeSearchRange( uint32_t bigLen, uint32_t littleLen, int32_t& offset,
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// define nsString obsolete methods
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTStringObsolete.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// define nsCString obsolete methods
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTStringObsolete.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// specialized methods:
|
||||
|
||||
template <typename T>
|
||||
template <typename EnableIfChar16>
|
||||
int32_t
|
||||
nsString::Find( const nsString& aString, int32_t aOffset, int32_t aCount ) const
|
||||
nsTString<T>::Find(const self_type& aString, int32_t aOffset, int32_t aCount) const
|
||||
{
|
||||
// this method changes the meaning of aOffset and aCount:
|
||||
Find_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
|
||||
Find_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
|
||||
|
||||
int32_t result = FindSubstring(mData + aOffset, aCount, static_cast<const char16_t*>(aString.get()), aString.Length(), false);
|
||||
// Capture the raw buffer locally to help msvc deduce the type.
|
||||
const char_type* str = aString.get();
|
||||
int32_t result = FindSubstring(this->mData + aOffset, aCount, str, aString.Length(), false);
|
||||
if (result != kNotFound)
|
||||
result += aOffset;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename EnableIfChar16>
|
||||
int32_t
|
||||
nsString::Find( const char16_t* aString, int32_t aOffset, int32_t aCount ) const
|
||||
nsTString<T>::Find(const char_type* aString, int32_t aOffset, int32_t aCount) const
|
||||
{
|
||||
return Find(nsDependentString(aString), aOffset, aCount);
|
||||
return Find(nsTDependentString<T>(aString), aOffset, aCount);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename EnableIfChar16>
|
||||
int32_t
|
||||
nsString::RFind( const nsString& aString, int32_t aOffset, int32_t aCount ) const
|
||||
nsTString<T>::RFind(const self_type& aString, int32_t aOffset, int32_t aCount) const
|
||||
{
|
||||
// this method changes the meaning of aOffset and aCount:
|
||||
RFind_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
|
||||
RFind_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
|
||||
|
||||
int32_t result = RFindSubstring(mData + aOffset, aCount, static_cast<const char16_t*>(aString.get()), aString.Length(), false);
|
||||
// Capture the raw buffer locally to help msvc deduce the type.
|
||||
const char_type* str = aString.get();
|
||||
int32_t result = RFindSubstring(this->mData + aOffset, aCount, str, aString.Length(), false);
|
||||
if (result != kNotFound)
|
||||
result += aOffset;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename EnableIfChar16>
|
||||
int32_t
|
||||
nsString::RFind( const char16_t* aString, int32_t aOffset, int32_t aCount ) const
|
||||
nsTString<T>::RFind(const char_type* aString, int32_t aOffset, int32_t aCount) const
|
||||
{
|
||||
return RFind(nsDependentString(aString), aOffset, aCount);
|
||||
return RFind(nsTDependentString<T>(aString), aOffset, aCount);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename EnableIfChar16>
|
||||
int32_t
|
||||
nsString::FindCharInSet( const char16_t* aSet, int32_t aOffset ) const
|
||||
nsTString<T>::FindCharInSet(const char* aSet, int32_t aOffset) const
|
||||
{
|
||||
if (aOffset < 0)
|
||||
aOffset = 0;
|
||||
else if (aOffset >= int32_t(mLength))
|
||||
else if (aOffset >= int32_t(this->mLength))
|
||||
return kNotFound;
|
||||
|
||||
int32_t result = ::FindCharInSet(mData + aOffset, mLength - aOffset, aSet);
|
||||
int32_t result = ::FindCharInSet(this->mData + aOffset, this->mLength - aOffset, aSet);
|
||||
if (result != kNotFound)
|
||||
result += aOffset;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename EnableIfChar16>
|
||||
void
|
||||
nsString::ReplaceChar( const char16_t* aSet, char16_t aNewChar )
|
||||
nsTString<T>::ReplaceChar(const char* aSet, char16_t aNewChar)
|
||||
{
|
||||
if (!EnsureMutable()) // XXX do this lazily?
|
||||
AllocFailed(mLength);
|
||||
if (!this->EnsureMutable()) // XXX do this lazily?
|
||||
this->AllocFailed(this->mLength);
|
||||
|
||||
char16_t* data = mData;
|
||||
uint32_t lenRemaining = mLength;
|
||||
char16_t* data = this->mData;
|
||||
uint32_t lenRemaining = this->mLength;
|
||||
|
||||
while (lenRemaining)
|
||||
{
|
||||
|
@ -939,12 +947,14 @@ nsString::ReplaceChar( const char16_t* aSet, char16_t aNewChar )
|
|||
* nsTString::Compare,CompareWithConversion,etc.
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
template <typename EnableIfChar>
|
||||
int32_t
|
||||
nsCString::Compare( const char* aString, bool aIgnoreCase, int32_t aCount ) const
|
||||
nsTString<T>::Compare(const char_type* aString, bool aIgnoreCase, int32_t aCount) const
|
||||
{
|
||||
uint32_t strLen = char_traits::length(aString);
|
||||
|
||||
int32_t maxCount = int32_t(XPCOM_MIN(mLength, strLen));
|
||||
int32_t maxCount = int32_t(XPCOM_MIN(this->mLength, strLen));
|
||||
|
||||
int32_t compareCount;
|
||||
if (aCount < 0 || aCount > maxCount)
|
||||
|
@ -953,27 +963,29 @@ nsCString::Compare( const char* aString, bool aIgnoreCase, int32_t aCount ) cons
|
|||
compareCount = aCount;
|
||||
|
||||
int32_t result =
|
||||
nsBufferRoutines<char>::compare(mData, aString, compareCount, aIgnoreCase);
|
||||
nsBufferRoutines<T>::compare(this->mData, aString, compareCount, aIgnoreCase);
|
||||
|
||||
if (result == 0 &&
|
||||
(aCount < 0 || strLen < uint32_t(aCount) || mLength < uint32_t(aCount)))
|
||||
(aCount < 0 || strLen < uint32_t(aCount) || this->mLength < uint32_t(aCount)))
|
||||
{
|
||||
// Since the caller didn't give us a length to test, or strings shorter
|
||||
// than aCount, and compareCount characters matched, we have to assume
|
||||
// that the longer string is greater.
|
||||
|
||||
if (mLength != strLen)
|
||||
result = (mLength < strLen) ? -1 : 1;
|
||||
if (this->mLength != strLen)
|
||||
result = (this->mLength < strLen) ? -1 : 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename EnableIfChar16>
|
||||
bool
|
||||
nsString::EqualsIgnoreCase( const char* aString, int32_t aCount ) const
|
||||
nsTString<T>::EqualsIgnoreCase(const incompatible_char_type* aString, int32_t aCount) const
|
||||
{
|
||||
uint32_t strLen = nsCharTraits<char>::length(aString);
|
||||
|
||||
int32_t maxCount = int32_t(XPCOM_MIN(mLength, strLen));
|
||||
int32_t maxCount = int32_t(XPCOM_MIN(this->mLength, strLen));
|
||||
|
||||
int32_t compareCount;
|
||||
if (aCount < 0 || aCount > maxCount)
|
||||
|
@ -982,16 +994,16 @@ nsString::EqualsIgnoreCase( const char* aString, int32_t aCount ) const
|
|||
compareCount = aCount;
|
||||
|
||||
int32_t result =
|
||||
nsBufferRoutines<char16_t>::compare(mData, aString, compareCount, true);
|
||||
nsBufferRoutines<T>::compare(this->mData, aString, compareCount, true);
|
||||
|
||||
if (result == 0 &&
|
||||
(aCount < 0 || strLen < uint32_t(aCount) || mLength < uint32_t(aCount)))
|
||||
(aCount < 0 || strLen < uint32_t(aCount) || this->mLength < uint32_t(aCount)))
|
||||
{
|
||||
// Since the caller didn't give us a length to test, or strings shorter
|
||||
// than aCount, and compareCount characters matched, we have to assume
|
||||
// that the longer string is greater.
|
||||
|
||||
if (mLength != strLen)
|
||||
if (this->mLength != strLen)
|
||||
result = 1; // Arbitrarily using any number != 0
|
||||
}
|
||||
return result == 0;
|
||||
|
@ -1002,17 +1014,18 @@ nsString::EqualsIgnoreCase( const char* aString, int32_t aCount ) const
|
|||
* nsTString::ToDouble
|
||||
*/
|
||||
|
||||
template <>
|
||||
double
|
||||
nsCString::ToDouble(nsresult* aErrorCode) const
|
||||
nsTString<char>::ToDouble(nsresult* aErrorCode) const
|
||||
{
|
||||
double res = 0.0;
|
||||
if (mLength > 0)
|
||||
if (this->mLength > 0)
|
||||
{
|
||||
char *conv_stopped;
|
||||
const char *str = mData;
|
||||
const char *str = this->mData;
|
||||
// Use PR_strtod, not strtod, since we don't want locale involved.
|
||||
res = PR_strtod(str, &conv_stopped);
|
||||
if (conv_stopped == str+mLength)
|
||||
if (conv_stopped == str+this->mLength)
|
||||
*aErrorCode = NS_OK;
|
||||
else // Not all the string was scanned
|
||||
*aErrorCode = NS_ERROR_ILLEGAL_VALUE;
|
||||
|
@ -1025,10 +1038,21 @@ nsCString::ToDouble(nsresult* aErrorCode) const
|
|||
return res;
|
||||
}
|
||||
|
||||
template <>
|
||||
double
|
||||
nsString::ToDouble(nsresult* aErrorCode) const
|
||||
nsTString<char16_t>::ToDouble(nsresult* aErrorCode) const
|
||||
{
|
||||
return NS_LossyConvertUTF16toASCII(*this).ToDouble(aErrorCode);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
float
|
||||
nsTString<T>::ToFloat(nsresult* aErrorCode) const
|
||||
{
|
||||
return (float)ToDouble(aErrorCode);
|
||||
}
|
||||
|
||||
template class nsTString<char>;
|
||||
template class nsTString<char16_t>;
|
||||
|
||||
#endif // !MOZ_STRING_WITH_OBSOLETE_API
|
||||
|
|
|
@ -352,14 +352,7 @@ nsStringBuffer::SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSiz
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
// define nsAString
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTSubstring.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// define nsACString
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTSubstring.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// Provide rust bindings to the nsA[C]String types
|
||||
extern "C" {
|
||||
|
|
|
@ -6,12 +6,4 @@
|
|||
|
||||
#include "nsSubstringTuple.h"
|
||||
|
||||
// define nsSubstringTuple
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTSubstringTuple.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// define nsCSubstringTuple
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTSubstringTuple.cpp"
|
||||
#include "string-template-undef.h"
|
||||
|
|
|
@ -9,14 +9,6 @@
|
|||
|
||||
#include "nsSubstring.h"
|
||||
|
||||
// declare nsSubstringTuple
|
||||
#include "string-template-def-unichar.h"
|
||||
#include "nsTSubstringTuple.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
// declare nsCSubstringTuple
|
||||
#include "string-template-def-char.h"
|
||||
#include "nsTSubstringTuple.h"
|
||||
#include "string-template-undef.h"
|
||||
|
||||
#endif // !defined(nsSubstringTuple_h___)
|
||||
|
|
|
@ -4,22 +4,24 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
nsTDependentString_CharT::nsTDependentString_CharT(const char_type* aStart,
|
||||
const char_type* aEnd)
|
||||
template <typename T>
|
||||
nsTDependentString<T>::nsTDependentString(const char_type* aStart,
|
||||
const char_type* aEnd)
|
||||
: string_type(const_cast<char_type*>(aStart), uint32_t(aEnd - aStart),
|
||||
DataFlags::TERMINATED, ClassFlags(0))
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aStart <= aEnd, "Overflow!");
|
||||
AssertValidDependentString();
|
||||
this->AssertValidDependentString();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTDependentString_CharT::Rebind(const string_type& str, uint32_t startPos)
|
||||
nsTDependentString<T>::Rebind(const string_type& str, uint32_t startPos)
|
||||
{
|
||||
MOZ_ASSERT(str.GetDataFlags() & DataFlags::TERMINATED, "Unterminated flat string");
|
||||
|
||||
// If we currently own a buffer, release it.
|
||||
Finalize();
|
||||
this->Finalize();
|
||||
|
||||
size_type strLength = str.Length();
|
||||
|
||||
|
@ -31,12 +33,13 @@ nsTDependentString_CharT::Rebind(const string_type& str, uint32_t startPos)
|
|||
const_cast<char_type*>(static_cast<const char_type*>(str.Data())) + startPos;
|
||||
size_type newLen = strLength - startPos;
|
||||
DataFlags newDataFlags = str.GetDataFlags() & (DataFlags::TERMINATED | DataFlags::LITERAL);
|
||||
SetData(newData, newLen, newDataFlags);
|
||||
this->SetData(newData, newLen, newDataFlags);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTDependentString_CharT::Rebind(const char_type* aStart, const char_type* aEnd)
|
||||
nsTDependentString<T>::Rebind(const char_type* aStart, const char_type* aEnd)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aStart <= aEnd, "Overflow!");
|
||||
Rebind(aStart, uint32_t(aEnd - aStart));
|
||||
this->Rebind(aStart, uint32_t(aEnd - aStart));
|
||||
}
|
||||
|
|
|
@ -4,9 +4,13 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsTDependentString_h
|
||||
#define nsTDependentString_h
|
||||
|
||||
#include "nsTString.h"
|
||||
|
||||
/**
|
||||
* nsTDependentString_CharT
|
||||
* nsTDependentString
|
||||
*
|
||||
* Stores a null-terminated, immutable sequence of characters.
|
||||
*
|
||||
|
@ -16,11 +20,41 @@
|
|||
* nsTDependentString continues to reference valid memory for the
|
||||
* duration of its use.
|
||||
*/
|
||||
class nsTDependentString_CharT : public nsTString_CharT
|
||||
template <typename T>
|
||||
class nsTDependentString : public nsTString<T>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef nsTDependentString_CharT self_type;
|
||||
typedef nsTDependentString<T> self_type;
|
||||
typedef nsTString<T> base_string_type;
|
||||
typedef typename base_string_type::string_type string_type;
|
||||
|
||||
typedef typename base_string_type::fallible_t fallible_t;
|
||||
|
||||
typedef typename base_string_type::char_type char_type;
|
||||
typedef typename base_string_type::char_traits char_traits;
|
||||
typedef typename base_string_type::incompatible_char_type incompatible_char_type;
|
||||
|
||||
typedef typename base_string_type::substring_tuple_type substring_tuple_type;
|
||||
|
||||
typedef typename base_string_type::const_iterator const_iterator;
|
||||
typedef typename base_string_type::iterator iterator;
|
||||
|
||||
typedef typename base_string_type::comparator_type comparator_type;
|
||||
|
||||
typedef typename base_string_type::char_iterator char_iterator;
|
||||
typedef typename base_string_type::const_char_iterator const_char_iterator;
|
||||
|
||||
typedef typename base_string_type::index_type index_type;
|
||||
typedef typename base_string_type::size_type size_type;
|
||||
|
||||
// These are only for internal use within the string classes:
|
||||
typedef typename base_string_type::DataFlags DataFlags;
|
||||
typedef typename base_string_type::ClassFlags ClassFlags;
|
||||
|
||||
using typename base_string_type::IsChar;
|
||||
using typename base_string_type::IsChar16;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
@ -28,47 +62,49 @@ public:
|
|||
* constructors
|
||||
*/
|
||||
|
||||
nsTDependentString_CharT(const char_type* aStart, const char_type* aEnd);
|
||||
nsTDependentString(const char_type* aStart, const char_type* aEnd);
|
||||
|
||||
nsTDependentString_CharT(const char_type* aData, uint32_t aLength)
|
||||
nsTDependentString(const char_type* aData, uint32_t aLength)
|
||||
: string_type(const_cast<char_type*>(aData), aLength,
|
||||
DataFlags::TERMINATED, ClassFlags(0))
|
||||
{
|
||||
AssertValidDependentString();
|
||||
this->AssertValidDependentString();
|
||||
}
|
||||
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
nsTDependentString_CharT(char16ptr_t aData, uint32_t aLength)
|
||||
: nsTDependentString_CharT(static_cast<const char16_t*>(aData), aLength)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
nsTDependentString(char16ptr_t aData, uint32_t aLength)
|
||||
: nsTDependentString(static_cast<const char16_t*>(aData), aLength)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
explicit
|
||||
nsTDependentString_CharT(const char_type* aData)
|
||||
nsTDependentString(const char_type* aData)
|
||||
: string_type(const_cast<char_type*>(aData),
|
||||
uint32_t(char_traits::length(aData)),
|
||||
DataFlags::TERMINATED, ClassFlags(0))
|
||||
{
|
||||
AssertValidDependentString();
|
||||
string_type::AssertValidDependentString();
|
||||
}
|
||||
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
explicit
|
||||
nsTDependentString_CharT(char16ptr_t aData)
|
||||
: nsTDependentString_CharT(static_cast<const char16_t*>(aData))
|
||||
nsTDependentString(char16ptr_t aData)
|
||||
: nsTDependentString(static_cast<const char16_t*>(aData))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
nsTDependentString_CharT(const string_type& aStr, uint32_t aStartPos)
|
||||
nsTDependentString(const string_type& aStr, uint32_t aStartPos)
|
||||
: string_type()
|
||||
{
|
||||
Rebind(aStr, aStartPos);
|
||||
}
|
||||
|
||||
// Create a nsTDependentSubstring to be bound later
|
||||
nsTDependentString_CharT()
|
||||
nsTDependentString()
|
||||
: string_type()
|
||||
{
|
||||
}
|
||||
|
@ -83,7 +119,7 @@ public:
|
|||
* allow this class to be bound to a different string...
|
||||
*/
|
||||
|
||||
using nsTString_CharT::Rebind;
|
||||
using nsTString<T>::Rebind;
|
||||
void Rebind(const char_type* aData)
|
||||
{
|
||||
Rebind(aData, uint32_t(char_traits::length(aData)));
|
||||
|
@ -95,5 +131,10 @@ public:
|
|||
private:
|
||||
|
||||
// NOT USED
|
||||
nsTDependentString_CharT(const substring_tuple_type&) = delete;
|
||||
nsTDependentString(const substring_tuple_type&) = delete;
|
||||
};
|
||||
|
||||
extern template class nsTDependentString<char>;
|
||||
extern template class nsTDependentString<char16_t>;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTDependentSubstring_CharT::Rebind(const substring_type& str,
|
||||
nsTDependentSubstring<T>::Rebind(const substring_type& str,
|
||||
uint32_t startPos, uint32_t length)
|
||||
{
|
||||
// If we currently own a buffer, release it.
|
||||
Finalize();
|
||||
this->Finalize();
|
||||
|
||||
size_type strLength = str.Length();
|
||||
|
||||
|
@ -21,44 +22,49 @@ nsTDependentSubstring_CharT::Rebind(const substring_type& str,
|
|||
const_cast<char_type*>(static_cast<const char_type*>(str.Data())) + startPos;
|
||||
size_type newLength = XPCOM_MIN(length, strLength - startPos);
|
||||
DataFlags newDataFlags = DataFlags(0);
|
||||
SetData(newData, newLength, newDataFlags);
|
||||
this->SetData(newData, newLength, newDataFlags);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTDependentSubstring_CharT::Rebind(const char_type* data, size_type length)
|
||||
nsTDependentSubstring<T>::Rebind(const char_type* data, size_type length)
|
||||
{
|
||||
NS_ASSERTION(data, "nsTDependentSubstring must wrap a non-NULL buffer");
|
||||
|
||||
// If we currently own a buffer, release it.
|
||||
Finalize();
|
||||
this->Finalize();
|
||||
|
||||
char_type* newData =
|
||||
const_cast<char_type*>(static_cast<const char_type*>(data));
|
||||
size_type newLength = length;
|
||||
DataFlags newDataFlags = DataFlags(0);
|
||||
SetData(newData, newLength, newDataFlags);
|
||||
this->SetData(newData, newLength, newDataFlags);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTDependentSubstring_CharT::Rebind(const char_type* aStart, const char_type* aEnd)
|
||||
nsTDependentSubstring<T>::Rebind(const char_type* aStart, const char_type* aEnd)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aStart <= aEnd, "Overflow!");
|
||||
Rebind(aStart, size_type(aEnd - aStart));
|
||||
this->Rebind(aStart, size_type(aEnd - aStart));
|
||||
}
|
||||
|
||||
nsTDependentSubstring_CharT::nsTDependentSubstring_CharT(const char_type* aStart,
|
||||
const char_type* aEnd)
|
||||
template <typename T>
|
||||
nsTDependentSubstring<T>::nsTDependentSubstring(const char_type* aStart,
|
||||
const char_type* aEnd)
|
||||
: substring_type(const_cast<char_type*>(aStart), uint32_t(aEnd - aStart),
|
||||
DataFlags(0), ClassFlags(0))
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aStart <= aEnd, "Overflow!");
|
||||
}
|
||||
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
nsTDependentSubstring_CharT::nsTDependentSubstring_CharT(char16ptr_t aStart,
|
||||
char16ptr_t aEnd)
|
||||
: nsTDependentSubstring_CharT(static_cast<const char16_t*>(aStart),
|
||||
static_cast<const char16_t*>(aEnd))
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename T>
|
||||
template <typename EnableIfChar16>
|
||||
nsTDependentSubstring<T>::nsTDependentSubstring(char16ptr_t aStart,
|
||||
char16ptr_t aEnd)
|
||||
: substring_type(static_cast<const char16_t*>(aStart),
|
||||
static_cast<const char16_t*>(aEnd))
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(static_cast<const char16_t*>(aStart) <=
|
||||
static_cast<const char16_t*>(aEnd),
|
||||
|
@ -66,8 +72,9 @@ nsTDependentSubstring_CharT::nsTDependentSubstring_CharT(char16ptr_t aStart,
|
|||
}
|
||||
#endif
|
||||
|
||||
nsTDependentSubstring_CharT::nsTDependentSubstring_CharT(const const_iterator& aStart,
|
||||
const const_iterator& aEnd)
|
||||
template <typename T>
|
||||
nsTDependentSubstring<T>::nsTDependentSubstring(const const_iterator& aStart,
|
||||
const const_iterator& aEnd)
|
||||
: substring_type(const_cast<char_type*>(aStart.get()),
|
||||
uint32_t(aEnd.get() - aStart.get()),
|
||||
DataFlags(0), ClassFlags(0))
|
||||
|
@ -75,9 +82,25 @@ nsTDependentSubstring_CharT::nsTDependentSubstring_CharT(const const_iterator& a
|
|||
MOZ_RELEASE_ASSERT(aStart.get() <= aEnd.get(), "Overflow!");
|
||||
}
|
||||
|
||||
const nsTDependentSubstring_CharT
|
||||
Substring(const CharT* aStart, const CharT* aEnd)
|
||||
template <typename T>
|
||||
const nsTDependentSubstring<T>
|
||||
Substring(const T* aStart, const T* aEnd)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aStart <= aEnd, "Overflow!");
|
||||
return nsTDependentSubstring_CharT(aStart, aEnd);
|
||||
return nsTDependentSubstring<T>(aStart, aEnd);
|
||||
}
|
||||
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
const nsTDependentSubstring<char16_t>
|
||||
Substring(char16ptr_t aData, uint32_t aLength)
|
||||
{
|
||||
return nsTDependentSubstring<char16_t>(aData, aLength);
|
||||
}
|
||||
|
||||
const nsTDependentSubstring<char16_t>
|
||||
Substring(char16ptr_t aStart, char16ptr_t aEnd)
|
||||
{
|
||||
return Substring(static_cast<const char16_t*>(aStart),
|
||||
static_cast<const char16_t*>(aEnd));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
// IWYU pragma: private, include "nsString.h"
|
||||
|
||||
#ifndef nsTDependentSubstring_h
|
||||
#define nsTDependentSubstring_h
|
||||
|
||||
#include "nsTSubstring.h"
|
||||
#include "nsTLiteralString.h"
|
||||
|
||||
/**
|
||||
* nsTDependentSubstring_CharT
|
||||
*
|
||||
|
@ -16,11 +22,38 @@
|
|||
* nsDependentSubstring for wide characters
|
||||
* nsDependentCSubstring for narrow characters
|
||||
*/
|
||||
class nsTDependentSubstring_CharT : public nsTSubstring_CharT
|
||||
template <typename T>
|
||||
class nsTDependentSubstring : public nsTSubstring<T>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef nsTDependentSubstring_CharT self_type;
|
||||
typedef nsTDependentSubstring<T> self_type;
|
||||
typedef nsTSubstring<T> substring_type;
|
||||
typedef typename substring_type::fallible_t fallible_t;
|
||||
|
||||
typedef typename substring_type::char_type char_type;
|
||||
typedef typename substring_type::char_traits char_traits;
|
||||
typedef typename substring_type::incompatible_char_type incompatible_char_type;
|
||||
|
||||
typedef typename substring_type::substring_tuple_type substring_tuple_type;
|
||||
|
||||
typedef typename substring_type::const_iterator const_iterator;
|
||||
typedef typename substring_type::iterator iterator;
|
||||
|
||||
typedef typename substring_type::comparator_type comparator_type;
|
||||
|
||||
typedef typename substring_type::char_iterator char_iterator;
|
||||
typedef typename substring_type::const_char_iterator const_char_iterator;
|
||||
|
||||
typedef typename substring_type::index_type index_type;
|
||||
typedef typename substring_type::size_type size_type;
|
||||
|
||||
// These are only for internal use within the string classes:
|
||||
typedef typename substring_type::DataFlags DataFlags;
|
||||
typedef typename substring_type::ClassFlags ClassFlags;
|
||||
|
||||
using typename substring_type::IsChar;
|
||||
using typename substring_type::IsChar16;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -31,35 +64,37 @@ public:
|
|||
|
||||
void Rebind(const char_type* aStart, const char_type* aEnd);
|
||||
|
||||
nsTDependentSubstring_CharT(const substring_type& aStr, uint32_t aStartPos,
|
||||
uint32_t aLength = size_type(-1))
|
||||
nsTDependentSubstring(const substring_type& aStr, uint32_t aStartPos,
|
||||
uint32_t aLength = size_type(-1))
|
||||
: substring_type()
|
||||
{
|
||||
Rebind(aStr, aStartPos, aLength);
|
||||
}
|
||||
|
||||
nsTDependentSubstring_CharT(const char_type* aData, size_type aLength)
|
||||
nsTDependentSubstring(const char_type* aData, size_type aLength)
|
||||
: substring_type(const_cast<char_type*>(aData), aLength,
|
||||
DataFlags(0), ClassFlags(0))
|
||||
{
|
||||
}
|
||||
|
||||
nsTDependentSubstring_CharT(const char_type* aStart, const char_type* aEnd);
|
||||
nsTDependentSubstring(const char_type* aStart, const char_type* aEnd);
|
||||
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
nsTDependentSubstring_CharT(char16ptr_t aData, size_type aLength)
|
||||
: nsTDependentSubstring_CharT(static_cast<const char16_t*>(aData), aLength)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
nsTDependentSubstring(char16ptr_t aData, size_type aLength)
|
||||
: nsTDependentSubstring(static_cast<const char16_t*>(aData), aLength)
|
||||
{
|
||||
}
|
||||
|
||||
nsTDependentSubstring_CharT(char16ptr_t aStart, char16ptr_t aEnd);
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
nsTDependentSubstring(char16ptr_t aStart, char16ptr_t aEnd);
|
||||
#endif
|
||||
|
||||
nsTDependentSubstring_CharT(const const_iterator& aStart,
|
||||
const const_iterator& aEnd);
|
||||
nsTDependentSubstring(const const_iterator& aStart,
|
||||
const const_iterator& aEnd);
|
||||
|
||||
// Create a nsTDependentSubstring to be bound later
|
||||
nsTDependentSubstring_CharT()
|
||||
nsTDependentSubstring()
|
||||
: substring_type()
|
||||
{
|
||||
}
|
||||
|
@ -71,37 +106,64 @@ private:
|
|||
void operator=(const self_type&); // we're immutable, you can't assign into a substring
|
||||
};
|
||||
|
||||
inline const nsTDependentSubstring_CharT
|
||||
Substring(const nsTSubstring_CharT& aStr, uint32_t aStartPos,
|
||||
extern template class nsTDependentSubstring<char>;
|
||||
extern template class nsTDependentSubstring<char16_t>;
|
||||
|
||||
template <typename T>
|
||||
inline const nsTDependentSubstring<T>
|
||||
Substring(const nsTSubstring<T>& aStr, uint32_t aStartPos,
|
||||
uint32_t aLength = uint32_t(-1))
|
||||
{
|
||||
return nsTDependentSubstring_CharT(aStr, aStartPos, aLength);
|
||||
return nsTDependentSubstring<T>(aStr, aStartPos, aLength);
|
||||
}
|
||||
|
||||
inline const nsTDependentSubstring_CharT
|
||||
Substring(const nsReadingIterator<CharT>& aStart,
|
||||
const nsReadingIterator<CharT>& aEnd)
|
||||
template <typename T>
|
||||
inline const nsTDependentSubstring<T>
|
||||
Substring(const nsTLiteralString<T>& aStr, uint32_t aStartPos,
|
||||
uint32_t aLength = uint32_t(-1))
|
||||
{
|
||||
return nsTDependentSubstring_CharT(aStart.get(), aEnd.get());
|
||||
return nsTDependentSubstring<T>(aStr, aStartPos, aLength);
|
||||
}
|
||||
|
||||
inline const nsTDependentSubstring_CharT
|
||||
Substring(const CharT* aData, uint32_t aLength)
|
||||
template <typename T>
|
||||
inline const nsTDependentSubstring<T>
|
||||
Substring(const nsReadingIterator<T>& aStart,
|
||||
const nsReadingIterator<T>& aEnd)
|
||||
{
|
||||
return nsTDependentSubstring_CharT(aData, aLength);
|
||||
return nsTDependentSubstring<T>(aStart.get(), aEnd.get());
|
||||
}
|
||||
|
||||
const nsTDependentSubstring_CharT
|
||||
Substring(const CharT* aStart, const CharT* aEnd);
|
||||
|
||||
inline const nsTDependentSubstring_CharT
|
||||
StringHead(const nsTSubstring_CharT& aStr, uint32_t aCount)
|
||||
template <typename T>
|
||||
inline const nsTDependentSubstring<T>
|
||||
Substring(const T* aData, uint32_t aLength)
|
||||
{
|
||||
return nsTDependentSubstring_CharT(aStr, 0, aCount);
|
||||
return nsTDependentSubstring<T>(aData, aLength);
|
||||
}
|
||||
|
||||
inline const nsTDependentSubstring_CharT
|
||||
StringTail(const nsTSubstring_CharT& aStr, uint32_t aCount)
|
||||
template <typename T>
|
||||
const nsTDependentSubstring<T>
|
||||
Substring(const T* aStart, const T* aEnd);
|
||||
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
inline const nsTDependentSubstring<char16_t>
|
||||
Substring(char16ptr_t aData, uint32_t aLength);
|
||||
|
||||
const nsTDependentSubstring<char16_t>
|
||||
Substring(char16ptr_t aStart, char16ptr_t aEnd);
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline const nsTDependentSubstring<T>
|
||||
StringHead(const nsTSubstring<T>& aStr, uint32_t aCount)
|
||||
{
|
||||
return nsTDependentSubstring_CharT(aStr, aStr.Length() - aCount, aCount);
|
||||
return nsTDependentSubstring<T>(aStr, 0, aCount);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const nsTDependentSubstring<T>
|
||||
StringTail(const nsTSubstring<T>& aStr, uint32_t aCount)
|
||||
{
|
||||
return nsTDependentSubstring<T>(aStr, aStr.Length() - aCount, aCount);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsTLiteralString_h
|
||||
#define nsTLiteralString_h
|
||||
|
||||
#include "nsTStringRepr.h"
|
||||
|
||||
/**
|
||||
* nsTLiteralString_CharT
|
||||
*
|
||||
|
@ -15,11 +20,17 @@
|
|||
* to be static (permanent) and therefore, as an optimization, this class
|
||||
* does not have a destructor.
|
||||
*/
|
||||
class nsTLiteralString_CharT : public mozilla::detail::nsTStringRepr_CharT
|
||||
template<typename T>
|
||||
class nsTLiteralString : public mozilla::detail::nsTStringRepr<T>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef nsTLiteralString_CharT self_type;
|
||||
typedef nsTLiteralString<T> self_type;
|
||||
typedef typename mozilla::detail::nsTStringRepr<T>::base_string_type base_string_type;
|
||||
typedef typename base_string_type::char_type char_type;
|
||||
typedef typename base_string_type::size_type size_type;
|
||||
typedef typename base_string_type::DataFlags DataFlags;
|
||||
typedef typename base_string_type::ClassFlags ClassFlags;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -28,7 +39,7 @@ public:
|
|||
*/
|
||||
|
||||
template<size_type N>
|
||||
explicit constexpr nsTLiteralString_CharT(const char_type (&aStr)[N])
|
||||
explicit constexpr nsTLiteralString(const char_type (&aStr)[N])
|
||||
: base_string_type(const_cast<char_type*>(aStr), N - 1,
|
||||
DataFlags::TERMINATED | DataFlags::LITERAL,
|
||||
ClassFlags::NULL_TERMINATED)
|
||||
|
@ -40,40 +51,42 @@ public:
|
|||
* Use sparingly. If possible, rewrite code to use const ns[C]String&
|
||||
* and the implicit cast will just work.
|
||||
*/
|
||||
const nsTString_CharT& AsString() const
|
||||
const nsTString<T>& AsString() const
|
||||
{
|
||||
return *reinterpret_cast<const nsTString_CharT*>(this);
|
||||
return *reinterpret_cast<const nsTString<T>*>(this);
|
||||
}
|
||||
|
||||
operator const nsTString_CharT&() const
|
||||
operator const nsTString<T>&() const
|
||||
{
|
||||
return AsString();
|
||||
}
|
||||
|
||||
template<typename N> struct raw_type { typedef N* type; };
|
||||
|
||||
#ifdef MOZ_USE_CHAR16_WRAPPER
|
||||
template<> struct raw_type<char16_t> { typedef char16ptr_t type; };
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Prohibit get() on temporaries as in nsLiteralCString("x").get().
|
||||
* These should be written as just "x", using a string literal directly.
|
||||
*/
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
char16ptr_t get() const && = delete;
|
||||
char16ptr_t get() const &
|
||||
#else
|
||||
const char_type* get() const && = delete;
|
||||
const char_type* get() const &
|
||||
#endif
|
||||
const typename raw_type<T>::type get() const && = delete;
|
||||
const typename raw_type<T>::type get() const &
|
||||
{
|
||||
return mData;
|
||||
return this->mData;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// NOT TO BE IMPLEMENTED
|
||||
template<size_type N>
|
||||
nsTLiteralString_CharT(char_type (&aStr)[N]) = delete;
|
||||
nsTLiteralString(char_type (&aStr)[N]) = delete;
|
||||
|
||||
self_type& operator=(const self_type&) = delete;
|
||||
};
|
||||
|
||||
static_assert(sizeof(nsTLiteralString_CharT) == sizeof(nsTString_CharT),
|
||||
"nsTLiteralString_CharT can masquerade as nsTString_CharT, "
|
||||
"so they must have identical layout");
|
||||
extern template class nsTLiteralString<char>;
|
||||
extern template class nsTLiteralString<char16_t>;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTPromiseFlatString_CharT::Init(const substring_type& str)
|
||||
nsTPromiseFlatString<T>::Init(const substring_type& str)
|
||||
{
|
||||
if (str.IsTerminated()) {
|
||||
char_type* newData =
|
||||
|
@ -15,8 +16,8 @@ nsTPromiseFlatString_CharT::Init(const substring_type& str)
|
|||
str.GetDataFlags() & (DataFlags::TERMINATED | DataFlags::LITERAL);
|
||||
// does not promote DataFlags::VOIDED
|
||||
|
||||
SetData(newData, newLength, newDataFlags);
|
||||
this->SetData(newData, newLength, newDataFlags);
|
||||
} else {
|
||||
Assign(str);
|
||||
this->Assign(str);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsTPromiseFlatString_h
|
||||
#define nsTPromiseFlatString_h
|
||||
|
||||
#include "nsTString.h"
|
||||
|
||||
/**
|
||||
* NOTE:
|
||||
|
@ -64,11 +68,22 @@
|
|||
* string (e.g., |nsTString|), the right thing happens.
|
||||
*/
|
||||
|
||||
class nsTPromiseFlatString_CharT : public nsTString_CharT
|
||||
template <typename T>
|
||||
class nsTPromiseFlatString : public nsTString<T>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef nsTPromiseFlatString_CharT self_type;
|
||||
typedef nsTPromiseFlatString<T> self_type;
|
||||
typedef nsTString<T> base_string_type;
|
||||
typedef typename base_string_type::substring_type substring_type;
|
||||
typedef typename base_string_type::string_type string_type;
|
||||
typedef typename base_string_type::substring_tuple_type substring_tuple_type;
|
||||
typedef typename base_string_type::char_type char_type;
|
||||
typedef typename base_string_type::size_type size_type;
|
||||
|
||||
// These are only for internal use within the string classes:
|
||||
typedef typename base_string_type::DataFlags DataFlags;
|
||||
typedef typename base_string_type::ClassFlags ClassFlags;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -78,35 +93,55 @@ private:
|
|||
void operator=(const self_type&) = delete;
|
||||
|
||||
// NOT TO BE IMPLEMENTED
|
||||
nsTPromiseFlatString_CharT() = delete;
|
||||
nsTPromiseFlatString() = delete;
|
||||
|
||||
// NOT TO BE IMPLEMENTED
|
||||
nsTPromiseFlatString_CharT(const string_type& aStr) = delete;
|
||||
nsTPromiseFlatString(const string_type& aStr) = delete;
|
||||
|
||||
public:
|
||||
|
||||
explicit
|
||||
nsTPromiseFlatString_CharT(const substring_type& aStr)
|
||||
nsTPromiseFlatString(const substring_type& aStr)
|
||||
: string_type()
|
||||
{
|
||||
Init(aStr);
|
||||
}
|
||||
|
||||
explicit
|
||||
nsTPromiseFlatString_CharT(const substring_tuple_type& aTuple)
|
||||
nsTPromiseFlatString(const substring_tuple_type& aTuple)
|
||||
: string_type()
|
||||
{
|
||||
// nothing else to do here except assign the value of the tuple
|
||||
// into ourselves.
|
||||
Assign(aTuple);
|
||||
this->Assign(aTuple);
|
||||
}
|
||||
};
|
||||
|
||||
extern template class nsTPromiseFlatString<char>;
|
||||
extern template class nsTPromiseFlatString<char16_t>;
|
||||
|
||||
// We template this so that the constructor is chosen based on the type of the
|
||||
// parameter. This allows us to reject attempts to promise a flat flat string.
|
||||
template<class T>
|
||||
const nsTPromiseFlatString_CharT
|
||||
TPromiseFlatString_CharT(const T& aString)
|
||||
const nsTPromiseFlatString<T>
|
||||
TPromiseFlatString(const typename nsTPromiseFlatString<T>::substring_type& aString)
|
||||
{
|
||||
return nsTPromiseFlatString_CharT(aString);
|
||||
return nsTPromiseFlatString<T>(aString);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const nsTPromiseFlatString<T>
|
||||
TPromiseFlatString(const typename nsTPromiseFlatString<T>::substring_tuple_type& aString)
|
||||
{
|
||||
return nsTPromiseFlatString<T>(aString);
|
||||
}
|
||||
|
||||
#ifndef PromiseFlatCString
|
||||
#define PromiseFlatCString TPromiseFlatString<char>
|
||||
#endif
|
||||
|
||||
#ifndef PromiseFlatString
|
||||
#define PromiseFlatString TPromiseFlatString<char16_t>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTString_CharT::Rebind(const char_type* data, size_type length)
|
||||
nsTString<T>::Rebind(const char_type* data, size_type length)
|
||||
{
|
||||
// If we currently own a buffer, release it.
|
||||
Finalize();
|
||||
this->Finalize();
|
||||
|
||||
SetData(const_cast<char_type*>(data), length, DataFlags::TERMINATED);
|
||||
AssertValidDependentString();
|
||||
this->SetData(const_cast<char_type*>(data), length, DataFlags::TERMINATED);
|
||||
this->AssertValidDependentString();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
// IWYU pragma: private, include "nsString.h"
|
||||
|
||||
#ifndef nsTString_h
|
||||
#define nsTString_h
|
||||
|
||||
#include "nsTSubstring.h"
|
||||
|
||||
/**
|
||||
* This is the canonical null-terminated string class. All subclasses
|
||||
* promise null-terminated storage. Instances of this class allocate
|
||||
|
@ -17,11 +22,47 @@
|
|||
* This class is also known as nsAFlat[C]String, where "flat" is used
|
||||
* to denote a null-terminated string.
|
||||
*/
|
||||
class nsTString_CharT : public nsTSubstring_CharT
|
||||
template <typename T>
|
||||
class nsTString : public nsTSubstring<T>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef nsTString_CharT self_type;
|
||||
typedef nsTString<T> self_type;
|
||||
|
||||
#ifdef __clang__
|
||||
// bindgen w/ clang 3.9 at least chokes on a typedef, but using is okay.
|
||||
using typename nsTSubstring<T>::substring_type;
|
||||
#else
|
||||
// On the other hand msvc chokes on the using statement. It seems others
|
||||
// don't care either way so we lump them in here.
|
||||
typedef typename nsTSubstring<T>::substring_type substring_type;
|
||||
#endif
|
||||
|
||||
typedef typename substring_type::fallible_t fallible_t;
|
||||
|
||||
typedef typename substring_type::char_type char_type;
|
||||
typedef typename substring_type::char_traits char_traits;
|
||||
typedef typename substring_type::incompatible_char_type incompatible_char_type;
|
||||
|
||||
typedef typename substring_type::substring_tuple_type substring_tuple_type;
|
||||
|
||||
typedef typename substring_type::const_iterator const_iterator;
|
||||
typedef typename substring_type::iterator iterator;
|
||||
|
||||
typedef typename substring_type::comparator_type comparator_type;
|
||||
|
||||
typedef typename substring_type::char_iterator char_iterator;
|
||||
typedef typename substring_type::const_char_iterator const_char_iterator;
|
||||
|
||||
typedef typename substring_type::index_type index_type;
|
||||
typedef typename substring_type::size_type size_type;
|
||||
|
||||
// These are only for internal use within the string classes:
|
||||
typedef typename substring_type::DataFlags DataFlags;
|
||||
typedef typename substring_type::ClassFlags ClassFlags;
|
||||
|
||||
using typename substring_type::IsChar;
|
||||
using typename substring_type::IsChar16;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -29,78 +70,80 @@ public:
|
|||
* constructors
|
||||
*/
|
||||
|
||||
nsTString_CharT()
|
||||
nsTString()
|
||||
: substring_type(ClassFlags::NULL_TERMINATED)
|
||||
{
|
||||
}
|
||||
|
||||
explicit
|
||||
nsTString_CharT(const char_type* aData, size_type aLength = size_type(-1))
|
||||
nsTString(const char_type* aData, size_type aLength = size_type(-1))
|
||||
: substring_type(ClassFlags::NULL_TERMINATED)
|
||||
{
|
||||
Assign(aData, aLength);
|
||||
this->Assign(aData, aLength);
|
||||
}
|
||||
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
explicit
|
||||
nsTString_CharT(char16ptr_t aStr, size_type aLength = size_type(-1))
|
||||
nsTString(char16ptr_t aStr, size_type aLength = size_type(-1))
|
||||
: substring_type(ClassFlags::NULL_TERMINATED)
|
||||
{
|
||||
Assign(static_cast<const char16_t*>(aStr), aLength);
|
||||
this->Assign(static_cast<const char16_t*>(aStr), aLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsTString_CharT(const self_type& aStr)
|
||||
nsTString(const self_type& aStr)
|
||||
: substring_type(ClassFlags::NULL_TERMINATED)
|
||||
{
|
||||
Assign(aStr);
|
||||
this->Assign(aStr);
|
||||
}
|
||||
|
||||
MOZ_IMPLICIT nsTString_CharT(const substring_tuple_type& aTuple)
|
||||
MOZ_IMPLICIT nsTString(const substring_tuple_type& aTuple)
|
||||
: substring_type(ClassFlags::NULL_TERMINATED)
|
||||
{
|
||||
Assign(aTuple);
|
||||
this->Assign(aTuple);
|
||||
}
|
||||
|
||||
explicit
|
||||
nsTString_CharT(const substring_type& aReadable)
|
||||
nsTString(const substring_type& aReadable)
|
||||
: substring_type(ClassFlags::NULL_TERMINATED)
|
||||
{
|
||||
Assign(aReadable);
|
||||
this->Assign(aReadable);
|
||||
}
|
||||
|
||||
|
||||
// |operator=| does not inherit, so we must define our own
|
||||
self_type& operator=(char_type aChar)
|
||||
{
|
||||
Assign(aChar);
|
||||
this->Assign(aChar);
|
||||
return *this;
|
||||
}
|
||||
self_type& operator=(const char_type* aData)
|
||||
{
|
||||
Assign(aData);
|
||||
this->Assign(aData);
|
||||
return *this;
|
||||
}
|
||||
self_type& operator=(const self_type& aStr)
|
||||
{
|
||||
Assign(aStr);
|
||||
this->Assign(aStr);
|
||||
return *this;
|
||||
}
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
self_type& operator=(const char16ptr_t aStr)
|
||||
{
|
||||
Assign(static_cast<const char16_t*>(aStr));
|
||||
this->Assign(static_cast<const char16_t*>(aStr));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
self_type& operator=(const substring_type& aStr)
|
||||
{
|
||||
Assign(aStr);
|
||||
this->Assign(aStr);
|
||||
return *this;
|
||||
}
|
||||
self_type& operator=(const substring_tuple_type& aTuple)
|
||||
{
|
||||
Assign(aTuple);
|
||||
this->Assign(aTuple);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -108,13 +151,14 @@ public:
|
|||
* returns the null-terminated string
|
||||
*/
|
||||
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
MOZ_NO_DANGLING_ON_TEMPORARIES char16ptr_t get() const
|
||||
#else
|
||||
MOZ_NO_DANGLING_ON_TEMPORARIES const char_type* get() const
|
||||
template <typename U> struct raw_type { typedef const U* type; };
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <> struct raw_type<char16_t> { typedef char16ptr_t type; };
|
||||
#endif
|
||||
|
||||
MOZ_NO_DANGLING_ON_TEMPORARIES typename raw_type<T>::type get() const
|
||||
{
|
||||
return mData;
|
||||
return this->mData;
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,8 +171,8 @@ public:
|
|||
|
||||
char_type CharAt(index_type aIndex) const
|
||||
{
|
||||
NS_ASSERTION(aIndex <= mLength, "index exceeds allowable range");
|
||||
return mData[aIndex];
|
||||
NS_ASSERTION(aIndex <= this->mLength, "index exceeds allowable range");
|
||||
return this->mData[aIndex];
|
||||
}
|
||||
|
||||
char_type operator[](index_type aIndex) const
|
||||
|
@ -151,24 +195,25 @@ public:
|
|||
* @return offset in string, or kNotFound
|
||||
*/
|
||||
|
||||
int32_t Find(const nsCString& aString, bool aIgnoreCase = false,
|
||||
int32_t Find(const nsTString<char>& aString, bool aIgnoreCase = false,
|
||||
int32_t aOffset = 0, int32_t aCount = -1) const;
|
||||
int32_t Find(const char* aString, bool aIgnoreCase = false,
|
||||
int32_t aOffset = 0, int32_t aCount = -1) const;
|
||||
|
||||
#ifdef CharT_is_PRUnichar
|
||||
int32_t Find(const nsString& aString, int32_t aOffset = 0,
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
int32_t Find(const self_type& aString, int32_t aOffset = 0,
|
||||
int32_t aCount = -1) const;
|
||||
int32_t Find(const char16_t* aString, int32_t aOffset = 0,
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
int32_t Find(const char_type* aString, int32_t aOffset = 0,
|
||||
int32_t aCount = -1) const;
|
||||
#ifdef MOZ_USE_CHAR16_WRAPPER
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
int32_t Find(char16ptr_t aString, int32_t aOffset = 0,
|
||||
int32_t aCount = -1) const
|
||||
{
|
||||
return Find(static_cast<const char16_t*>(aString), aOffset, aCount);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
@ -183,17 +228,18 @@ public:
|
|||
* @return offset in string, or kNotFound
|
||||
*/
|
||||
|
||||
int32_t RFind(const nsCString& aString, bool aIgnoreCase = false,
|
||||
// Case aIgnoreCase option only with char versions
|
||||
int32_t RFind(const nsTString<char>& aString, bool aIgnoreCase = false,
|
||||
int32_t aOffset = -1, int32_t aCount = -1) const;
|
||||
int32_t RFind(const char* aCString, bool aIgnoreCase = false,
|
||||
int32_t aOffset = -1, int32_t aCount = -1) const;
|
||||
|
||||
#ifdef CharT_is_PRUnichar
|
||||
int32_t RFind(const nsString& aString, int32_t aOffset = -1,
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
int32_t RFind(const self_type& aString, int32_t aOffset = -1,
|
||||
int32_t aCount = -1) const;
|
||||
int32_t RFind(const char16_t* aString, int32_t aOffset = -1,
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
int32_t RFind(const char_type* aString, int32_t aOffset = -1,
|
||||
int32_t aCount = -1) const;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
@ -221,15 +267,14 @@ public:
|
|||
* @return offset in string, or kNotFound
|
||||
*/
|
||||
|
||||
int32_t FindCharInSet(const char* aString, int32_t aOffset = 0) const;
|
||||
int32_t FindCharInSet(const char_type* aString, int32_t aOffset = 0) const;
|
||||
int32_t FindCharInSet(const self_type& aString, int32_t aOffset = 0) const
|
||||
{
|
||||
return FindCharInSet(aString.get(), aOffset);
|
||||
}
|
||||
|
||||
#ifdef CharT_is_PRUnichar
|
||||
int32_t FindCharInSet(const char16_t* aString, int32_t aOffset = 0) const;
|
||||
#endif
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
int32_t FindCharInSet(const char* aSet, int32_t aOffset = 0) const;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -257,11 +302,9 @@ public:
|
|||
* @param aCount tells us how many chars to compare
|
||||
* @return -1,0,1
|
||||
*/
|
||||
|
||||
#ifdef CharT_is_char
|
||||
int32_t Compare(const char* aString, bool aIgnoreCase = false,
|
||||
template <typename EnableIfChar = IsChar>
|
||||
int32_t Compare(const char_type* aString, bool aIgnoreCase = false,
|
||||
int32_t aCount = -1) const;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
@ -272,16 +315,14 @@ public:
|
|||
* @param aCount tells us how many chars to compare
|
||||
* @return boolean
|
||||
*/
|
||||
#ifdef CharT_is_char
|
||||
bool EqualsIgnoreCase(const char* aString, int32_t aCount = -1) const
|
||||
template <typename EnableIfChar = IsChar>
|
||||
bool EqualsIgnoreCase(const char_type* aString, int32_t aCount = -1) const
|
||||
{
|
||||
return Compare(aString, true, aCount) == 0;
|
||||
}
|
||||
#else
|
||||
bool EqualsIgnoreCase(const char* aString, int32_t aCount = -1) const;
|
||||
|
||||
|
||||
#endif // !CharT_is_PRUnichar
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
bool EqualsIgnoreCase(const incompatible_char_type* aString, int32_t aCount = -1) const;
|
||||
|
||||
/**
|
||||
* Perform string to double-precision float conversion.
|
||||
|
@ -297,11 +338,7 @@ public:
|
|||
* @param aErrorCode will contain error if one occurs
|
||||
* @return single-precision float rep of string value
|
||||
*/
|
||||
float ToFloat(nsresult* aErrorCode) const
|
||||
{
|
||||
return (float)ToDouble(aErrorCode);
|
||||
}
|
||||
|
||||
float ToFloat(nsresult* aErrorCode) const;
|
||||
|
||||
/**
|
||||
* Perform string to int conversion.
|
||||
|
@ -337,7 +374,7 @@ public:
|
|||
* aWritable = Substring(aReadable, 0, 17);
|
||||
*/
|
||||
|
||||
size_type Mid(self_type& aResult, uint32_t aStartPos, uint32_t aCount) const;
|
||||
size_type Mid(self_type& aResult, index_type aStartPos, size_type aCount) const;
|
||||
|
||||
size_type Left(self_type& aResult, size_type aCount) const
|
||||
{
|
||||
|
@ -346,8 +383,8 @@ public:
|
|||
|
||||
size_type Right(self_type& aResult, size_type aCount) const
|
||||
{
|
||||
aCount = XPCOM_MIN(mLength, aCount);
|
||||
return Mid(aResult, mLength - aCount, aCount);
|
||||
aCount = XPCOM_MIN(this->mLength, aCount);
|
||||
return Mid(aResult, this->mLength - aCount, aCount);
|
||||
}
|
||||
|
||||
|
||||
|
@ -368,12 +405,13 @@ public:
|
|||
*
|
||||
* @param aSet -- characters to be cut from this
|
||||
*/
|
||||
#ifdef CharT_is_PRUnichar
|
||||
using nsTSubstring_CharT::StripChars;
|
||||
#endif
|
||||
void StripChars(const char* aSet);
|
||||
bool StripChars(const char* aSet, const fallible_t&);
|
||||
void StripChars(const char_type* aSet);
|
||||
|
||||
template<typename EnableIfChar16 = IsChar16>
|
||||
bool StripChars(const incompatible_char_type* aSet, const fallible_t&);
|
||||
|
||||
template<typename EnableIfChar16 = IsChar16>
|
||||
void StripChars(const incompatible_char_type* aSet);
|
||||
|
||||
/**
|
||||
* This method strips whitespace throughout the string.
|
||||
|
@ -387,10 +425,11 @@ public:
|
|||
*/
|
||||
|
||||
void ReplaceChar(char_type aOldChar, char_type aNewChar);
|
||||
void ReplaceChar(const char* aSet, char_type aNewChar);
|
||||
#ifdef CharT_is_PRUnichar
|
||||
void ReplaceChar(const char16_t* aSet, char16_t aNewChar);
|
||||
#endif
|
||||
void ReplaceChar(const char_type* aSet, char_type aNewChar);
|
||||
|
||||
template<typename EnableIfChar16 = IsChar16>
|
||||
void ReplaceChar(const char* aSet, char16_t aNewChar);
|
||||
|
||||
/**
|
||||
* Replace all occurrences of aTarget with aNewValue.
|
||||
* The complexity of this function is O(n+m), n being the length of the string
|
||||
|
@ -444,9 +483,9 @@ public:
|
|||
*/
|
||||
void AssertValidDependentString()
|
||||
{
|
||||
NS_ASSERTION(mData, "nsTDependentString must wrap a non-NULL buffer");
|
||||
NS_ASSERTION(mLength != size_type(-1), "nsTDependentString has bogus length");
|
||||
NS_ASSERTION(mData[mLength] == 0,
|
||||
NS_ASSERTION(this->mData, "nsTDependentString must wrap a non-NULL buffer");
|
||||
NS_ASSERTION(this->mLength != size_type(-1), "nsTDependentString has bogus length");
|
||||
NS_ASSERTION(this->mData[substring_type::mLength] == 0,
|
||||
"nsTDependentString must wrap only null-terminated strings. "
|
||||
"You are probably looking for nsTDependentSubstring.");
|
||||
}
|
||||
|
@ -455,17 +494,18 @@ public:
|
|||
protected:
|
||||
|
||||
// allow subclasses to initialize fields directly
|
||||
nsTString_CharT(char_type* aData, size_type aLength, DataFlags aDataFlags,
|
||||
ClassFlags aClassFlags)
|
||||
nsTString(char_type* aData, size_type aLength, DataFlags aDataFlags,
|
||||
ClassFlags aClassFlags)
|
||||
: substring_type(aData, aLength, aDataFlags,
|
||||
aClassFlags | ClassFlags::NULL_TERMINATED)
|
||||
{
|
||||
}
|
||||
|
||||
friend const nsTString_CharT& TNullString_CharT();
|
||||
friend const nsTString<char>& NullCString();
|
||||
friend const nsTString<char16_t>& NullString();
|
||||
|
||||
// Used by Null[C]String.
|
||||
explicit nsTString_CharT(DataFlags aDataFlags)
|
||||
explicit nsTString(DataFlags aDataFlags)
|
||||
: substring_type(char_traits::sEmptyBuffer, 0,
|
||||
aDataFlags | DataFlags::TERMINATED,
|
||||
ClassFlags::NULL_TERMINATED)
|
||||
|
@ -480,13 +520,33 @@ protected:
|
|||
};
|
||||
};
|
||||
|
||||
// TODO(erahm): Do something with ToDouble so that we can extern the
|
||||
// nsTString templates.
|
||||
//extern template class nsTString<char>;
|
||||
//extern template class nsTString<char16_t>;
|
||||
|
||||
class nsTFixedString_CharT : public nsTString_CharT
|
||||
template <typename T>
|
||||
class nsTFixedString : public nsTString<T>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef nsTFixedString_CharT self_type;
|
||||
typedef nsTFixedString_CharT fixed_string_type;
|
||||
typedef nsTFixedString<T> self_type;
|
||||
typedef nsTFixedString<T> fixed_string_type;
|
||||
|
||||
typedef nsTString<T> base_string_type;
|
||||
typedef typename base_string_type::string_type string_type;
|
||||
typedef typename base_string_type::char_type char_type;
|
||||
typedef typename base_string_type::char_traits char_traits;
|
||||
typedef typename base_string_type::substring_type substring_type;
|
||||
typedef typename base_string_type::size_type size_type;
|
||||
typedef typename base_string_type::substring_tuple_type substring_tuple_type;
|
||||
|
||||
// These are only for internal use within the string classes:
|
||||
typedef typename base_string_type::DataFlags DataFlags;
|
||||
typedef typename base_string_type::ClassFlags ClassFlags;
|
||||
|
||||
using typename base_string_type::IsChar;
|
||||
using typename base_string_type::IsChar16;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -500,7 +560,7 @@ public:
|
|||
* the length of the string already contained in the buffer
|
||||
*/
|
||||
|
||||
nsTFixedString_CharT(char_type* aData, size_type aStorageSize)
|
||||
nsTFixedString(char_type* aData, size_type aStorageSize)
|
||||
: string_type(aData, uint32_t(char_traits::length(aData)),
|
||||
DataFlags::TERMINATED | DataFlags::FIXED,
|
||||
ClassFlags::FIXED)
|
||||
|
@ -509,8 +569,8 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
nsTFixedString_CharT(char_type* aData, size_type aStorageSize,
|
||||
size_type aLength)
|
||||
nsTFixedString(char_type* aData, size_type aStorageSize,
|
||||
size_type aLength)
|
||||
: string_type(aData, aLength, DataFlags::TERMINATED | DataFlags::FIXED,
|
||||
ClassFlags::FIXED)
|
||||
, mFixedCapacity(aStorageSize - 1)
|
||||
|
@ -523,52 +583,72 @@ public:
|
|||
// |operator=| does not inherit, so we must define our own
|
||||
self_type& operator=(char_type aChar)
|
||||
{
|
||||
Assign(aChar);
|
||||
this->Assign(aChar);
|
||||
return *this;
|
||||
}
|
||||
self_type& operator=(const char_type* aData)
|
||||
{
|
||||
Assign(aData);
|
||||
this->Assign(aData);
|
||||
return *this;
|
||||
}
|
||||
self_type& operator=(const substring_type& aStr)
|
||||
{
|
||||
Assign(aStr);
|
||||
this->Assign(aStr);
|
||||
return *this;
|
||||
}
|
||||
self_type& operator=(const substring_tuple_type& aTuple)
|
||||
{
|
||||
Assign(aTuple);
|
||||
this->Assign(aTuple);
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
friend class nsTSubstring_CharT;
|
||||
friend class nsTSubstring<T>;
|
||||
|
||||
size_type mFixedCapacity;
|
||||
char_type* mFixedBuf;
|
||||
};
|
||||
|
||||
extern template class nsTFixedString<char>;
|
||||
extern template class nsTFixedString<char>;
|
||||
|
||||
/**
|
||||
* nsTAutoString_CharT
|
||||
* nsTAutoStringN
|
||||
*
|
||||
* Subclass of nsTString_CharT that adds support for stack-based string
|
||||
* Subclass of nsTString that adds support for stack-based string
|
||||
* allocation. It is normally not a good idea to use this class on the
|
||||
* heap, because it will allocate space which may be wasted if the string
|
||||
* it contains is significantly smaller or any larger than 64 characters.
|
||||
*
|
||||
* NAMES:
|
||||
* nsAutoStringN / nsAutoString for wide characters
|
||||
* nsAutoCStringN / nsAutoCString for narrow characters
|
||||
* nsAutoStringN / nsTAutoString for wide characters
|
||||
* nsAutoCStringN / nsTAutoCString for narrow characters
|
||||
*/
|
||||
template<size_t N>
|
||||
class MOZ_NON_MEMMOVABLE nsTAutoStringN_CharT : public nsTFixedString_CharT
|
||||
template<typename T, size_t N>
|
||||
class MOZ_NON_MEMMOVABLE nsTAutoStringN : public nsTFixedString<T>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef nsTAutoStringN_CharT<N> self_type;
|
||||
typedef nsTAutoStringN<T, N> self_type;
|
||||
|
||||
#ifdef __clang__
|
||||
// bindgen w/ clang 3.9 at least chokes on a typedef, but using is okay.
|
||||
using typename nsTFixedString<T>::fixed_string_type;
|
||||
#else
|
||||
// On the other hand msvc chokes on the using statement. It seems others
|
||||
// don't care either way so we lump them in here.
|
||||
typedef typename nsTFixedString<T>::fixed_string_type fixed_string_type;
|
||||
#endif
|
||||
|
||||
typedef typename fixed_string_type::char_type char_type;
|
||||
typedef typename fixed_string_type::char_traits char_traits;
|
||||
typedef typename fixed_string_type::substring_type substring_type;
|
||||
typedef typename fixed_string_type::size_type size_type;
|
||||
typedef typename fixed_string_type::substring_tuple_type substring_tuple_type;
|
||||
|
||||
using typename fixed_string_type::IsChar;
|
||||
using typename fixed_string_type::IsChar16;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -576,84 +656,85 @@ public:
|
|||
* constructors
|
||||
*/
|
||||
|
||||
nsTAutoStringN_CharT()
|
||||
nsTAutoStringN()
|
||||
: fixed_string_type(mStorage, N, 0)
|
||||
{
|
||||
}
|
||||
|
||||
explicit
|
||||
nsTAutoStringN_CharT(char_type aChar)
|
||||
nsTAutoStringN(char_type aChar)
|
||||
: fixed_string_type(mStorage, N, 0)
|
||||
{
|
||||
Assign(aChar);
|
||||
this->Assign(aChar);
|
||||
}
|
||||
|
||||
explicit
|
||||
nsTAutoStringN_CharT(const char_type* aData,
|
||||
size_type aLength = size_type(-1))
|
||||
nsTAutoStringN(const char_type* aData, size_type aLength = size_type(-1))
|
||||
: fixed_string_type(mStorage, N, 0)
|
||||
{
|
||||
Assign(aData, aLength);
|
||||
this->Assign(aData, aLength);
|
||||
}
|
||||
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
explicit
|
||||
nsTAutoStringN_CharT(char16ptr_t aData, size_type aLength = size_type(-1))
|
||||
: nsTAutoStringN_CharT(static_cast<const char16_t*>(aData), aLength)
|
||||
nsTAutoStringN(char16ptr_t aData, size_type aLength = size_type(-1))
|
||||
: nsTAutoStringN(static_cast<const char16_t*>(aData), aLength)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
nsTAutoStringN_CharT(const self_type& aStr)
|
||||
nsTAutoStringN(const self_type& aStr)
|
||||
: fixed_string_type(mStorage, N, 0)
|
||||
{
|
||||
Assign(aStr);
|
||||
this->Assign(aStr);
|
||||
}
|
||||
|
||||
explicit
|
||||
nsTAutoStringN_CharT(const substring_type& aStr)
|
||||
nsTAutoStringN(const substring_type& aStr)
|
||||
: fixed_string_type(mStorage, N, 0)
|
||||
{
|
||||
Assign(aStr);
|
||||
this->Assign(aStr);
|
||||
}
|
||||
|
||||
MOZ_IMPLICIT nsTAutoStringN_CharT(const substring_tuple_type& aTuple)
|
||||
MOZ_IMPLICIT nsTAutoStringN(const substring_tuple_type& aTuple)
|
||||
: fixed_string_type(mStorage, N, 0)
|
||||
{
|
||||
Assign(aTuple);
|
||||
this->Assign(aTuple);
|
||||
}
|
||||
|
||||
// |operator=| does not inherit, so we must define our own
|
||||
self_type& operator=(char_type aChar)
|
||||
{
|
||||
Assign(aChar);
|
||||
this->Assign(aChar);
|
||||
return *this;
|
||||
}
|
||||
self_type& operator=(const char_type* aData)
|
||||
{
|
||||
Assign(aData);
|
||||
this->Assign(aData);
|
||||
return *this;
|
||||
}
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
self_type& operator=(char16ptr_t aStr)
|
||||
{
|
||||
Assign(aStr);
|
||||
this->Assign(aStr);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
self_type& operator=(const self_type& aStr)
|
||||
{
|
||||
Assign(aStr);
|
||||
this->Assign(aStr);
|
||||
return *this;
|
||||
}
|
||||
self_type& operator=(const substring_type& aStr)
|
||||
{
|
||||
Assign(aStr);
|
||||
this->Assign(aStr);
|
||||
return *this;
|
||||
}
|
||||
self_type& operator=(const substring_tuple_type& aTuple)
|
||||
{
|
||||
Assign(aTuple);
|
||||
this->Assign(aTuple);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -664,9 +745,9 @@ private:
|
|||
char_type mStorage[N];
|
||||
};
|
||||
|
||||
// We define this typedef instead of providing a default value for N so that so
|
||||
// there is a default typename that doesn't require angle brackets.
|
||||
using nsTAutoString_CharT = nsTAutoStringN_CharT<AutoStringDefaultStorageSize>;
|
||||
// Externs for the most common nsTAutoStringN variations.
|
||||
extern template class nsTAutoStringN<char, 64>;
|
||||
extern template class nsTAutoStringN<char16_t, 64>;
|
||||
|
||||
//
|
||||
// nsAutoString stores pointers into itself which are invalidated when an
|
||||
|
@ -674,26 +755,26 @@ using nsTAutoString_CharT = nsTAutoStringN_CharT<AutoStringDefaultStorageSize>;
|
|||
// elements!
|
||||
//
|
||||
template<class E> class nsTArrayElementTraits;
|
||||
template<>
|
||||
class nsTArrayElementTraits<nsTAutoString_CharT>
|
||||
template<typename T>
|
||||
class nsTArrayElementTraits<nsTAutoString<T>>
|
||||
{
|
||||
public:
|
||||
template<class A> struct Dont_Instantiate_nsTArray_of;
|
||||
template<class A> struct Instead_Use_nsTArray_of;
|
||||
|
||||
static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT>*
|
||||
Construct(Instead_Use_nsTArray_of<nsTString_CharT>* aE)
|
||||
static Dont_Instantiate_nsTArray_of<nsTAutoString<T>>*
|
||||
Construct(Instead_Use_nsTArray_of<nsTString<T>>* aE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
template<class A>
|
||||
static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT>*
|
||||
Construct(Instead_Use_nsTArray_of<nsTString_CharT>* aE, const A& aArg)
|
||||
static Dont_Instantiate_nsTArray_of<nsTAutoString<T>>*
|
||||
Construct(Instead_Use_nsTArray_of<nsTString<T>>* aE, const A& aArg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static Dont_Instantiate_nsTArray_of<nsTAutoString_CharT>*
|
||||
Destruct(Instead_Use_nsTArray_of<nsTString_CharT>* aE)
|
||||
static Dont_Instantiate_nsTArray_of<nsTAutoString<T>>*
|
||||
Destruct(Instead_Use_nsTArray_of<nsTString<T>>* aE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -727,18 +808,19 @@ public:
|
|||
* // ...
|
||||
* }
|
||||
*/
|
||||
class MOZ_STACK_CLASS nsTGetterCopies_CharT
|
||||
template <typename T>
|
||||
class MOZ_STACK_CLASS nsTGetterCopies
|
||||
{
|
||||
public:
|
||||
typedef CharT char_type;
|
||||
typedef T char_type;
|
||||
|
||||
explicit nsTGetterCopies_CharT(nsTSubstring_CharT& aStr)
|
||||
explicit nsTGetterCopies(nsTSubstring<T>& aStr)
|
||||
: mString(aStr)
|
||||
, mData(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
~nsTGetterCopies_CharT()
|
||||
~nsTGetterCopies()
|
||||
{
|
||||
mString.Adopt(mData); // OK if mData is null
|
||||
}
|
||||
|
@ -749,14 +831,16 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
nsTSubstring_CharT& mString;
|
||||
nsTSubstring<T>& mString;
|
||||
char_type* mData;
|
||||
};
|
||||
|
||||
// See the comment above nsTGetterCopies_CharT for how to use this.
|
||||
inline nsTGetterCopies_CharT
|
||||
getter_Copies(nsTSubstring_CharT& aString)
|
||||
template <typename T>
|
||||
inline nsTGetterCopies<T>
|
||||
getter_Copies(nsTSubstring<T>& aString)
|
||||
{
|
||||
return nsTGetterCopies_CharT(aString);
|
||||
return nsTGetterCopies<T>(aString);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,18 +4,20 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
template <typename T>
|
||||
int NS_FASTCALL
|
||||
Compare(const nsTSubstring_CharT::base_string_type& aLhs,
|
||||
const nsTSubstring_CharT::base_string_type& aRhs,
|
||||
const nsTStringComparator_CharT& comp)
|
||||
Compare(const mozilla::detail::nsTStringRepr<T>& aLhs,
|
||||
const mozilla::detail::nsTStringRepr<T>& aRhs,
|
||||
const nsTStringComparator<T>& comp)
|
||||
{
|
||||
typedef nsTSubstring_CharT::size_type size_type;
|
||||
typedef typename nsTSubstring<T>::size_type size_type;
|
||||
typedef typename nsTSubstring<T>::const_iterator const_iterator;
|
||||
|
||||
if (&aLhs == &aRhs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsTSubstring_CharT::const_iterator leftIter, rightIter;
|
||||
const_iterator leftIter, rightIter;
|
||||
aLhs.BeginReading(leftIter);
|
||||
aRhs.BeginReading(rightIter);
|
||||
|
||||
|
@ -38,13 +40,14 @@ Compare(const nsTSubstring_CharT::base_string_type& aLhs,
|
|||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int
|
||||
nsTDefaultStringComparator_CharT::operator()(const char_type* aLhs,
|
||||
const char_type* aRhs,
|
||||
uint32_t aLLength,
|
||||
uint32_t aRLength) const
|
||||
nsTDefaultStringComparator<T>::operator()(const char_type* aLhs,
|
||||
const char_type* aRhs,
|
||||
uint32_t aLLength,
|
||||
uint32_t aRLength) const
|
||||
{
|
||||
return
|
||||
aLLength == aRLength ? nsCharTraits<CharT>::compare(aLhs, aRhs, aLLength) :
|
||||
aLLength == aRLength ? nsCharTraits<T>::compare(aLhs, aRhs, aLLength) :
|
||||
(aLLength > aRLength) ? 1 : -1;
|
||||
}
|
||||
|
|
|
@ -14,23 +14,24 @@
|
|||
* aOffset specifies starting index
|
||||
* aCount specifies number of string compares (iterations)
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
int32_t
|
||||
nsTString_CharT::Find( const nsCString& aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
|
||||
nsTString<T>::Find(const nsTString<char>& aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
|
||||
{
|
||||
// this method changes the meaning of aOffset and aCount:
|
||||
Find_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
|
||||
Find_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
|
||||
|
||||
int32_t result = FindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
|
||||
int32_t result = FindSubstring(this->mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
|
||||
if (result != kNotFound)
|
||||
result += aOffset;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int32_t
|
||||
nsTString_CharT::Find( const char* aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
|
||||
nsTString<T>::Find(const char* aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
|
||||
{
|
||||
return Find(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
|
||||
return Find(nsTDependentString<char>(aString), aIgnoreCase, aOffset, aCount);
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,34 +41,35 @@ nsTString_CharT::Find( const char* aString, bool aIgnoreCase, int32_t aOffset, i
|
|||
* aOffset specifies starting index
|
||||
* aCount specifies number of string compares (iterations)
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
int32_t
|
||||
nsTString_CharT::RFind( const nsCString& aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
|
||||
nsTString<T>::RFind(const nsTString<char>& aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
|
||||
{
|
||||
// this method changes the meaning of aOffset and aCount:
|
||||
RFind_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
|
||||
RFind_ComputeSearchRange(this->mLength, aString.Length(), aOffset, aCount);
|
||||
|
||||
int32_t result = RFindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
|
||||
int32_t result = RFindSubstring(this->mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
|
||||
if (result != kNotFound)
|
||||
result += aOffset;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int32_t
|
||||
nsTString_CharT::RFind( const char* aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
|
||||
nsTString<T>::RFind(const char* aString, bool aIgnoreCase, int32_t aOffset, int32_t aCount) const
|
||||
{
|
||||
return RFind(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
|
||||
return RFind(nsTDependentString<char>(aString), aIgnoreCase, aOffset, aCount);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nsTString::RFindChar
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
int32_t
|
||||
nsTString_CharT::RFindChar( char16_t aChar, int32_t aOffset, int32_t aCount) const
|
||||
nsTString<T>::RFindChar(char16_t aChar, int32_t aOffset, int32_t aCount) const
|
||||
{
|
||||
return nsBufferRoutines<CharT>::rfind_char(mData, mLength, aOffset, aChar, aCount);
|
||||
return nsBufferRoutines<T>::rfind_char(this->mData, this->mLength, aOffset, aChar, aCount);
|
||||
}
|
||||
|
||||
|
||||
|
@ -75,15 +77,16 @@ nsTString_CharT::RFindChar( char16_t aChar, int32_t aOffset, int32_t aCount) con
|
|||
* nsTString::FindCharInSet
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
int32_t
|
||||
nsTString_CharT::FindCharInSet( const char* aSet, int32_t aOffset ) const
|
||||
nsTString<T>::FindCharInSet(const char_type* aSet, int32_t aOffset) const
|
||||
{
|
||||
if (aOffset < 0)
|
||||
aOffset = 0;
|
||||
else if (aOffset >= int32_t(mLength))
|
||||
else if (aOffset >= int32_t(this->mLength))
|
||||
return kNotFound;
|
||||
|
||||
int32_t result = ::FindCharInSet(mData + aOffset, mLength - aOffset, aSet);
|
||||
int32_t result = ::FindCharInSet(this->mData + aOffset, this->mLength - aOffset, aSet);
|
||||
if (result != kNotFound)
|
||||
result += aOffset;
|
||||
return result;
|
||||
|
@ -94,30 +97,32 @@ nsTString_CharT::FindCharInSet( const char* aSet, int32_t aOffset ) const
|
|||
* nsTString::RFindCharInSet
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
int32_t
|
||||
nsTString_CharT::RFindCharInSet( const CharT* aSet, int32_t aOffset ) const
|
||||
nsTString<T>::RFindCharInSet(const char_type* aSet, int32_t aOffset) const
|
||||
{
|
||||
// We want to pass a "data length" to ::RFindCharInSet
|
||||
if (aOffset < 0 || aOffset > int32_t(mLength))
|
||||
aOffset = mLength;
|
||||
if (aOffset < 0 || aOffset > int32_t(this->mLength))
|
||||
aOffset = this->mLength;
|
||||
else
|
||||
++aOffset;
|
||||
|
||||
return ::RFindCharInSet(mData, aOffset, aSet);
|
||||
return ::RFindCharInSet(this->mData, aOffset, aSet);
|
||||
}
|
||||
|
||||
|
||||
// it's a shame to replicate this code. it was done this way in the past
|
||||
// to help performance. this function also gets to keep the rickg style
|
||||
// indentation :-/
|
||||
template <typename T>
|
||||
int32_t
|
||||
nsTString_CharT::ToInteger( nsresult* aErrorCode, uint32_t aRadix ) const
|
||||
nsTString<T>::ToInteger(nsresult* aErrorCode, uint32_t aRadix) const
|
||||
{
|
||||
CharT* cp=mData;
|
||||
int32_t theRadix=10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect)
|
||||
int32_t result=0;
|
||||
bool negate=false;
|
||||
CharT theChar=0;
|
||||
char_type* cp = this->mData;
|
||||
int32_t theRadix = 10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect)
|
||||
int32_t result = 0;
|
||||
bool negate = false;
|
||||
char_type theChar = 0;
|
||||
|
||||
//initial value, override if we find an integer
|
||||
*aErrorCode=NS_ERROR_ILLEGAL_VALUE;
|
||||
|
@ -126,8 +131,8 @@ nsTString_CharT::ToInteger( nsresult* aErrorCode, uint32_t aRadix ) const
|
|||
|
||||
//begin by skipping over leading chars that shouldn't be part of the number...
|
||||
|
||||
CharT* endcp=cp+mLength;
|
||||
bool done=false;
|
||||
char_type* endcp=cp+this->mLength;
|
||||
bool done=false;
|
||||
|
||||
while((cp<endcp) && (!done)){
|
||||
switch(*cp++) {
|
||||
|
@ -159,7 +164,7 @@ nsTString_CharT::ToInteger( nsresult* aErrorCode, uint32_t aRadix ) const
|
|||
if (aRadix!=kAutoDetect) theRadix = aRadix; // override
|
||||
|
||||
//now iterate the numeric chars and build our result
|
||||
CharT* first=--cp; //in case we have to back up.
|
||||
char_type* first=--cp; //in case we have to back up.
|
||||
bool haveValue = false;
|
||||
|
||||
while(cp<endcp){
|
||||
|
@ -237,14 +242,15 @@ nsTString_CharT::ToInteger( nsresult* aErrorCode, uint32_t aRadix ) const
|
|||
/**
|
||||
* nsTString::ToInteger64
|
||||
*/
|
||||
template <typename T>
|
||||
int64_t
|
||||
nsTString_CharT::ToInteger64( nsresult* aErrorCode, uint32_t aRadix ) const
|
||||
nsTString<T>::ToInteger64(nsresult* aErrorCode, uint32_t aRadix) const
|
||||
{
|
||||
CharT* cp=mData;
|
||||
char_type* cp=this->mData;
|
||||
int32_t theRadix=10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect)
|
||||
int64_t result=0;
|
||||
bool negate=false;
|
||||
CharT theChar=0;
|
||||
bool negate=false;
|
||||
char_type theChar=0;
|
||||
|
||||
//initial value, override if we find an integer
|
||||
*aErrorCode=NS_ERROR_ILLEGAL_VALUE;
|
||||
|
@ -253,8 +259,8 @@ nsTString_CharT::ToInteger64( nsresult* aErrorCode, uint32_t aRadix ) const
|
|||
|
||||
//begin by skipping over leading chars that shouldn't be part of the number...
|
||||
|
||||
CharT* endcp=cp+mLength;
|
||||
bool done=false;
|
||||
char_type* endcp=cp+this->mLength;
|
||||
bool done=false;
|
||||
|
||||
while((cp<endcp) && (!done)){
|
||||
switch(*cp++) {
|
||||
|
@ -286,7 +292,7 @@ nsTString_CharT::ToInteger64( nsresult* aErrorCode, uint32_t aRadix ) const
|
|||
if (aRadix!=kAutoDetect) theRadix = aRadix; // override
|
||||
|
||||
//now iterate the numeric chars and build our result
|
||||
CharT* first=--cp; //in case we have to back up.
|
||||
char_type* first=--cp; //in case we have to back up.
|
||||
bool haveValue = false;
|
||||
|
||||
while(cp<endcp){
|
||||
|
@ -365,10 +371,11 @@ nsTString_CharT::ToInteger64( nsresult* aErrorCode, uint32_t aRadix ) const
|
|||
* nsTString::Mid
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
nsTString_CharT::Mid( self_type& aResult, index_type aStartPos, size_type aLengthToCopy ) const
|
||||
template <typename T>
|
||||
typename nsTString<T>::size_type
|
||||
nsTString<T>::Mid(self_type& aResult, index_type aStartPos, size_type aLengthToCopy) const
|
||||
{
|
||||
if (aStartPos == 0 && aLengthToCopy >= mLength)
|
||||
if (aStartPos == 0 && aLengthToCopy >= this->mLength)
|
||||
aResult = *this;
|
||||
else
|
||||
aResult = Substring(*this, aStartPos, aLengthToCopy);
|
||||
|
@ -381,16 +388,17 @@ nsTString_CharT::Mid( self_type& aResult, index_type aStartPos, size_type aLengt
|
|||
* nsTString::SetCharAt
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
nsTString_CharT::SetCharAt( char16_t aChar, uint32_t aIndex )
|
||||
nsTString<T>::SetCharAt(char16_t aChar, uint32_t aIndex)
|
||||
{
|
||||
if (aIndex >= mLength)
|
||||
if (aIndex >= this->mLength)
|
||||
return false;
|
||||
|
||||
if (!EnsureMutable())
|
||||
AllocFailed(mLength);
|
||||
if (!this->EnsureMutable())
|
||||
this->AllocFailed(this->mLength);
|
||||
|
||||
mData[aIndex] = CharT(aChar);
|
||||
this->mData[aIndex] = char_type(aChar);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -399,41 +407,54 @@ nsTString_CharT::SetCharAt( char16_t aChar, uint32_t aIndex )
|
|||
* nsTString::StripChars,StripChar,StripWhitespace
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
template<typename EnableIfChar16>
|
||||
void
|
||||
nsTString_CharT::StripChars( const char* aSet )
|
||||
nsTString<T>::StripChars(const incompatible_char_type* aSet)
|
||||
{
|
||||
if (!StripChars(aSet, mozilla::fallible)) {
|
||||
AllocFailed(mLength);
|
||||
this->AllocFailed(this->mLength);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename EnableIfChar16>
|
||||
bool
|
||||
nsTString_CharT::StripChars( const char* aSet, const fallible_t& )
|
||||
nsTString<T>::StripChars(const incompatible_char_type* aSet, const fallible_t&)
|
||||
{
|
||||
if (!EnsureMutable()) {
|
||||
if (!this->EnsureMutable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mLength = nsBufferRoutines<CharT>::strip_chars(mData, mLength, aSet);
|
||||
this->mLength = nsBufferRoutines<T>::strip_chars(this->mData, this->mLength, aSet);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
nsTString_CharT::StripWhitespace()
|
||||
nsTString<T>::StripChars(const char_type* aSet)
|
||||
{
|
||||
nsTSubstring<T>::StripChars(aSet);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTString<T>::StripWhitespace()
|
||||
{
|
||||
if (!StripWhitespace(mozilla::fallible)) {
|
||||
AllocFailed(mLength);
|
||||
this->AllocFailed(this->mLength);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
nsTString_CharT::StripWhitespace( const fallible_t& )
|
||||
nsTString<T>::StripWhitespace(const fallible_t&)
|
||||
{
|
||||
if (!EnsureMutable()) {
|
||||
if (!this->EnsureMutable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
StripTaggedASCII(mozilla::ASCIIMask::MaskWhitespace());
|
||||
this->StripTaggedASCII(mozilla::ASCIIMask::MaskWhitespace());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -441,27 +462,29 @@ nsTString_CharT::StripWhitespace( const fallible_t& )
|
|||
* nsTString::ReplaceChar,ReplaceSubstring
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTString_CharT::ReplaceChar( char_type aOldChar, char_type aNewChar )
|
||||
nsTString<T>::ReplaceChar(char_type aOldChar, char_type aNewChar)
|
||||
{
|
||||
if (!EnsureMutable()) // XXX do this lazily?
|
||||
AllocFailed(mLength);
|
||||
if (!this->EnsureMutable()) // XXX do this lazily?
|
||||
this->AllocFailed(this->mLength);
|
||||
|
||||
for (uint32_t i=0; i<mLength; ++i)
|
||||
for (uint32_t i=0; i<this->mLength; ++i)
|
||||
{
|
||||
if (mData[i] == aOldChar)
|
||||
mData[i] = aNewChar;
|
||||
if (this->mData[i] == aOldChar)
|
||||
this->mData[i] = aNewChar;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
|
||||
nsTString<T>::ReplaceChar(const char_type* aSet, char_type aNewChar)
|
||||
{
|
||||
if (!EnsureMutable()) // XXX do this lazily?
|
||||
AllocFailed(mLength);
|
||||
if (!this->EnsureMutable()) // XXX do this lazily?
|
||||
this->AllocFailed(this->mLength);
|
||||
|
||||
char_type* data = mData;
|
||||
uint32_t lenRemaining = mLength;
|
||||
char_type* data = this->mData;
|
||||
uint32_t lenRemaining = this->mLength;
|
||||
|
||||
while (lenRemaining)
|
||||
{
|
||||
|
@ -477,39 +500,43 @@ nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
|
|||
|
||||
void ReleaseData(void* aData, nsAString::DataFlags aFlags);
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTString_CharT::ReplaceSubstring(const char_type* aTarget,
|
||||
const char_type* aNewValue)
|
||||
nsTString<T>::ReplaceSubstring(const char_type* aTarget,
|
||||
const char_type* aNewValue)
|
||||
{
|
||||
ReplaceSubstring(nsTDependentString_CharT(aTarget),
|
||||
nsTDependentString_CharT(aNewValue));
|
||||
ReplaceSubstring(nsTDependentString<T>(aTarget),
|
||||
nsTDependentString<T>(aNewValue));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
nsTString_CharT::ReplaceSubstring(const char_type* aTarget,
|
||||
const char_type* aNewValue,
|
||||
const fallible_t& aFallible)
|
||||
nsTString<T>::ReplaceSubstring(const char_type* aTarget,
|
||||
const char_type* aNewValue,
|
||||
const fallible_t& aFallible)
|
||||
{
|
||||
return ReplaceSubstring(nsTDependentString_CharT(aTarget),
|
||||
nsTDependentString_CharT(aNewValue),
|
||||
return ReplaceSubstring(nsTDependentString<T>(aTarget),
|
||||
nsTDependentString<T>(aNewValue),
|
||||
aFallible);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
|
||||
const self_type& aNewValue)
|
||||
nsTString<T>::ReplaceSubstring(const self_type& aTarget,
|
||||
const self_type& aNewValue)
|
||||
{
|
||||
if (!ReplaceSubstring(aTarget, aNewValue, mozilla::fallible)) {
|
||||
// Note that this may wildly underestimate the allocation that failed, as
|
||||
// we could have been replacing multiple copies of aTarget.
|
||||
AllocFailed(mLength + (aNewValue.Length() - aTarget.Length()));
|
||||
this->AllocFailed(this->mLength + (aNewValue.Length() - aTarget.Length()));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
|
||||
const self_type& aNewValue,
|
||||
const fallible_t&)
|
||||
nsTString<T>::ReplaceSubstring(const self_type& aTarget,
|
||||
const self_type& aNewValue,
|
||||
const fallible_t&)
|
||||
{
|
||||
if (aTarget.Length() == 0)
|
||||
return true;
|
||||
|
@ -520,8 +547,8 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
|
|||
mozilla::CheckedUint32 newLength;
|
||||
while (true)
|
||||
{
|
||||
int32_t r = FindSubstring(mData + i, mLength - i, static_cast<const char_type*>(aTarget.Data()), aTarget.Length(), false);
|
||||
int32_t until = (r == kNotFound) ? mLength - i : r;
|
||||
int32_t r = FindSubstring(this->mData + i, this->mLength - i, static_cast<const char_type*>(aTarget.Data()), aTarget.Length(), false);
|
||||
int32_t until = (r == kNotFound) ? this->mLength - i : r;
|
||||
nonMatching.AppendElement(Segment(i, until));
|
||||
newLength += until;
|
||||
if (r == kNotFound) {
|
||||
|
@ -530,10 +557,10 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
|
|||
|
||||
newLength += aNewValue.Length();
|
||||
i += r + aTarget.Length();
|
||||
if (i >= mLength) {
|
||||
if (i >= this->mLength) {
|
||||
// Add an auxiliary entry at the end of the list to help as an edge case
|
||||
// for the algorithms below.
|
||||
nonMatching.AppendElement(Segment(mLength, 0));
|
||||
nonMatching.AppendElement(Segment(this->mLength, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -545,22 +572,22 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
|
|||
// If there's only one non-matching segment, then the target string was not
|
||||
// found, and there's nothing to do.
|
||||
if (nonMatching.Length() == 1) {
|
||||
MOZ_ASSERT(nonMatching[0].mBegin == 0 && nonMatching[0].mLength == mLength,
|
||||
MOZ_ASSERT(nonMatching[0].mBegin == 0 && nonMatching[0].mLength == this->mLength,
|
||||
"We should have the correct non-matching segment.");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make sure that we can mutate our buffer.
|
||||
// Note that we always allocate at least an mLength sized buffer, because the
|
||||
// Note that we always allocate at least an this->mLength sized buffer, because the
|
||||
// rest of the algorithm relies on having access to all of the original
|
||||
// string. In other words, we over-allocate in the shrinking case.
|
||||
char_type* oldData;
|
||||
DataFlags oldFlags;
|
||||
if (!MutatePrep(XPCOM_MAX(mLength, newLength.value()), &oldData, &oldFlags))
|
||||
if (!this->MutatePrep(XPCOM_MAX(this->mLength, newLength.value()), &oldData, &oldFlags))
|
||||
return false;
|
||||
if (oldData) {
|
||||
// Copy all of the old data to the new buffer.
|
||||
char_traits::copy(mData, oldData, mLength);
|
||||
char_traits::copy(this->mData, oldData, this->mLength);
|
||||
::ReleaseData(oldData, oldFlags);
|
||||
}
|
||||
|
||||
|
@ -571,8 +598,8 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
|
|||
// When we move the i'th non-matching segment into position, we need to
|
||||
// account for the characters deleted by the previous |i| replacements by
|
||||
// subtracting |i * delta|.
|
||||
const char_type* sourceSegmentPtr = mData + nonMatching[i].mBegin;
|
||||
char_type* destinationSegmentPtr = mData + nonMatching[i].mBegin - i * delta;
|
||||
const char_type* sourceSegmentPtr = this->mData + nonMatching[i].mBegin;
|
||||
char_type* destinationSegmentPtr = this->mData + nonMatching[i].mBegin - i * delta;
|
||||
// Write the i'th replacement immediately before the new i'th non-matching
|
||||
// segment.
|
||||
char_traits::copy(destinationSegmentPtr - aNewValue.Length(),
|
||||
|
@ -587,8 +614,8 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
|
|||
// When we move the i'th non-matching segment into position, we need to
|
||||
// account for the characters added by the previous |i| replacements by
|
||||
// adding |i * delta|.
|
||||
const char_type* sourceSegmentPtr = mData + nonMatching[i].mBegin;
|
||||
char_type* destinationSegmentPtr = mData + nonMatching[i].mBegin + i * delta;
|
||||
const char_type* sourceSegmentPtr = this->mData + nonMatching[i].mBegin;
|
||||
char_type* destinationSegmentPtr = this->mData + nonMatching[i].mBegin + i * delta;
|
||||
char_traits::move(destinationSegmentPtr, sourceSegmentPtr,
|
||||
nonMatching[i].mLength);
|
||||
// Write the i'th replacement immediately before the new i'th non-matching
|
||||
|
@ -599,8 +626,8 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
|
|||
}
|
||||
|
||||
// Adjust the length and make sure the string is null terminated.
|
||||
mLength = newLength.value();
|
||||
mData[mLength] = char_type(0);
|
||||
this->mLength = newLength.value();
|
||||
this->mData[this->mLength] = char_type(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -609,19 +636,20 @@ nsTString_CharT::ReplaceSubstring(const self_type& aTarget,
|
|||
* nsTString::Trim
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTString_CharT::Trim( const char* aSet, bool aTrimLeading, bool aTrimTrailing, bool aIgnoreQuotes )
|
||||
nsTString<T>::Trim(const char* aSet, bool aTrimLeading, bool aTrimTrailing, bool aIgnoreQuotes)
|
||||
{
|
||||
// the old implementation worried about aSet being null :-/
|
||||
if (!aSet)
|
||||
return;
|
||||
|
||||
char_type* start = mData;
|
||||
char_type* end = mData + mLength;
|
||||
char_type* start = this->mData;
|
||||
char_type* end = this->mData + this->mLength;
|
||||
|
||||
// skip over quotes if requested
|
||||
if (aIgnoreQuotes && mLength > 2 && mData[0] == mData[mLength - 1] &&
|
||||
(mData[0] == '\'' || mData[0] == '"'))
|
||||
if (aIgnoreQuotes && this->mLength > 2 && this->mData[0] == this->mData[this->mLength - 1] &&
|
||||
(this->mData[0] == '\'' || this->mData[0] == '"'))
|
||||
{
|
||||
++start;
|
||||
--end;
|
||||
|
@ -631,7 +659,7 @@ nsTString_CharT::Trim( const char* aSet, bool aTrimLeading, bool aTrimTrailing,
|
|||
|
||||
if (aTrimLeading)
|
||||
{
|
||||
uint32_t cutStart = start - mData;
|
||||
uint32_t cutStart = start - this->mData;
|
||||
uint32_t cutLength = 0;
|
||||
|
||||
// walk forward from start to end
|
||||
|
@ -644,17 +672,17 @@ nsTString_CharT::Trim( const char* aSet, bool aTrimLeading, bool aTrimTrailing,
|
|||
|
||||
if (cutLength)
|
||||
{
|
||||
Cut(cutStart, cutLength);
|
||||
this->Cut(cutStart, cutLength);
|
||||
|
||||
// reset iterators
|
||||
start = mData + cutStart;
|
||||
end = mData + mLength - cutStart;
|
||||
start = this->mData + cutStart;
|
||||
end = this->mData + this->mLength - cutStart;
|
||||
}
|
||||
}
|
||||
|
||||
if (aTrimTrailing)
|
||||
{
|
||||
uint32_t cutEnd = end - mData;
|
||||
uint32_t cutEnd = end - this->mData;
|
||||
uint32_t cutLength = 0;
|
||||
|
||||
// walk backward from end to start
|
||||
|
@ -667,7 +695,7 @@ nsTString_CharT::Trim( const char* aSet, bool aTrimLeading, bool aTrimTrailing,
|
|||
}
|
||||
|
||||
if (cutLength)
|
||||
Cut(cutEnd - cutLength, cutLength);
|
||||
this->Cut(cutEnd - cutLength, cutLength);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -676,22 +704,23 @@ nsTString_CharT::Trim( const char* aSet, bool aTrimLeading, bool aTrimTrailing,
|
|||
* nsTString::CompressWhitespace.
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTString_CharT::CompressWhitespace( bool aTrimLeading, bool aTrimTrailing )
|
||||
nsTString<T>::CompressWhitespace(bool aTrimLeading, bool aTrimTrailing)
|
||||
{
|
||||
// Quick exit
|
||||
if (mLength == 0) {
|
||||
if (this->mLength == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EnsureMutable())
|
||||
AllocFailed(mLength);
|
||||
if (!this->EnsureMutable())
|
||||
this->AllocFailed(this->mLength);
|
||||
|
||||
const ASCIIMaskArray& mask = mozilla::ASCIIMask::MaskWhitespace();
|
||||
|
||||
char_type* to = mData;
|
||||
char_type* from = mData;
|
||||
char_type* end = mData + mLength;
|
||||
char_type* to = this->mData;
|
||||
char_type* from = this->mData;
|
||||
char_type* end = this->mData + this->mLength;
|
||||
|
||||
// Compresses runs of whitespace down to a normal space ' ' and convert
|
||||
// any whitespace to a normal space. This assumes that whitespace is
|
||||
|
@ -711,10 +740,10 @@ nsTString_CharT::CompressWhitespace( bool aTrimLeading, bool aTrimTrailing )
|
|||
}
|
||||
|
||||
// If we need to trim the trailing whitespace, back up one character.
|
||||
if (aTrimTrailing && skipWS && to > mData) {
|
||||
if (aTrimTrailing && skipWS && to > this->mData) {
|
||||
to--;
|
||||
}
|
||||
|
||||
*to = char_type(0); // add the null
|
||||
mLength = to - mData;
|
||||
this->mLength = to - this->mData;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,374 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsTStringRepr_h
|
||||
#define nsTStringRepr_h
|
||||
|
||||
#include <type_traits> // std::enable_if
|
||||
|
||||
#include "nsStringFlags.h"
|
||||
#include "nsCharTraits.h"
|
||||
|
||||
template <typename T> class nsTSubstringTuple;
|
||||
|
||||
// The base for string comparators
|
||||
template <typename T> class nsTStringComparator
|
||||
{
|
||||
public:
|
||||
typedef T char_type;
|
||||
|
||||
nsTStringComparator() {}
|
||||
|
||||
virtual int operator()(const char_type*, const char_type*,
|
||||
uint32_t, uint32_t) const = 0;
|
||||
};
|
||||
|
||||
// The default string comparator (case-sensitive comparision)
|
||||
template <typename T> class nsTDefaultStringComparator
|
||||
: public nsTStringComparator<T>
|
||||
{
|
||||
public:
|
||||
typedef T char_type;
|
||||
|
||||
nsTDefaultStringComparator() {}
|
||||
|
||||
virtual int operator()(const char_type*, const char_type*,
|
||||
uint32_t, uint32_t) const override;
|
||||
};
|
||||
|
||||
extern template class nsTDefaultStringComparator<char>;
|
||||
extern template class nsTDefaultStringComparator<char16_t>;
|
||||
|
||||
namespace mozilla {
|
||||
namespace detail {
|
||||
|
||||
// nsTStringRepr defines a string's memory layout and some accessor methods.
|
||||
// This class exists so that nsTLiteralString can avoid inheriting
|
||||
// nsTSubstring's destructor. All methods on this class must be const because
|
||||
// literal strings are not writable.
|
||||
//
|
||||
// This class is an implementation detail and should not be instantiated
|
||||
// directly, nor used in any way outside of the string code itself. It is
|
||||
// buried in a namespace to discourage its use in function parameters.
|
||||
// If you need to take a parameter, use [const] ns[C]Substring&.
|
||||
// If you need to instantiate a string, use ns[C]String or descendents.
|
||||
//
|
||||
// NAMES:
|
||||
// nsStringRepr for wide characters
|
||||
// nsCStringRepr for narrow characters
|
||||
template <typename T> class nsTStringRepr
|
||||
{
|
||||
public:
|
||||
typedef mozilla::fallible_t fallible_t;
|
||||
|
||||
typedef T char_type;
|
||||
|
||||
typedef nsCharTraits<char_type> char_traits;
|
||||
typedef typename char_traits::incompatible_char_type incompatible_char_type;
|
||||
|
||||
typedef nsTStringRepr<T> self_type;
|
||||
typedef self_type base_string_type;
|
||||
|
||||
typedef nsTSubstring<T> substring_type;
|
||||
typedef nsTSubstringTuple<T> substring_tuple_type;
|
||||
|
||||
typedef nsReadingIterator<char_type> const_iterator;
|
||||
typedef nsWritingIterator<char_type> iterator;
|
||||
|
||||
typedef nsTStringComparator<char_type> comparator_type;
|
||||
|
||||
typedef char_type* char_iterator;
|
||||
typedef const char_type* const_char_iterator;
|
||||
|
||||
typedef uint32_t index_type;
|
||||
typedef uint32_t size_type;
|
||||
|
||||
// These are only for internal use within the string classes:
|
||||
typedef StringDataFlags DataFlags;
|
||||
typedef StringClassFlags ClassFlags;
|
||||
|
||||
// These are used to conditionally enable functions for specific character
|
||||
// types.
|
||||
using IsChar = std::enable_if<std::is_same<char, T>::value>;
|
||||
using IsChar16 = std::enable_if<std::is_same<char16_t, T>::value>;
|
||||
|
||||
// Reading iterators.
|
||||
const_char_iterator BeginReading() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
const_char_iterator EndReading() const
|
||||
{
|
||||
return mData + mLength;
|
||||
}
|
||||
|
||||
// Deprecated reading iterators.
|
||||
const_iterator& BeginReading(const_iterator& aIter) const
|
||||
{
|
||||
aIter.mStart = mData;
|
||||
aIter.mEnd = mData + mLength;
|
||||
aIter.mPosition = aIter.mStart;
|
||||
return aIter;
|
||||
}
|
||||
|
||||
const_iterator& EndReading(const_iterator& aIter) const
|
||||
{
|
||||
aIter.mStart = mData;
|
||||
aIter.mEnd = mData + mLength;
|
||||
aIter.mPosition = aIter.mEnd;
|
||||
return aIter;
|
||||
}
|
||||
|
||||
const_char_iterator& BeginReading(const_char_iterator& aIter) const
|
||||
{
|
||||
return aIter = mData;
|
||||
}
|
||||
|
||||
const_char_iterator& EndReading(const_char_iterator& aIter) const
|
||||
{
|
||||
return aIter = mData + mLength;
|
||||
}
|
||||
|
||||
// Accessors.
|
||||
template <typename U> struct raw_type { typedef const U* type; };
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <> struct raw_type<char16_t> { typedef char16ptr_t type; };
|
||||
#endif
|
||||
|
||||
// Returns pointer to string data (not necessarily null-terminated)
|
||||
const typename raw_type<T>::type Data() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
size_type Length() const
|
||||
{
|
||||
return mLength;
|
||||
}
|
||||
|
||||
DataFlags GetDataFlags() const
|
||||
{
|
||||
return mDataFlags;
|
||||
}
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return mLength == 0;
|
||||
}
|
||||
|
||||
bool IsLiteral() const
|
||||
{
|
||||
return !!(mDataFlags & DataFlags::LITERAL);
|
||||
}
|
||||
|
||||
bool IsVoid() const
|
||||
{
|
||||
return !!(mDataFlags & DataFlags::VOIDED);
|
||||
}
|
||||
|
||||
bool IsTerminated() const
|
||||
{
|
||||
return !!(mDataFlags & DataFlags::TERMINATED);
|
||||
}
|
||||
|
||||
char_type CharAt(index_type aIndex) const
|
||||
{
|
||||
NS_ASSERTION(aIndex < mLength, "index exceeds allowable range");
|
||||
return mData[aIndex];
|
||||
}
|
||||
|
||||
char_type operator[](index_type aIndex) const
|
||||
{
|
||||
return CharAt(aIndex);
|
||||
}
|
||||
|
||||
char_type First() const;
|
||||
|
||||
char_type Last() const;
|
||||
|
||||
size_type NS_FASTCALL CountChar(char_type) const;
|
||||
int32_t NS_FASTCALL FindChar(char_type, index_type aOffset = 0) const;
|
||||
|
||||
inline bool Contains(char_type aChar) const
|
||||
{
|
||||
return FindChar(aChar) != kNotFound;
|
||||
}
|
||||
|
||||
// Equality.
|
||||
bool NS_FASTCALL Equals(const self_type&) const;
|
||||
bool NS_FASTCALL Equals(const self_type&, const comparator_type&) const;
|
||||
|
||||
bool NS_FASTCALL Equals(const substring_tuple_type& aTuple) const;
|
||||
bool NS_FASTCALL Equals(const substring_tuple_type& aTuple,
|
||||
const comparator_type& aComp) const;
|
||||
|
||||
bool NS_FASTCALL Equals(const char_type* aData) const;
|
||||
bool NS_FASTCALL Equals(const char_type* aData,
|
||||
const comparator_type& aComp) const;
|
||||
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
bool NS_FASTCALL Equals(char16ptr_t aData) const
|
||||
{
|
||||
return Equals(static_cast<const char16_t*>(aData));
|
||||
}
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
bool NS_FASTCALL Equals(char16ptr_t aData, const comparator_type& aComp) const
|
||||
{
|
||||
return Equals(static_cast<const char16_t*>(aData), aComp);
|
||||
}
|
||||
#endif
|
||||
|
||||
// An efficient comparison with ASCII that can be used even
|
||||
// for wide strings. Call this version when you know the
|
||||
// length of 'data'.
|
||||
bool NS_FASTCALL EqualsASCII(const char* aData, size_type aLen) const;
|
||||
// An efficient comparison with ASCII that can be used even
|
||||
// for wide strings. Call this version when 'data' is
|
||||
// null-terminated.
|
||||
bool NS_FASTCALL EqualsASCII(const char* aData) const;
|
||||
|
||||
// EqualsLiteral must ONLY be applied to an actual literal string, or
|
||||
// a char array *constant* declared without an explicit size.
|
||||
// Do not attempt to use it with a regular char* pointer, or with a
|
||||
// non-constant char array variable. Use EqualsASCII for them.
|
||||
// The template trick to acquire the array length at compile time without
|
||||
// using a macro is due to Corey Kosak, with much thanks.
|
||||
template<int N>
|
||||
inline bool EqualsLiteral(const char (&aStr)[N]) const
|
||||
{
|
||||
return EqualsASCII(aStr, N - 1);
|
||||
}
|
||||
|
||||
// The LowerCaseEquals methods compare the ASCII-lowercase version of
|
||||
// this string (lowercasing only ASCII uppercase characters) to some
|
||||
// ASCII/Literal string. The ASCII string is *not* lowercased for
|
||||
// you. If you compare to an ASCII or literal string that contains an
|
||||
// uppercase character, it is guaranteed to return false. We will
|
||||
// throw assertions too.
|
||||
bool NS_FASTCALL LowerCaseEqualsASCII(const char* aData,
|
||||
size_type aLen) const;
|
||||
bool NS_FASTCALL LowerCaseEqualsASCII(const char* aData) const;
|
||||
|
||||
// LowerCaseEqualsLiteral must ONLY be applied to an actual
|
||||
// literal string, or a char array *constant* declared without an
|
||||
// explicit size. Do not attempt to use it with a regular char*
|
||||
// pointer, or with a non-constant char array variable. Use
|
||||
// LowerCaseEqualsASCII for them.
|
||||
template<int N>
|
||||
bool LowerCaseEqualsLiteral(const char (&aStr)[N]) const
|
||||
{
|
||||
return LowerCaseEqualsASCII(aStr, N - 1);
|
||||
}
|
||||
|
||||
// Returns true if this string overlaps with the given string fragment.
|
||||
bool IsDependentOn(const char_type* aStart, const char_type* aEnd) const
|
||||
{
|
||||
// If it _isn't_ the case that one fragment starts after the other ends,
|
||||
// or ends before the other starts, then, they conflict:
|
||||
//
|
||||
// !(f2.begin >= f1.aEnd || f2.aEnd <= f1.begin)
|
||||
//
|
||||
// Simplified, that gives us:
|
||||
return (aStart < (mData + mLength) && aEnd > mData);
|
||||
}
|
||||
|
||||
protected:
|
||||
nsTStringRepr() = delete; // Never instantiate directly
|
||||
|
||||
constexpr
|
||||
nsTStringRepr(char_type* aData, size_type aLength,
|
||||
DataFlags aDataFlags, ClassFlags aClassFlags)
|
||||
: mData(aData)
|
||||
, mLength(aLength)
|
||||
, mDataFlags(aDataFlags)
|
||||
, mClassFlags(aClassFlags)
|
||||
{
|
||||
}
|
||||
|
||||
char_type* mData;
|
||||
size_type mLength;
|
||||
DataFlags mDataFlags;
|
||||
ClassFlags const mClassFlags;
|
||||
};
|
||||
|
||||
extern template class nsTStringRepr<char>;
|
||||
extern template class nsTStringRepr<char16_t>;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mozilla
|
||||
|
||||
template <typename T>
|
||||
int NS_FASTCALL
|
||||
Compare(const mozilla::detail::nsTStringRepr<T>& aLhs,
|
||||
const mozilla::detail::nsTStringRepr<T>& aRhs,
|
||||
const nsTStringComparator<T>& = nsTDefaultStringComparator<T>());
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
operator!=(const mozilla::detail::nsTStringRepr<T>& aLhs,
|
||||
const mozilla::detail::nsTStringRepr<T>& aRhs)
|
||||
{
|
||||
return !aLhs.Equals(aRhs);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
operator!=(const mozilla::detail::nsTStringRepr<T>& aLhs,
|
||||
const T* aRhs)
|
||||
{
|
||||
return !aLhs.Equals(aRhs);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
operator<(const mozilla::detail::nsTStringRepr<T>& aLhs,
|
||||
const mozilla::detail::nsTStringRepr<T>& aRhs)
|
||||
{
|
||||
return Compare(aLhs, aRhs) < 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
operator<=(const mozilla::detail::nsTStringRepr<T>& aLhs,
|
||||
const mozilla::detail::nsTStringRepr<T>& aRhs)
|
||||
{
|
||||
return Compare(aLhs, aRhs) <= 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
operator==(const mozilla::detail::nsTStringRepr<T>& aLhs,
|
||||
const mozilla::detail::nsTStringRepr<T>& aRhs)
|
||||
{
|
||||
return aLhs.Equals(aRhs);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
operator==(const mozilla::detail::nsTStringRepr<T>& aLhs,
|
||||
const T* aRhs)
|
||||
{
|
||||
return aLhs.Equals(aRhs);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
operator>=(const mozilla::detail::nsTStringRepr<T>& aLhs,
|
||||
const mozilla::detail::nsTStringRepr<T>& aRhs)
|
||||
{
|
||||
return Compare(aLhs, aRhs) >= 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
operator>(const mozilla::detail::nsTStringRepr<T>& aLhs,
|
||||
const mozilla::detail::nsTStringRepr<T>& aRhs)
|
||||
{
|
||||
return Compare(aLhs, aRhs) > 0;
|
||||
}
|
||||
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -5,6 +5,9 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
// IWYU pragma: private, include "nsString.h"
|
||||
|
||||
#ifndef nsTSubstring_h
|
||||
#define nsTSubstring_h
|
||||
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
@ -12,317 +15,14 @@
|
|||
#include "mozilla/IntegerTypeTraits.h"
|
||||
#include "mozilla/Span.h"
|
||||
|
||||
#include "nsTStringRepr.h"
|
||||
|
||||
#ifndef MOZILLA_INTERNAL_API
|
||||
#error "Using XPCOM strings is limited to code linked into libxul."
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The base for string comparators
|
||||
*/
|
||||
class nsTStringComparator_CharT
|
||||
{
|
||||
public:
|
||||
typedef CharT char_type;
|
||||
|
||||
nsTStringComparator_CharT()
|
||||
{
|
||||
}
|
||||
|
||||
virtual int operator()(const char_type*, const char_type*,
|
||||
uint32_t, uint32_t) const = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The default string comparator (case-sensitive comparision)
|
||||
*/
|
||||
class nsTDefaultStringComparator_CharT
|
||||
: public nsTStringComparator_CharT
|
||||
{
|
||||
public:
|
||||
typedef CharT char_type;
|
||||
|
||||
nsTDefaultStringComparator_CharT()
|
||||
{
|
||||
}
|
||||
|
||||
virtual int operator()(const char_type*, const char_type*,
|
||||
uint32_t, uint32_t) const override;
|
||||
};
|
||||
|
||||
class nsTSubstringSplitter_CharT;
|
||||
|
||||
namespace mozilla {
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* nsTStringRepr defines a string's memory layout and some accessor methods.
|
||||
* This class exists so that nsTLiteralString can avoid inheriting
|
||||
* nsTSubstring's destructor. All methods on this class must be const because
|
||||
* literal strings are not writable.
|
||||
*
|
||||
* This class is an implementation detail and should not be instantiated
|
||||
* directly, nor used in any way outside of the string code itself. It is
|
||||
* buried in a namespace to discourage its use in function parameters.
|
||||
* If you need to take a parameter, use [const] ns[C]Substring&.
|
||||
* If you need to instantiate a string, use ns[C]String or descendents.
|
||||
*
|
||||
* NAMES:
|
||||
* nsStringRepr for wide characters
|
||||
* nsCStringRepr for narrow characters
|
||||
*
|
||||
*/
|
||||
class nsTStringRepr_CharT
|
||||
{
|
||||
public:
|
||||
typedef mozilla::fallible_t fallible_t;
|
||||
|
||||
typedef CharT char_type;
|
||||
|
||||
typedef nsCharTraits<char_type> char_traits;
|
||||
typedef char_traits::incompatible_char_type incompatible_char_type;
|
||||
|
||||
typedef nsTStringRepr_CharT self_type;
|
||||
typedef self_type base_string_type;
|
||||
|
||||
typedef nsTSubstring_CharT substring_type;
|
||||
typedef nsTSubstringTuple_CharT substring_tuple_type;
|
||||
typedef nsTString_CharT string_type;
|
||||
|
||||
typedef nsReadingIterator<char_type> const_iterator;
|
||||
typedef nsWritingIterator<char_type> iterator;
|
||||
|
||||
typedef nsTStringComparator_CharT comparator_type;
|
||||
|
||||
typedef char_type* char_iterator;
|
||||
typedef const char_type* const_char_iterator;
|
||||
|
||||
typedef uint32_t index_type;
|
||||
typedef uint32_t size_type;
|
||||
|
||||
// These are only for internal use within the string classes:
|
||||
typedef StringDataFlags DataFlags;
|
||||
typedef StringClassFlags ClassFlags;
|
||||
|
||||
/**
|
||||
* reading iterators
|
||||
*/
|
||||
|
||||
const_char_iterator BeginReading() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
const_char_iterator EndReading() const
|
||||
{
|
||||
return mData + mLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* deprecated reading iterators
|
||||
*/
|
||||
|
||||
const_iterator& BeginReading(const_iterator& aIter) const
|
||||
{
|
||||
aIter.mStart = mData;
|
||||
aIter.mEnd = mData + mLength;
|
||||
aIter.mPosition = aIter.mStart;
|
||||
return aIter;
|
||||
}
|
||||
|
||||
const_iterator& EndReading(const_iterator& aIter) const
|
||||
{
|
||||
aIter.mStart = mData;
|
||||
aIter.mEnd = mData + mLength;
|
||||
aIter.mPosition = aIter.mEnd;
|
||||
return aIter;
|
||||
}
|
||||
|
||||
const_char_iterator& BeginReading(const_char_iterator& aIter) const
|
||||
{
|
||||
return aIter = mData;
|
||||
}
|
||||
|
||||
const_char_iterator& EndReading(const_char_iterator& aIter) const
|
||||
{
|
||||
return aIter = mData + mLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* accessors
|
||||
*/
|
||||
|
||||
// returns pointer to string data (not necessarily null-terminated)
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
char16ptr_t Data() const
|
||||
#else
|
||||
const char_type* Data() const
|
||||
#endif
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
size_type Length() const
|
||||
{
|
||||
return mLength;
|
||||
}
|
||||
|
||||
DataFlags GetDataFlags() const
|
||||
{
|
||||
return mDataFlags;
|
||||
}
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return mLength == 0;
|
||||
}
|
||||
|
||||
bool IsLiteral() const
|
||||
{
|
||||
return !!(mDataFlags & DataFlags::LITERAL);
|
||||
}
|
||||
|
||||
bool IsVoid() const
|
||||
{
|
||||
return !!(mDataFlags & DataFlags::VOIDED);
|
||||
}
|
||||
|
||||
bool IsTerminated() const
|
||||
{
|
||||
return !!(mDataFlags & DataFlags::TERMINATED);
|
||||
}
|
||||
|
||||
char_type CharAt(index_type aIndex) const
|
||||
{
|
||||
NS_ASSERTION(aIndex < mLength, "index exceeds allowable range");
|
||||
return mData[aIndex];
|
||||
}
|
||||
|
||||
char_type operator[](index_type aIndex) const
|
||||
{
|
||||
return CharAt(aIndex);
|
||||
}
|
||||
|
||||
char_type First() const;
|
||||
|
||||
char_type Last() const;
|
||||
|
||||
size_type NS_FASTCALL CountChar(char_type) const;
|
||||
int32_t NS_FASTCALL FindChar(char_type, index_type aOffset = 0) const;
|
||||
|
||||
inline bool Contains(char_type aChar) const
|
||||
{
|
||||
return FindChar(aChar) != kNotFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* equality
|
||||
*/
|
||||
|
||||
bool NS_FASTCALL Equals(const self_type&) const;
|
||||
bool NS_FASTCALL Equals(const self_type&, const comparator_type&) const;
|
||||
|
||||
bool NS_FASTCALL Equals(const substring_tuple_type& aTuple) const;
|
||||
bool NS_FASTCALL Equals(const substring_tuple_type& aTuple,
|
||||
const comparator_type& aComp) const;
|
||||
|
||||
bool NS_FASTCALL Equals(const char_type* aData) const;
|
||||
bool NS_FASTCALL Equals(const char_type* aData,
|
||||
const comparator_type& aComp) const;
|
||||
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
bool NS_FASTCALL Equals(char16ptr_t aData) const
|
||||
{
|
||||
return Equals(static_cast<const char16_t*>(aData));
|
||||
}
|
||||
bool NS_FASTCALL Equals(char16ptr_t aData, const comparator_type& aComp) const
|
||||
{
|
||||
return Equals(static_cast<const char16_t*>(aData), aComp);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* An efficient comparison with ASCII that can be used even
|
||||
* for wide strings. Call this version when you know the
|
||||
* length of 'data'.
|
||||
*/
|
||||
bool NS_FASTCALL EqualsASCII(const char* aData, size_type aLen) const;
|
||||
/**
|
||||
* An efficient comparison with ASCII that can be used even
|
||||
* for wide strings. Call this version when 'data' is
|
||||
* null-terminated.
|
||||
*/
|
||||
bool NS_FASTCALL EqualsASCII(const char* aData) const;
|
||||
|
||||
// EqualsLiteral must ONLY be applied to an actual literal string, or
|
||||
// a char array *constant* declared without an explicit size.
|
||||
// Do not attempt to use it with a regular char* pointer, or with a
|
||||
// non-constant char array variable. Use EqualsASCII for them.
|
||||
// The template trick to acquire the array length at compile time without
|
||||
// using a macro is due to Corey Kosak, with much thanks.
|
||||
template<int N>
|
||||
inline bool EqualsLiteral(const char (&aStr)[N]) const
|
||||
{
|
||||
return EqualsASCII(aStr, N - 1);
|
||||
}
|
||||
|
||||
// The LowerCaseEquals methods compare the ASCII-lowercase version of
|
||||
// this string (lowercasing only ASCII uppercase characters) to some
|
||||
// ASCII/Literal string. The ASCII string is *not* lowercased for
|
||||
// you. If you compare to an ASCII or literal string that contains an
|
||||
// uppercase character, it is guaranteed to return false. We will
|
||||
// throw assertions too.
|
||||
bool NS_FASTCALL LowerCaseEqualsASCII(const char* aData,
|
||||
size_type aLen) const;
|
||||
bool NS_FASTCALL LowerCaseEqualsASCII(const char* aData) const;
|
||||
|
||||
// LowerCaseEqualsLiteral must ONLY be applied to an actual
|
||||
// literal string, or a char array *constant* declared without an
|
||||
// explicit size. Do not attempt to use it with a regular char*
|
||||
// pointer, or with a non-constant char array variable. Use
|
||||
// LowerCaseEqualsASCII for them.
|
||||
template<int N>
|
||||
inline bool LowerCaseEqualsLiteral(const char (&aStr)[N]) const
|
||||
{
|
||||
return LowerCaseEqualsASCII(aStr, N - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if this string overlaps with the given string fragment.
|
||||
*/
|
||||
bool IsDependentOn(const char_type* aStart, const char_type* aEnd) const
|
||||
{
|
||||
/**
|
||||
* if it _isn't_ the case that one fragment starts after the other ends,
|
||||
* or ends before the other starts, then, they conflict:
|
||||
*
|
||||
* !(f2.begin >= f1.aEnd || f2.aEnd <= f1.begin)
|
||||
*
|
||||
* Simplified, that gives us:
|
||||
*/
|
||||
return (aStart < (mData + mLength) && aEnd > mData);
|
||||
}
|
||||
|
||||
protected:
|
||||
nsTStringRepr_CharT() = delete; // Never instantiate directly
|
||||
|
||||
constexpr
|
||||
nsTStringRepr_CharT(char_type* aData, size_type aLength,
|
||||
DataFlags aDataFlags, ClassFlags aClassFlags)
|
||||
: mData(aData)
|
||||
, mLength(aLength)
|
||||
, mDataFlags(aDataFlags)
|
||||
, mClassFlags(aClassFlags)
|
||||
{
|
||||
}
|
||||
|
||||
char_type* mData;
|
||||
size_type mLength;
|
||||
DataFlags mDataFlags;
|
||||
ClassFlags const mClassFlags;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mozilla
|
||||
template <typename T> class nsTSubstringSplitter;
|
||||
template <typename T> class nsTString;
|
||||
|
||||
/**
|
||||
* nsTSubstring is an abstract string class. From an API perspective, this
|
||||
|
@ -336,13 +36,45 @@ protected:
|
|||
* nsACString for narrow characters
|
||||
*
|
||||
*/
|
||||
class nsTSubstring_CharT : public mozilla::detail::nsTStringRepr_CharT
|
||||
template <typename T>
|
||||
class nsTSubstring : public mozilla::detail::nsTStringRepr<T>
|
||||
{
|
||||
public:
|
||||
typedef nsTSubstring_CharT self_type;
|
||||
typedef nsTSubstring<T> self_type;
|
||||
|
||||
typedef nsTString<T> string_type;
|
||||
|
||||
typedef typename mozilla::detail::nsTStringRepr<T> base_string_type;
|
||||
typedef typename base_string_type::substring_type substring_type;
|
||||
|
||||
typedef typename base_string_type::fallible_t fallible_t;
|
||||
|
||||
typedef typename base_string_type::char_type char_type;
|
||||
typedef typename base_string_type::char_traits char_traits;
|
||||
typedef typename base_string_type::incompatible_char_type incompatible_char_type;
|
||||
|
||||
typedef typename base_string_type::substring_tuple_type substring_tuple_type;
|
||||
|
||||
typedef typename base_string_type::const_iterator const_iterator;
|
||||
typedef typename base_string_type::iterator iterator;
|
||||
|
||||
typedef typename base_string_type::comparator_type comparator_type;
|
||||
|
||||
typedef typename base_string_type::char_iterator char_iterator;
|
||||
typedef typename base_string_type::const_char_iterator const_char_iterator;
|
||||
|
||||
typedef typename base_string_type::index_type index_type;
|
||||
typedef typename base_string_type::size_type size_type;
|
||||
|
||||
// These are only for internal use within the string classes:
|
||||
typedef typename base_string_type::DataFlags DataFlags;
|
||||
typedef typename base_string_type::ClassFlags ClassFlags;
|
||||
|
||||
using typename base_string_type::IsChar;
|
||||
using typename base_string_type::IsChar16;
|
||||
|
||||
// this acts like a virtual destructor
|
||||
~nsTSubstring_CharT()
|
||||
~nsTSubstring()
|
||||
{
|
||||
Finalize();
|
||||
}
|
||||
|
@ -354,29 +86,29 @@ public:
|
|||
char_iterator BeginWriting()
|
||||
{
|
||||
if (!EnsureMutable()) {
|
||||
AllocFailed(mLength);
|
||||
AllocFailed(base_string_type::mLength);
|
||||
}
|
||||
|
||||
return mData;
|
||||
return base_string_type::mData;
|
||||
}
|
||||
|
||||
char_iterator BeginWriting(const fallible_t&)
|
||||
{
|
||||
return EnsureMutable() ? mData : char_iterator(0);
|
||||
return EnsureMutable() ? base_string_type::mData : char_iterator(0);
|
||||
}
|
||||
|
||||
char_iterator EndWriting()
|
||||
{
|
||||
if (!EnsureMutable()) {
|
||||
AllocFailed(mLength);
|
||||
AllocFailed(base_string_type::mLength);
|
||||
}
|
||||
|
||||
return mData + mLength;
|
||||
return base_string_type::mData + base_string_type::mLength;
|
||||
}
|
||||
|
||||
char_iterator EndWriting(const fallible_t&)
|
||||
{
|
||||
return EnsureMutable() ? (mData + mLength) : char_iterator(0);
|
||||
return EnsureMutable() ? (base_string_type::mData + base_string_type::mLength) : char_iterator(0);
|
||||
}
|
||||
|
||||
char_iterator& BeginWriting(char_iterator& aIter)
|
||||
|
@ -407,7 +139,7 @@ public:
|
|||
{
|
||||
char_type* data = BeginWriting();
|
||||
aIter.mStart = data;
|
||||
aIter.mEnd = data + mLength;
|
||||
aIter.mEnd = data + base_string_type::mLength;
|
||||
aIter.mPosition = aIter.mStart;
|
||||
return aIter;
|
||||
}
|
||||
|
@ -416,7 +148,7 @@ public:
|
|||
{
|
||||
char_type* data = BeginWriting();
|
||||
aIter.mStart = data;
|
||||
aIter.mEnd = data + mLength;
|
||||
aIter.mEnd = data + base_string_type::mLength;
|
||||
aIter.mPosition = aIter.mEnd;
|
||||
return aIter;
|
||||
}
|
||||
|
@ -443,17 +175,20 @@ public:
|
|||
MOZ_MUST_USE bool NS_FASTCALL Assign(const substring_tuple_type&,
|
||||
const fallible_t&);
|
||||
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
void Assign(char16ptr_t aData)
|
||||
{
|
||||
Assign(static_cast<const char16_t*>(aData));
|
||||
}
|
||||
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
void Assign(char16ptr_t aData, size_type aLength)
|
||||
{
|
||||
Assign(static_cast<const char16_t*>(aData), aLength);
|
||||
}
|
||||
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
MOZ_MUST_USE bool Assign(char16ptr_t aData, size_type aLength,
|
||||
const fallible_t& aFallible)
|
||||
{
|
||||
|
@ -490,13 +225,12 @@ public:
|
|||
{
|
||||
AssignLiteral(aStr, N - 1);
|
||||
}
|
||||
#ifdef CharT_is_PRUnichar
|
||||
template<int N>
|
||||
void AssignLiteral(const char (&aStr)[N])
|
||||
|
||||
template<int N, typename EnableIfChar16 = IsChar16>
|
||||
void AssignLiteral(const incompatible_char_type (&aStr)[N])
|
||||
{
|
||||
AssignASCII(aStr, N - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
self_type& operator=(char_type aChar)
|
||||
{
|
||||
|
@ -508,7 +242,8 @@ public:
|
|||
Assign(aData);
|
||||
return *this;
|
||||
}
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
self_type& operator=(char16ptr_t aData)
|
||||
{
|
||||
Assign(aData);
|
||||
|
@ -587,23 +322,24 @@ public:
|
|||
|
||||
void Append(char_type aChar)
|
||||
{
|
||||
Replace(mLength, 0, aChar);
|
||||
Replace(base_string_type::mLength, 0, aChar);
|
||||
}
|
||||
MOZ_MUST_USE bool Append(char_type aChar, const fallible_t& aFallible)
|
||||
{
|
||||
return Replace(mLength, 0, aChar, aFallible);
|
||||
return Replace(base_string_type::mLength, 0, aChar, aFallible);
|
||||
}
|
||||
void Append(const char_type* aData, size_type aLength = size_type(-1))
|
||||
{
|
||||
Replace(mLength, 0, aData, aLength);
|
||||
Replace(base_string_type::mLength, 0, aData, aLength);
|
||||
}
|
||||
MOZ_MUST_USE bool Append(const char_type* aData, size_type aLength,
|
||||
const fallible_t& aFallible)
|
||||
{
|
||||
return Replace(mLength, 0, aData, aLength, aFallible);
|
||||
return Replace(base_string_type::mLength, 0, aData, aLength, aFallible);
|
||||
}
|
||||
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
void Append(char16ptr_t aData, size_type aLength = size_type(-1))
|
||||
{
|
||||
Append(static_cast<const char16_t*>(aData), aLength);
|
||||
|
@ -612,30 +348,30 @@ public:
|
|||
|
||||
void Append(const self_type& aStr)
|
||||
{
|
||||
Replace(mLength, 0, aStr);
|
||||
Replace(base_string_type::mLength, 0, aStr);
|
||||
}
|
||||
MOZ_MUST_USE bool Append(const self_type& aStr, const fallible_t& aFallible)
|
||||
{
|
||||
return Replace(mLength, 0, aStr, aFallible);
|
||||
return Replace(base_string_type::mLength, 0, aStr, aFallible);
|
||||
}
|
||||
void Append(const substring_tuple_type& aTuple)
|
||||
{
|
||||
Replace(mLength, 0, aTuple);
|
||||
Replace(base_string_type::mLength, 0, aTuple);
|
||||
}
|
||||
|
||||
void AppendASCII(const char* aData, size_type aLength = size_type(-1))
|
||||
{
|
||||
ReplaceASCII(mLength, 0, aData, aLength);
|
||||
ReplaceASCII(base_string_type::mLength, 0, aData, aLength);
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool AppendASCII(const char* aData, const fallible_t& aFallible)
|
||||
{
|
||||
return ReplaceASCII(mLength, 0, aData, size_type(-1), aFallible);
|
||||
return ReplaceASCII(base_string_type::mLength, 0, aData, size_type(-1), aFallible);
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool AppendASCII(const char* aData, size_type aLength, const fallible_t& aFallible)
|
||||
{
|
||||
return ReplaceASCII(mLength, 0, aData, aLength, aFallible);
|
||||
return ReplaceASCII(base_string_type::mLength, 0, aData, aLength, aFallible);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -704,21 +440,23 @@ public:
|
|||
template<int N>
|
||||
void AppendLiteral(const char_type (&aStr)[N])
|
||||
{
|
||||
ReplaceLiteral(mLength, 0, aStr, N - 1);
|
||||
ReplaceLiteral(base_string_type::mLength, 0, aStr, N - 1);
|
||||
}
|
||||
#ifdef CharT_is_PRUnichar
|
||||
template<int N>
|
||||
void AppendLiteral(const char (&aStr)[N])
|
||||
|
||||
// Only enable for T = char16_t
|
||||
template<int N, typename EnableIfChar16 = IsChar16>
|
||||
void AppendLiteral(const incompatible_char_type (&aStr)[N])
|
||||
{
|
||||
AppendASCII(aStr, N - 1);
|
||||
}
|
||||
|
||||
template<int N>
|
||||
MOZ_MUST_USE bool AppendLiteral(const char (&aStr)[N], const fallible_t& aFallible)
|
||||
// Only enable for T = char16_t
|
||||
template<int N, typename EnableIfChar16 = IsChar16>
|
||||
MOZ_MUST_USE bool
|
||||
AppendLiteral(const incompatible_char_type (&aStr)[N], const fallible_t& aFallible)
|
||||
{
|
||||
return AppendASCII(aStr, N - 1, aFallible);
|
||||
}
|
||||
#endif
|
||||
|
||||
self_type& operator+=(char_type aChar)
|
||||
{
|
||||
|
@ -730,7 +468,8 @@ public:
|
|||
Append(aData);
|
||||
return *this;
|
||||
}
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
self_type& operator+=(char16ptr_t aData)
|
||||
{
|
||||
Append(aData);
|
||||
|
@ -757,7 +496,8 @@ public:
|
|||
{
|
||||
Replace(aPos, 0, aData, aLength);
|
||||
}
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
void Insert(char16ptr_t aData, index_type aPos,
|
||||
size_type aLength = size_type(-1))
|
||||
{
|
||||
|
@ -787,7 +527,7 @@ public:
|
|||
Replace(aCutStart, aCutLength, char_traits::sEmptyBuffer, 0);
|
||||
}
|
||||
|
||||
nsTSubstringSplitter_CharT Split(const char_type aChar) const;
|
||||
nsTSubstringSplitter<T> Split(const char_type aChar) const;
|
||||
|
||||
/**
|
||||
* buffer sizing
|
||||
|
@ -810,7 +550,7 @@ public:
|
|||
|
||||
void Truncate(size_type aNewLength = 0)
|
||||
{
|
||||
NS_ASSERTION(aNewLength <= mLength, "Truncate cannot make string longer");
|
||||
NS_ASSERTION(aNewLength <= base_string_type::mLength, "Truncate cannot make string longer");
|
||||
SetLength(aNewLength);
|
||||
}
|
||||
|
||||
|
@ -828,8 +568,8 @@ public:
|
|||
*/
|
||||
inline size_type GetData(const char_type** aData) const
|
||||
{
|
||||
*aData = mData;
|
||||
return mLength;
|
||||
*aData = base_string_type::mData;
|
||||
return base_string_type::mLength;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -845,11 +585,11 @@ public:
|
|||
size_type GetMutableData(char_type** aData, size_type aNewLen = size_type(-1))
|
||||
{
|
||||
if (!EnsureMutable(aNewLen)) {
|
||||
AllocFailed(aNewLen == size_type(-1) ? mLength : aNewLen);
|
||||
AllocFailed(aNewLen == size_type(-1) ? base_string_type::mLength : aNewLen);
|
||||
}
|
||||
|
||||
*aData = mData;
|
||||
return mLength;
|
||||
*aData = base_string_type::mData;
|
||||
return base_string_type::mLength;
|
||||
}
|
||||
|
||||
size_type GetMutableData(char_type** aData, size_type aNewLen, const fallible_t&)
|
||||
|
@ -859,16 +599,18 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
*aData = mData;
|
||||
return mLength;
|
||||
*aData = base_string_type::mData;
|
||||
return base_string_type::mLength;
|
||||
}
|
||||
|
||||
#if defined(CharT_is_PRUnichar) && defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
size_type GetMutableData(wchar_t** aData, size_type aNewLen = size_type(-1))
|
||||
{
|
||||
return GetMutableData(reinterpret_cast<char16_t**>(aData), aNewLen);
|
||||
}
|
||||
|
||||
template <typename EnableIfChar16 = IsChar16>
|
||||
size_type GetMutableData(wchar_t** aData, size_type aNewLen,
|
||||
const fallible_t& aFallible)
|
||||
{
|
||||
|
@ -883,12 +625,12 @@ public:
|
|||
|
||||
operator mozilla::Span<char_type>()
|
||||
{
|
||||
return mozilla::MakeSpan(BeginWriting(), Length());
|
||||
return mozilla::MakeSpan(BeginWriting(), base_string_type::Length());
|
||||
}
|
||||
|
||||
operator mozilla::Span<const char_type>() const
|
||||
{
|
||||
return mozilla::MakeSpan(BeginReading(), Length());
|
||||
return mozilla::MakeSpan(base_string_type::BeginReading(), base_string_type::Length());
|
||||
}
|
||||
|
||||
void Append(mozilla::Span<const char_type> aSpan)
|
||||
|
@ -908,19 +650,21 @@ public:
|
|||
return Append(aSpan.Elements(), len, aFallible);
|
||||
}
|
||||
|
||||
#if !defined(CharT_is_PRUnichar)
|
||||
template <typename EnableIfChar = IsChar>
|
||||
operator mozilla::Span<uint8_t>()
|
||||
{
|
||||
return mozilla::MakeSpan(reinterpret_cast<uint8_t*>(BeginWriting()),
|
||||
Length());
|
||||
base_string_type::Length());
|
||||
}
|
||||
|
||||
template <typename EnableIfChar = IsChar>
|
||||
operator mozilla::Span<const uint8_t>() const
|
||||
{
|
||||
return mozilla::MakeSpan(reinterpret_cast<const uint8_t*>(BeginReading()),
|
||||
Length());
|
||||
return mozilla::MakeSpan(reinterpret_cast<const uint8_t*>(base_string_type::BeginReading()),
|
||||
base_string_type::Length());
|
||||
}
|
||||
|
||||
template <typename EnableIfChar = IsChar>
|
||||
void Append(mozilla::Span<const uint8_t> aSpan)
|
||||
{
|
||||
auto len = aSpan.Length();
|
||||
|
@ -928,6 +672,7 @@ public:
|
|||
Append(reinterpret_cast<const char*>(aSpan.Elements()), len);
|
||||
}
|
||||
|
||||
template <typename EnableIfChar = IsChar>
|
||||
MOZ_MUST_USE bool Append(mozilla::Span<const uint8_t> aSpan,
|
||||
const fallible_t& aFallible)
|
||||
{
|
||||
|
@ -938,7 +683,6 @@ public:
|
|||
return Append(
|
||||
reinterpret_cast<const char*>(aSpan.Elements()), len, aFallible);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* string data is never null, but can be marked void. if true, the
|
||||
|
@ -995,7 +739,7 @@ public:
|
|||
*/
|
||||
void ForgetSharedBuffer()
|
||||
{
|
||||
if (mDataFlags & DataFlags::SHARED) {
|
||||
if (base_string_type::mDataFlags & DataFlags::SHARED) {
|
||||
SetToEmptyBuffer();
|
||||
}
|
||||
}
|
||||
|
@ -1003,8 +747,8 @@ public:
|
|||
protected:
|
||||
void AssertValid()
|
||||
{
|
||||
MOZ_ASSERT(!(mClassFlags & ClassFlags::NULL_TERMINATED) ||
|
||||
(mDataFlags & DataFlags::TERMINATED),
|
||||
MOZ_ASSERT(!(this->mClassFlags & ClassFlags::NULL_TERMINATED) ||
|
||||
(this->mDataFlags & DataFlags::TERMINATED),
|
||||
"String classes whose static type guarantees a null-terminated "
|
||||
"buffer must not be assigned a non-null-terminated buffer.");
|
||||
}
|
||||
|
@ -1015,8 +759,8 @@ public:
|
|||
* this is public to support automatic conversion of tuple to string
|
||||
* base type, which helps avoid converting to nsTAString.
|
||||
*/
|
||||
MOZ_IMPLICIT nsTSubstring_CharT(const substring_tuple_type& aTuple)
|
||||
: nsTStringRepr_CharT(nullptr, 0, DataFlags(0), ClassFlags(0))
|
||||
MOZ_IMPLICIT nsTSubstring(const substring_tuple_type& aTuple)
|
||||
: base_string_type(nullptr, 0, DataFlags(0), ClassFlags(0))
|
||||
{
|
||||
AssertValid();
|
||||
Assign(aTuple);
|
||||
|
@ -1038,11 +782,11 @@ public:
|
|||
size_t SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf)
|
||||
const;
|
||||
|
||||
template<class T>
|
||||
template<class N>
|
||||
void NS_ABORT_OOM(T)
|
||||
{
|
||||
struct never {}; // a compiler-friendly way to do static_assert(false)
|
||||
static_assert(mozilla::IsSame<T, never>::value,
|
||||
static_assert(mozilla::IsSame<N, never>::value,
|
||||
"In string classes, use AllocFailed to account for sizeof(char_type). "
|
||||
"Use the global ::NS_ABORT_OOM if you really have a count of bytes.");
|
||||
}
|
||||
|
@ -1055,27 +799,27 @@ public:
|
|||
protected:
|
||||
|
||||
// default initialization
|
||||
nsTSubstring_CharT()
|
||||
: nsTStringRepr_CharT(char_traits::sEmptyBuffer, 0, DataFlags::TERMINATED,
|
||||
ClassFlags(0))
|
||||
nsTSubstring()
|
||||
: base_string_type(char_traits::sEmptyBuffer, 0, DataFlags::TERMINATED,
|
||||
ClassFlags(0))
|
||||
{
|
||||
AssertValid();
|
||||
}
|
||||
|
||||
// copy-constructor, constructs as dependent on given object
|
||||
// (NOTE: this is for internal use only)
|
||||
nsTSubstring_CharT(const self_type& aStr)
|
||||
: nsTStringRepr_CharT(aStr.mData, aStr.mLength,
|
||||
aStr.mDataFlags & (DataFlags::TERMINATED | DataFlags::VOIDED),
|
||||
ClassFlags(0))
|
||||
nsTSubstring(const self_type& aStr)
|
||||
: base_string_type(aStr.base_string_type::mData, aStr.base_string_type::mLength,
|
||||
aStr.base_string_type::mDataFlags & (DataFlags::TERMINATED | DataFlags::VOIDED),
|
||||
ClassFlags(0))
|
||||
{
|
||||
AssertValid();
|
||||
}
|
||||
|
||||
// initialization with ClassFlags
|
||||
explicit nsTSubstring_CharT(ClassFlags aClassFlags)
|
||||
: nsTStringRepr_CharT(char_traits::sEmptyBuffer, 0, DataFlags::TERMINATED,
|
||||
aClassFlags)
|
||||
explicit nsTSubstring(ClassFlags aClassFlags)
|
||||
: base_string_type(char_traits::sEmptyBuffer, 0, DataFlags::TERMINATED,
|
||||
aClassFlags)
|
||||
{
|
||||
AssertValid();
|
||||
}
|
||||
|
@ -1083,15 +827,15 @@ protected:
|
|||
/**
|
||||
* allows for direct initialization of a nsTSubstring object.
|
||||
*/
|
||||
nsTSubstring_CharT(char_type* aData, size_type aLength,
|
||||
DataFlags aDataFlags, ClassFlags aClassFlags)
|
||||
nsTSubstring(char_type* aData, size_type aLength,
|
||||
DataFlags aDataFlags, ClassFlags aClassFlags)
|
||||
// XXXbz or can I just include nscore.h and use NS_BUILD_REFCNT_LOGGING?
|
||||
#if defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING)
|
||||
#define XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
|
||||
;
|
||||
#else
|
||||
#undef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
|
||||
: nsTStringRepr_CharT(aData, aLength, aDataFlags, aClassFlags)
|
||||
: base_string_type(aData, aLength, aDataFlags, aClassFlags)
|
||||
{
|
||||
AssertValid();
|
||||
MOZ_RELEASE_ASSERT(CheckCapacity(aLength), "String is too large.");
|
||||
|
@ -1100,17 +844,17 @@ protected:
|
|||
|
||||
void SetToEmptyBuffer()
|
||||
{
|
||||
mData = char_traits::sEmptyBuffer;
|
||||
mLength = 0;
|
||||
mDataFlags = DataFlags::TERMINATED;
|
||||
base_string_type::mData = char_traits::sEmptyBuffer;
|
||||
base_string_type::mLength = 0;
|
||||
base_string_type::mDataFlags = DataFlags::TERMINATED;
|
||||
AssertValid();
|
||||
}
|
||||
|
||||
void SetData(char_type* aData, size_type aLength, DataFlags aDataFlags)
|
||||
{
|
||||
mData = aData;
|
||||
mLength = aLength;
|
||||
mDataFlags = aDataFlags;
|
||||
base_string_type::mData = aData;
|
||||
base_string_type::mLength = aLength;
|
||||
base_string_type::mDataFlags = aDataFlags;
|
||||
AssertValid();
|
||||
}
|
||||
|
||||
|
@ -1213,85 +957,27 @@ public:
|
|||
void NS_FASTCALL AssignLiteral(const char_type* aData, size_type aLength);
|
||||
};
|
||||
|
||||
static_assert(sizeof(nsTSubstring_CharT) ==
|
||||
sizeof(mozilla::detail::nsTStringRepr_CharT),
|
||||
extern template class nsTSubstring<char>;
|
||||
extern template class nsTSubstring<char16_t>;
|
||||
|
||||
static_assert(sizeof(nsTSubstring<char>) ==
|
||||
sizeof(mozilla::detail::nsTStringRepr<char>),
|
||||
"Don't add new data fields to nsTSubstring_CharT. "
|
||||
"Add to nsTStringRepr_CharT instead.");
|
||||
"Add to nsTStringRepr<T> instead.");
|
||||
|
||||
int NS_FASTCALL
|
||||
Compare(const nsTSubstring_CharT::base_string_type& aLhs,
|
||||
const nsTSubstring_CharT::base_string_type& aRhs,
|
||||
const nsTStringComparator_CharT& = nsTDefaultStringComparator_CharT());
|
||||
|
||||
|
||||
inline bool
|
||||
operator!=(const nsTSubstring_CharT::base_string_type& aLhs,
|
||||
const nsTSubstring_CharT::base_string_type& aRhs)
|
||||
{
|
||||
return !aLhs.Equals(aRhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(const nsTSubstring_CharT::base_string_type& aLhs,
|
||||
const nsTSubstring_CharT::char_type* aRhs)
|
||||
{
|
||||
return !aLhs.Equals(aRhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(const nsTSubstring_CharT::base_string_type& aLhs,
|
||||
const nsTSubstring_CharT::base_string_type& aRhs)
|
||||
{
|
||||
return Compare(aLhs, aRhs) < 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<=(const nsTSubstring_CharT::base_string_type& aLhs,
|
||||
const nsTSubstring_CharT::base_string_type& aRhs)
|
||||
{
|
||||
return Compare(aLhs, aRhs) <= 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(const nsTSubstring_CharT::base_string_type& aLhs,
|
||||
const nsTSubstring_CharT::base_string_type& aRhs)
|
||||
{
|
||||
return aLhs.Equals(aRhs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(const nsTSubstring_CharT::base_string_type& aLhs,
|
||||
const nsTSubstring_CharT::char_type* aRhs)
|
||||
{
|
||||
return aLhs.Equals(aRhs);
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
operator>=(const nsTSubstring_CharT::base_string_type& aLhs,
|
||||
const nsTSubstring_CharT::base_string_type& aRhs)
|
||||
{
|
||||
return Compare(aLhs, aRhs) >= 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>(const nsTSubstring_CharT::base_string_type& aLhs,
|
||||
const nsTSubstring_CharT::base_string_type& aRhs)
|
||||
{
|
||||
return Compare(aLhs, aRhs) > 0;
|
||||
}
|
||||
|
||||
// You should not need to instantiate this class directly.
|
||||
// Use nsTSubstring::Split instead.
|
||||
class nsTSubstringSplitter_CharT
|
||||
template <typename T>
|
||||
class nsTSubstringSplitter
|
||||
{
|
||||
typedef nsTSubstring_CharT::size_type size_type;
|
||||
typedef nsTSubstring_CharT::char_type char_type;
|
||||
typedef typename nsTSubstring<T>::size_type size_type;
|
||||
typedef typename nsTSubstring<T>::char_type char_type;
|
||||
|
||||
class nsTSubstringSplit_Iter
|
||||
{
|
||||
public:
|
||||
nsTSubstringSplit_Iter(const nsTSubstringSplitter_CharT& aObj,
|
||||
nsTSubstringSplit_Iter(const nsTSubstringSplitter<T>& aObj,
|
||||
size_type aPos)
|
||||
: mObj(aObj)
|
||||
, mPos(aPos)
|
||||
|
@ -1303,7 +989,7 @@ class nsTSubstringSplitter_CharT
|
|||
return mPos != other.mPos;
|
||||
}
|
||||
|
||||
const nsTDependentSubstring_CharT& operator*() const;
|
||||
const nsTDependentSubstring<T>& operator*() const;
|
||||
|
||||
const nsTSubstringSplit_Iter& operator++()
|
||||
{
|
||||
|
@ -1312,18 +998,18 @@ class nsTSubstringSplitter_CharT
|
|||
}
|
||||
|
||||
private:
|
||||
const nsTSubstringSplitter_CharT& mObj;
|
||||
const nsTSubstringSplitter<T>& mObj;
|
||||
size_type mPos;
|
||||
};
|
||||
|
||||
private:
|
||||
const nsTSubstring_CharT* const mStr;
|
||||
mozilla::UniquePtr<nsTDependentSubstring_CharT[]> mArray;
|
||||
const nsTSubstring<T>* const mStr;
|
||||
mozilla::UniquePtr<nsTDependentSubstring<T>[]> mArray;
|
||||
size_type mArraySize;
|
||||
const char_type mDelim;
|
||||
|
||||
public:
|
||||
nsTSubstringSplitter_CharT(const nsTSubstring_CharT* aStr, char_type aDelim);
|
||||
nsTSubstringSplitter(const nsTSubstring<T>* aStr, char_type aDelim);
|
||||
|
||||
nsTSubstringSplit_Iter begin() const
|
||||
{
|
||||
|
@ -1335,28 +1021,46 @@ public:
|
|||
return nsTSubstringSplit_Iter(*this, mArraySize);
|
||||
}
|
||||
|
||||
const nsTDependentSubstring_CharT& Get(const size_type index) const
|
||||
const nsTDependentSubstring<T>& Get(const size_type index) const
|
||||
{
|
||||
MOZ_ASSERT(index < mArraySize);
|
||||
return mArray[index];
|
||||
}
|
||||
};
|
||||
|
||||
extern template class nsTSubstringSplitter<char>;
|
||||
extern template class nsTSubstringSplitter<char16_t>;
|
||||
|
||||
/**
|
||||
* Span integration
|
||||
*/
|
||||
namespace mozilla {
|
||||
|
||||
inline Span<CharT>
|
||||
MakeSpan(nsTSubstring_CharT& aString)
|
||||
inline Span<char>
|
||||
MakeSpan(nsTSubstring<char>& aString)
|
||||
{
|
||||
return aString;
|
||||
}
|
||||
|
||||
inline Span<const CharT>
|
||||
MakeSpan(const nsTSubstring_CharT& aString)
|
||||
inline Span<const char>
|
||||
MakeSpan(const nsTSubstring<char>& aString)
|
||||
{
|
||||
return aString;
|
||||
}
|
||||
|
||||
inline Span<char16_t>
|
||||
MakeSpan(nsTSubstring<char16_t>& aString)
|
||||
{
|
||||
return aString;
|
||||
}
|
||||
|
||||
inline Span<const char16_t>
|
||||
MakeSpan(const nsTSubstring<char16_t>& aString)
|
||||
{
|
||||
return aString;
|
||||
}
|
||||
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
* computes the aggregate string length
|
||||
*/
|
||||
|
||||
nsTSubstringTuple_CharT::size_type
|
||||
nsTSubstringTuple_CharT::Length() const
|
||||
template <typename T>
|
||||
typename nsTSubstringTuple<T>::size_type
|
||||
nsTSubstringTuple<T>::Length() const
|
||||
{
|
||||
mozilla::CheckedInt<size_type> len;
|
||||
if (mHead) {
|
||||
|
@ -32,8 +33,9 @@ nsTSubstringTuple_CharT::Length() const
|
|||
* method. the string written to |aBuf| is not null-terminated.
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
nsTSubstringTuple_CharT::WriteTo(char_type* aBuf, uint32_t aBufLen) const
|
||||
nsTSubstringTuple<T>::WriteTo(char_type* aBuf, uint32_t aBufLen) const
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(aBufLen >= mFragB->Length(), "buffer too small");
|
||||
uint32_t headLen = aBufLen - mFragB->Length();
|
||||
|
@ -53,9 +55,10 @@ nsTSubstringTuple_CharT::WriteTo(char_type* aBuf, uint32_t aBufLen) const
|
|||
* the given char sequence.
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
nsTSubstringTuple_CharT::IsDependentOn(const char_type* aStart,
|
||||
const char_type* aEnd) const
|
||||
nsTSubstringTuple<T>::IsDependentOn(const char_type* aStart,
|
||||
const char_type* aEnd) const
|
||||
{
|
||||
// we aStart with the right-most fragment since it is faster to check.
|
||||
|
||||
|
|
|
@ -5,8 +5,13 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
// IWYU pragma: private, include "nsString.h"
|
||||
|
||||
#ifndef nsTSubstringTuple_h
|
||||
#define nsTSubstringTuple_h
|
||||
|
||||
#include "nsTStringRepr.h"
|
||||
|
||||
/**
|
||||
* nsTSubstringTuple_CharT
|
||||
* nsTSubstringTuple
|
||||
*
|
||||
* Represents a tuple of string fragments. Built as a recursive binary tree.
|
||||
* It is used to implement the concatenation of two or more string objects.
|
||||
|
@ -14,29 +19,30 @@
|
|||
* NOTE: This class is a private implementation detail and should never be
|
||||
* referenced outside the string code.
|
||||
*/
|
||||
class nsTSubstringTuple_CharT
|
||||
template <typename T>
|
||||
class nsTSubstringTuple
|
||||
{
|
||||
public:
|
||||
|
||||
typedef CharT char_type;
|
||||
typedef nsCharTraits<char_type> char_traits;
|
||||
typedef T char_type;
|
||||
typedef nsCharTraits<char_type> char_traits;
|
||||
|
||||
typedef nsTSubstringTuple_CharT self_type;
|
||||
typedef mozilla::detail::nsTStringRepr_CharT base_string_type;
|
||||
typedef uint32_t size_type;
|
||||
typedef nsTSubstringTuple<T> self_type;
|
||||
typedef mozilla::detail::nsTStringRepr<char_type> base_string_type;
|
||||
typedef uint32_t size_type;
|
||||
|
||||
public:
|
||||
|
||||
nsTSubstringTuple_CharT(const base_string_type* aStrA,
|
||||
const base_string_type* aStrB)
|
||||
nsTSubstringTuple(const base_string_type* aStrA,
|
||||
const base_string_type* aStrB)
|
||||
: mHead(nullptr)
|
||||
, mFragA(aStrA)
|
||||
, mFragB(aStrB)
|
||||
{
|
||||
}
|
||||
|
||||
nsTSubstringTuple_CharT(const self_type& aHead,
|
||||
const base_string_type* aStrB)
|
||||
nsTSubstringTuple(const self_type& aHead,
|
||||
const base_string_type* aStrB)
|
||||
: mHead(&aHead)
|
||||
, mFragA(nullptr) // this fragment is ignored when aHead != nullptr
|
||||
, mFragB(aStrB)
|
||||
|
@ -68,16 +74,20 @@ private:
|
|||
const base_string_type* const mFragB;
|
||||
};
|
||||
|
||||
inline const nsTSubstringTuple_CharT
|
||||
operator+(const nsTSubstringTuple_CharT::base_string_type& aStrA,
|
||||
const nsTSubstringTuple_CharT::base_string_type& aStrB)
|
||||
template <typename T>
|
||||
inline const nsTSubstringTuple<T>
|
||||
operator+(const mozilla::detail::nsTStringRepr<T>& aStrA,
|
||||
const mozilla::detail::nsTStringRepr<T>& aStrB)
|
||||
{
|
||||
return nsTSubstringTuple_CharT(&aStrA, &aStrB);
|
||||
return nsTSubstringTuple<T>(&aStrA, &aStrB);
|
||||
}
|
||||
|
||||
inline const nsTSubstringTuple_CharT
|
||||
operator+(const nsTSubstringTuple_CharT& aHead,
|
||||
const nsTSubstringTuple_CharT::base_string_type& aStrB)
|
||||
template <typename T>
|
||||
inline const nsTSubstringTuple<T>
|
||||
operator+(const nsTSubstringTuple<T>& aHead,
|
||||
const mozilla::detail::nsTStringRepr<T>& aStrB)
|
||||
{
|
||||
return nsTSubstringTuple_CharT(aHead, &aStrB);
|
||||
return nsTSubstringTuple<T>(aHead, &aStrB);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
// This file provides concrete instantiations for externed string template
|
||||
// classes and functions.
|
||||
|
||||
// ================
|
||||
// Template classes
|
||||
// ================
|
||||
template class mozilla::detail::nsTStringRepr<char>;
|
||||
template class mozilla::detail::nsTStringRepr<char16_t>;
|
||||
|
||||
template class nsTLiteralString<char>;
|
||||
template class nsTLiteralString<char16_t>;
|
||||
|
||||
template class nsTSubstring<char>;
|
||||
template class nsTSubstring<char16_t>;
|
||||
|
||||
template class nsTDependentSubstring<char>;
|
||||
template class nsTDependentSubstring<char16_t>;
|
||||
|
||||
// Note: nsTString is skipped as it's implicitly instantiated by derived
|
||||
// classes.
|
||||
|
||||
template class nsTFixedString<char>;
|
||||
template class nsTFixedString<char16_t>;
|
||||
template class nsTAutoStringN<char, 64>;
|
||||
template class nsTAutoStringN<char16_t, 64>;
|
||||
|
||||
template class nsTDependentString<char>;
|
||||
template class nsTDependentString<char16_t>;
|
||||
|
||||
template class nsTPromiseFlatString<char>;
|
||||
template class nsTPromiseFlatString<char16_t>;
|
||||
|
||||
template class nsTSubstringSplitter<char>;
|
||||
template class nsTSubstringSplitter<char16_t>;
|
||||
|
||||
template class nsTDefaultStringComparator<char>;
|
||||
template class nsTDefaultStringComparator<char16_t>;
|
||||
|
||||
// =============================
|
||||
// Templated top-level functions
|
||||
// =============================
|
||||
|
||||
template
|
||||
int
|
||||
Compare<char>(mozilla::detail::nsTStringRepr<char> const&,
|
||||
mozilla::detail::nsTStringRepr<char> const&,
|
||||
nsTStringComparator<char> const&);
|
||||
|
||||
template
|
||||
int
|
||||
Compare<char16_t>(mozilla::detail::nsTStringRepr<char16_t> const&,
|
||||
mozilla::detail::nsTStringRepr<char16_t> const&,
|
||||
nsTStringComparator<char16_t> const&);
|
||||
|
||||
template
|
||||
nsTDependentSubstring<char> const
|
||||
Substring<char>(char const*, char const*);
|
||||
|
||||
template
|
||||
nsTDependentSubstring<char16_t> const
|
||||
Substring<char16_t>(char16_t const*, char16_t const*);
|
||||
|
||||
// =========================================================
|
||||
// Templated member functions that are conditionally enabled
|
||||
// =========================================================
|
||||
|
||||
template
|
||||
int32_t
|
||||
nsTString<char16_t>::Find(const self_type&, int32_t, int32_t) const;
|
||||
|
||||
template
|
||||
int32_t
|
||||
nsTString<char16_t>::Find(const char_type*, int32_t, int32_t) const;
|
||||
|
||||
template
|
||||
int32_t
|
||||
nsTString<char16_t>::RFind(const self_type&, int32_t, int32_t) const;
|
||||
|
||||
template
|
||||
int32_t
|
||||
nsTString<char16_t>::RFind(const char_type*, int32_t, int32_t) const;
|
||||
|
||||
template
|
||||
int32_t
|
||||
nsTString<char16_t>::FindCharInSet(const char*, int32_t) const;
|
||||
|
||||
template
|
||||
int32_t
|
||||
nsTString<char>::Compare(const char_type*, bool, int32_t) const;
|
||||
|
||||
template
|
||||
bool
|
||||
nsTString<char16_t>::EqualsIgnoreCase(const incompatible_char_type*,
|
||||
int32_t) const;
|
||||
|
||||
template
|
||||
bool
|
||||
nsTString<char16_t>::StripChars(const incompatible_char_type*,
|
||||
const fallible_t&);
|
||||
|
||||
template
|
||||
void
|
||||
nsTString<char16_t>::StripChars(const incompatible_char_type*);
|
||||
|
||||
template
|
||||
void
|
||||
nsTString<char16_t>::ReplaceChar(const char*, char16_t);
|
|
@ -1,28 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
// IWYU pragma: private, include "nsString.h"
|
||||
|
||||
#define CharT char
|
||||
#define CharT_is_char 1
|
||||
#define nsTAString_IncompatibleCharT nsAString
|
||||
#define nsTString_CharT nsCString
|
||||
#define nsTStringRepr_CharT nsCStringRepr
|
||||
#define nsTFixedString_CharT nsFixedCString
|
||||
#define nsTAutoStringN_CharT nsAutoCStringN
|
||||
#define nsTAutoString_CharT nsAutoCString
|
||||
#define nsTSubstring_CharT nsACString
|
||||
#define PrintfAppend_CharT PrintfAppend_nsACString
|
||||
#define nsTSubstringTuple_CharT nsCSubstringTuple
|
||||
#define nsTStringComparator_CharT nsCStringComparator
|
||||
#define nsTDefaultStringComparator_CharT nsDefaultCStringComparator
|
||||
#define nsTDependentString_CharT nsDependentCString
|
||||
#define nsTDependentSubstring_CharT nsDependentCSubstring
|
||||
#define nsTLiteralString_CharT nsLiteralCString
|
||||
#define nsTGetterCopies_CharT nsCGetterCopies
|
||||
#define nsTPromiseFlatString_CharT nsPromiseFlatCString
|
||||
#define TPromiseFlatString_CharT PromiseFlatCString
|
||||
#define nsTSubstringSplitter_CharT nsCSubstringSplitter
|
||||
#define TNullString_CharT NullCString
|
|
@ -1,28 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
// IWYU pragma: private, include "nsString.h"
|
||||
|
||||
#define CharT char16_t
|
||||
#define CharT_is_PRUnichar 1
|
||||
#define nsTAString_IncompatibleCharT nsACString
|
||||
#define nsTString_CharT nsString
|
||||
#define nsTStringRepr_CharT nsStringRepr
|
||||
#define nsTFixedString_CharT nsFixedString
|
||||
#define nsTAutoStringN_CharT nsAutoStringN
|
||||
#define nsTAutoString_CharT nsAutoString
|
||||
#define nsTSubstring_CharT nsAString
|
||||
#define PrintfAppend_CharT PrintfAppend_nsAString
|
||||
#define nsTSubstringTuple_CharT nsSubstringTuple
|
||||
#define nsTStringComparator_CharT nsStringComparator
|
||||
#define nsTDefaultStringComparator_CharT nsDefaultStringComparator
|
||||
#define nsTDependentString_CharT nsDependentString
|
||||
#define nsTDependentSubstring_CharT nsDependentSubstring
|
||||
#define nsTLiteralString_CharT nsLiteralString
|
||||
#define nsTGetterCopies_CharT nsGetterCopies
|
||||
#define nsTPromiseFlatString_CharT nsPromiseFlatString
|
||||
#define TPromiseFlatString_CharT PromiseFlatString
|
||||
#define nsTSubstringSplitter_CharT nsSubstringSplitter
|
||||
#define TNullString_CharT NullString
|
|
@ -1,29 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
// IWYU pragma: private, include "nsString.h"
|
||||
|
||||
#undef CharT
|
||||
#undef CharT_is_PRUnichar
|
||||
#undef CharT_is_char
|
||||
#undef nsTAString_IncompatibleCharT
|
||||
#undef nsTString_CharT
|
||||
#undef nsTStringRepr_CharT
|
||||
#undef nsTFixedString_CharT
|
||||
#undef nsTAutoStringN_CharT
|
||||
#undef nsTAutoString_CharT
|
||||
#undef nsTSubstring_CharT
|
||||
#undef PrintfAppend_CharT
|
||||
#undef nsTSubstringTuple_CharT
|
||||
#undef nsTStringComparator_CharT
|
||||
#undef nsTDefaultStringComparator_CharT
|
||||
#undef nsTDependentString_CharT
|
||||
#undef nsTDependentSubstring_CharT
|
||||
#undef nsTLiteralString_CharT
|
||||
#undef nsTGetterCopies_CharT
|
||||
#undef nsTPromiseFlatString_CharT
|
||||
#undef TPromiseFlatString_CharT
|
||||
#undef nsTSubstringSplitter_CharT
|
||||
#undef TNullString_CharT
|
Загрузка…
Ссылка в новой задаче