зеркало из https://github.com/mozilla/pjs.git
Bug 737164 part A - make the nsTSubstring string API infallible by default. Note that this patch for reviewing sanity does not modify the subclass APIs, that will be a separate revision, r=jlebar
--HG-- extra : rebase_source : 48db8595e35e95ea6ddc3a35a553d5641b8d1a42
This commit is contained in:
Родитель
603705ce16
Коммит
c19ee28084
|
@ -277,7 +277,7 @@ Base64Encode(const nsACString &aBinaryData, nsACString &aString)
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
|
||||||
// Add one byte for null termination.
|
// Add one byte for null termination.
|
||||||
if (aString.SetCapacity(stringLen + 1) &&
|
if (aString.SetCapacity(stringLen + 1, fallible_t()) &&
|
||||||
(buffer = aString.BeginWriting()) &&
|
(buffer = aString.BeginWriting()) &&
|
||||||
PL_Base64Encode(aBinaryData.BeginReading(), aBinaryData.Length(), buffer)) {
|
PL_Base64Encode(aBinaryData.BeginReading(), aBinaryData.Length(), buffer)) {
|
||||||
// PL_Base64Encode doesn't null terminate the buffer for us when we pass
|
// PL_Base64Encode doesn't null terminate the buffer for us when we pass
|
||||||
|
@ -321,7 +321,7 @@ Base64Decode(const nsACString &aString, nsACString &aBinaryData)
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
|
||||||
// Add one byte for null termination.
|
// Add one byte for null termination.
|
||||||
if (aBinaryData.SetCapacity(binaryDataLen + 1) &&
|
if (aBinaryData.SetCapacity(binaryDataLen + 1, fallible_t()) &&
|
||||||
(buffer = aBinaryData.BeginWriting()) &&
|
(buffer = aBinaryData.BeginWriting()) &&
|
||||||
PL_Base64Decode(aString.BeginReading(), aString.Length(), buffer)) {
|
PL_Base64Decode(aString.BeginReading(), aString.Length(), buffer)) {
|
||||||
// PL_Base64Decode doesn't null terminate the buffer for us when we pass
|
// PL_Base64Decode doesn't null terminate the buffer for us when we pass
|
||||||
|
|
|
@ -58,6 +58,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "mozilla/fallible.h"
|
||||||
|
|
||||||
#define kNotFound -1
|
#define kNotFound -1
|
||||||
|
|
||||||
// declare nsAString
|
// declare nsAString
|
||||||
|
|
|
@ -83,6 +83,8 @@ class nsTDefaultStringComparator_CharT
|
||||||
class nsTSubstring_CharT
|
class nsTSubstring_CharT
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef mozilla::fallible_t fallible_t;
|
||||||
|
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
|
|
||||||
typedef nsCharTraits<char_type> char_traits;
|
typedef nsCharTraits<char_type> char_traits;
|
||||||
|
@ -155,15 +157,50 @@ class nsTSubstring_CharT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char_iterator BeginWriting()
|
char_iterator BeginWriting()
|
||||||
|
{
|
||||||
|
if (!EnsureMutable())
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
|
||||||
|
return mData;
|
||||||
|
}
|
||||||
|
|
||||||
|
char_iterator BeginWriting( const fallible_t& )
|
||||||
{
|
{
|
||||||
return EnsureMutable() ? mData : char_iterator(0);
|
return EnsureMutable() ? mData : char_iterator(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
char_iterator EndWriting()
|
char_iterator EndWriting()
|
||||||
|
{
|
||||||
|
if (!EnsureMutable())
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
|
||||||
|
return mData + mLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
char_iterator EndWriting( const fallible_t& )
|
||||||
{
|
{
|
||||||
return EnsureMutable() ? (mData + mLength) : char_iterator(0);
|
return EnsureMutable() ? (mData + mLength) : char_iterator(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char_iterator& BeginWriting( char_iterator& iter )
|
||||||
|
{
|
||||||
|
return iter = BeginWriting();
|
||||||
|
}
|
||||||
|
|
||||||
|
char_iterator& BeginWriting( char_iterator& iter, const fallible_t& )
|
||||||
|
{
|
||||||
|
return iter = BeginWriting(fallible_t());
|
||||||
|
}
|
||||||
|
|
||||||
|
char_iterator& EndWriting( char_iterator& iter )
|
||||||
|
{
|
||||||
|
return iter = EndWriting();
|
||||||
|
}
|
||||||
|
|
||||||
|
char_iterator& EndWriting( char_iterator& iter, const fallible_t& )
|
||||||
|
{
|
||||||
|
return iter = EndWriting(fallible_t());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* deprecated writing iterators
|
* deprecated writing iterators
|
||||||
|
@ -171,7 +208,7 @@ class nsTSubstring_CharT
|
||||||
|
|
||||||
iterator& BeginWriting( iterator& iter )
|
iterator& BeginWriting( iterator& iter )
|
||||||
{
|
{
|
||||||
char_type *data = EnsureMutable() ? mData : nsnull;
|
char_type *data = BeginWriting();
|
||||||
iter.mStart = data;
|
iter.mStart = data;
|
||||||
iter.mEnd = data + mLength;
|
iter.mEnd = data + mLength;
|
||||||
iter.mPosition = iter.mStart;
|
iter.mPosition = iter.mStart;
|
||||||
|
@ -180,24 +217,13 @@ class nsTSubstring_CharT
|
||||||
|
|
||||||
iterator& EndWriting( iterator& iter )
|
iterator& EndWriting( iterator& iter )
|
||||||
{
|
{
|
||||||
char_type *data = EnsureMutable() ? mData : nsnull;
|
char_type *data = BeginWriting();
|
||||||
iter.mStart = data;
|
iter.mStart = data;
|
||||||
iter.mEnd = data + mLength;
|
iter.mEnd = data + mLength;
|
||||||
iter.mPosition = iter.mEnd;
|
iter.mPosition = iter.mEnd;
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
char_iterator& BeginWriting( char_iterator& iter )
|
|
||||||
{
|
|
||||||
return iter = EnsureMutable() ? mData : char_iterator(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
char_iterator& EndWriting( char_iterator& iter )
|
|
||||||
{
|
|
||||||
return iter = EnsureMutable() ? (mData + mLength) : char_iterator(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* accessors
|
* accessors
|
||||||
*/
|
*/
|
||||||
|
@ -339,16 +365,35 @@ class nsTSubstring_CharT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void NS_FASTCALL Assign( char_type c );
|
void NS_FASTCALL Assign( char_type c );
|
||||||
void NS_FASTCALL Assign( const char_type* data, size_type length = size_type(-1) );
|
bool NS_FASTCALL Assign( char_type c, const fallible_t& ) NS_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
void NS_FASTCALL
|
||||||
|
Assign( const char_type* data, size_type length = size_type(-1) );
|
||||||
|
bool NS_FASTCALL Assign( const char_type* data, size_type length, const fallible_t& ) NS_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
void NS_FASTCALL Assign( const self_type& );
|
void NS_FASTCALL Assign( const self_type& );
|
||||||
|
bool NS_FASTCALL Assign( const self_type&, const fallible_t& ) NS_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
void NS_FASTCALL Assign( const substring_tuple_type& );
|
void NS_FASTCALL Assign( const substring_tuple_type& );
|
||||||
|
bool NS_FASTCALL Assign( const substring_tuple_type&, const fallible_t& ) NS_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
void NS_FASTCALL AssignASCII( const char* data, size_type length );
|
void NS_FASTCALL AssignASCII( const char* data, size_type length );
|
||||||
void NS_FASTCALL AssignASCII( const char* data );
|
bool NS_FASTCALL AssignASCII( const char* data, size_type length, const fallible_t& ) NS_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
void NS_FASTCALL AssignASCII( const char* data )
|
||||||
|
{
|
||||||
|
AssignASCII(data, strlen(data));
|
||||||
|
}
|
||||||
|
bool NS_FASTCALL AssignASCII( const char* data, const fallible_t& ) NS_WARN_UNUSED_RESULT
|
||||||
|
{
|
||||||
|
return AssignASCII(data, strlen(data), fallible_t());
|
||||||
|
}
|
||||||
|
|
||||||
// AssignLiteral must ONLY be applied to an actual literal string.
|
// AssignLiteral must ONLY be applied to an actual literal string.
|
||||||
// Do not attempt to use it with a regular char* pointer, or with a char
|
// Do not attempt to use it with a regular char* pointer, or with a char
|
||||||
// array variable. Use AssignASCII for those.
|
// array variable. Use AssignASCII for those.
|
||||||
|
// There are not fallible version of these methods because they only really
|
||||||
|
// apply to small allocations that we wouldn't want to check anyway.
|
||||||
#ifdef NS_DISABLE_LITERAL_TEMPLATE
|
#ifdef NS_DISABLE_LITERAL_TEMPLATE
|
||||||
void AssignLiteral( const char* str )
|
void AssignLiteral( const char* str )
|
||||||
{ AssignASCII(str); }
|
{ AssignASCII(str); }
|
||||||
|
@ -375,7 +420,7 @@ class nsTSubstring_CharT
|
||||||
|
|
||||||
void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, char_type c );
|
void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, char_type c );
|
||||||
void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length = size_type(-1) );
|
void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length = size_type(-1) );
|
||||||
void Replace( index_type cutStart, size_type cutLength, const self_type& str ) { Replace(cutStart, cutLength, str.Data(), str.Length()); }
|
void Replace( index_type cutStart, size_type cutLength, const self_type& str ) { Replace(cutStart, cutLength, str.Data(), str.Length()); }
|
||||||
void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& tuple );
|
void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& tuple );
|
||||||
|
|
||||||
void NS_FASTCALL ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) );
|
void NS_FASTCALL ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) );
|
||||||
|
@ -467,14 +512,12 @@ class nsTSubstring_CharT
|
||||||
/**
|
/**
|
||||||
* Attempts to set the capacity to the given size, without affecting
|
* Attempts to set the capacity to the given size, without affecting
|
||||||
* the length of the string. Also ensures that the buffer is mutable.
|
* the length of the string. Also ensures that the buffer is mutable.
|
||||||
*
|
|
||||||
* @returns true on success
|
|
||||||
* false on out-of-memory, or if requesting a size bigger
|
|
||||||
* than a string can hold (2^31 chars).
|
|
||||||
*/
|
*/
|
||||||
bool NS_FASTCALL SetCapacity( size_type newCapacity );
|
void NS_FASTCALL SetCapacity( size_type newCapacity );
|
||||||
|
bool NS_FASTCALL SetCapacity( size_type newCapacity, const fallible_t& ) NS_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
bool NS_FASTCALL SetLength( size_type newLength );
|
void NS_FASTCALL SetLength( size_type newLength );
|
||||||
|
bool NS_FASTCALL SetLength( size_type newLength, const fallible_t& ) NS_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
void Truncate( size_type newLength = 0 )
|
void Truncate( size_type newLength = 0 )
|
||||||
{
|
{
|
||||||
|
@ -510,7 +553,16 @@ class nsTSubstring_CharT
|
||||||
* @returns The length of the buffer in characters or 0 if unable to
|
* @returns The length of the buffer in characters or 0 if unable to
|
||||||
* satisfy the request due to low-memory conditions.
|
* satisfy the request due to low-memory conditions.
|
||||||
*/
|
*/
|
||||||
inline size_type GetMutableData( char_type** data, size_type newLen = size_type(-1) )
|
size_type GetMutableData( char_type** data, size_type newLen = size_type(-1) )
|
||||||
|
{
|
||||||
|
if (!EnsureMutable(newLen))
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
|
||||||
|
*data = mData;
|
||||||
|
return mLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type GetMutableData( char_type** data, size_type newLen, const fallible_t& )
|
||||||
{
|
{
|
||||||
if (!EnsureMutable(newLen))
|
if (!EnsureMutable(newLen))
|
||||||
{
|
{
|
||||||
|
@ -684,7 +736,7 @@ class nsTSubstring_CharT
|
||||||
* memory.
|
* memory.
|
||||||
*/
|
*/
|
||||||
bool ReplacePrep(index_type cutStart, size_type cutLength,
|
bool ReplacePrep(index_type cutStart, size_type cutLength,
|
||||||
size_type newLength)
|
size_type newLength) NS_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
cutLength = NS_MIN(cutLength, mLength - cutStart);
|
cutLength = NS_MIN(cutLength, mLength - cutStart);
|
||||||
PRUint32 newTotalLen = mLength - cutLength + newLength;
|
PRUint32 newTotalLen = mLength - cutLength + newLength;
|
||||||
|
@ -698,10 +750,11 @@ class nsTSubstring_CharT
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NS_FASTCALL ReplacePrepInternal(index_type cutStart,
|
bool NS_FASTCALL ReplacePrepInternal(index_type cutStart,
|
||||||
size_type cutLength,
|
size_type cutLength,
|
||||||
size_type newFragLength,
|
size_type newFragLength,
|
||||||
size_type newTotalLength);
|
size_type newTotalLength)
|
||||||
|
NS_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the number of writable storage units starting at mData.
|
* returns the number of writable storage units starting at mData.
|
||||||
* the value does not include space for the null-terminator character.
|
* the value does not include space for the null-terminator character.
|
||||||
|
@ -715,7 +768,7 @@ class nsTSubstring_CharT
|
||||||
* this helper function can be called prior to directly manipulating
|
* this helper function can be called prior to directly manipulating
|
||||||
* the contents of mData. see, for example, BeginWriting.
|
* the contents of mData. see, for example, BeginWriting.
|
||||||
*/
|
*/
|
||||||
bool NS_FASTCALL EnsureMutable( size_type newLen = size_type(-1) );
|
bool NS_FASTCALL EnsureMutable( size_type newLen = size_type(-1) ) NS_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns true if this string overlaps with the given string fragment.
|
* returns true if this string overlaps with the given string fragment.
|
||||||
|
|
|
@ -290,7 +290,8 @@ nsTString_CharT::SetCharAt( PRUnichar aChar, PRUint32 aIndex )
|
||||||
if (aIndex >= mLength)
|
if (aIndex >= mLength)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
EnsureMutable();
|
if (!EnsureMutable())
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
|
||||||
mData[aIndex] = CharT(aChar);
|
mData[aIndex] = CharT(aChar);
|
||||||
return true;
|
return true;
|
||||||
|
@ -304,7 +305,9 @@ nsTString_CharT::SetCharAt( PRUnichar aChar, PRUint32 aIndex )
|
||||||
void
|
void
|
||||||
nsTString_CharT::StripChars( const char* aSet )
|
nsTString_CharT::StripChars( const char* aSet )
|
||||||
{
|
{
|
||||||
EnsureMutable();
|
if (!EnsureMutable())
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
|
||||||
mLength = nsBufferRoutines<CharT>::strip_chars(mData, mLength, aSet);
|
mLength = nsBufferRoutines<CharT>::strip_chars(mData, mLength, aSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +325,8 @@ nsTString_CharT::StripWhitespace()
|
||||||
void
|
void
|
||||||
nsTString_CharT::ReplaceChar( char_type aOldChar, char_type aNewChar )
|
nsTString_CharT::ReplaceChar( char_type aOldChar, char_type aNewChar )
|
||||||
{
|
{
|
||||||
EnsureMutable(); // XXX do this lazily?
|
if (!EnsureMutable()) // XXX do this lazily?
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
|
||||||
for (PRUint32 i=0; i<mLength; ++i)
|
for (PRUint32 i=0; i<mLength; ++i)
|
||||||
{
|
{
|
||||||
|
@ -334,7 +338,8 @@ nsTString_CharT::ReplaceChar( char_type aOldChar, char_type aNewChar )
|
||||||
void
|
void
|
||||||
nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
|
nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
|
||||||
{
|
{
|
||||||
EnsureMutable(); // XXX do this lazily?
|
if (!EnsureMutable()) // XXX do this lazily?
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
|
||||||
char_type* data = mData;
|
char_type* data = mData;
|
||||||
PRUint32 lenRemaining = mLength;
|
PRUint32 lenRemaining = mLength;
|
||||||
|
|
|
@ -291,7 +291,7 @@ nsTSubstring_CharT::EnsureMutable( size_type newLen )
|
||||||
|
|
||||||
newLen = mLength;
|
newLen = mLength;
|
||||||
}
|
}
|
||||||
return SetLength(newLen);
|
return SetLength(newLen, fallible_t());
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -300,19 +300,36 @@ nsTSubstring_CharT::EnsureMutable( size_type newLen )
|
||||||
void
|
void
|
||||||
nsTSubstring_CharT::Assign( char_type c )
|
nsTSubstring_CharT::Assign( char_type c )
|
||||||
{
|
{
|
||||||
if (ReplacePrep(0, mLength, 1))
|
if (!ReplacePrep(0, mLength, 1))
|
||||||
*mData = c;
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
|
||||||
|
*mData = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsTSubstring_CharT::Assign( char_type c, const fallible_t& )
|
||||||
|
{
|
||||||
|
if (!ReplacePrep(0, mLength, 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*mData = c;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsTSubstring_CharT::Assign( const char_type* data, size_type length )
|
nsTSubstring_CharT::Assign( const char_type* data, size_type length )
|
||||||
{
|
{
|
||||||
// unfortunately, some callers pass null :-(
|
if (!Assign(data, length, fallible_t()))
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsTSubstring_CharT::Assign( const char_type* data, size_type length, const fallible_t& )
|
||||||
|
{
|
||||||
if (!data)
|
if (!data)
|
||||||
{
|
{
|
||||||
Truncate();
|
Truncate();
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length == size_type(-1))
|
if (length == size_type(-1))
|
||||||
|
@ -320,54 +337,66 @@ nsTSubstring_CharT::Assign( const char_type* data, size_type length )
|
||||||
|
|
||||||
if (IsDependentOn(data, data + length))
|
if (IsDependentOn(data, data + length))
|
||||||
{
|
{
|
||||||
// take advantage of sharing here...
|
return Assign(string_type(data, length), fallible_t());
|
||||||
Assign(string_type(data, length));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ReplacePrep(0, mLength, length))
|
if (!ReplacePrep(0, mLength, length))
|
||||||
char_traits::copy(mData, data, length);
|
return false;
|
||||||
|
|
||||||
|
char_traits::copy(mData, data, length);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsTSubstring_CharT::AssignASCII( const char* data, size_type length )
|
nsTSubstring_CharT::AssignASCII( const char* data, size_type length )
|
||||||
|
{
|
||||||
|
if (!AssignASCII(data, length, fallible_t()))
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsTSubstring_CharT::AssignASCII( const char* data, size_type length, const fallible_t& )
|
||||||
{
|
{
|
||||||
// A Unicode string can't depend on an ASCII string buffer,
|
// A Unicode string can't depend on an ASCII string buffer,
|
||||||
// so this dependence check only applies to CStrings.
|
// so this dependence check only applies to CStrings.
|
||||||
#ifdef CharT_is_char
|
#ifdef CharT_is_char
|
||||||
if (IsDependentOn(data, data + length))
|
if (IsDependentOn(data, data + length))
|
||||||
{
|
{
|
||||||
// take advantage of sharing here...
|
return Assign(string_type(data, length), fallible_t());
|
||||||
Assign(string_type(data, length));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ReplacePrep(0, mLength, length))
|
if (!ReplacePrep(0, mLength, length))
|
||||||
char_traits::copyASCII(mData, data, length);
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
void
|
char_traits::copyASCII(mData, data, length);
|
||||||
nsTSubstring_CharT::AssignASCII( const char* data )
|
return true;
|
||||||
{
|
|
||||||
AssignASCII(data, strlen(data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsTSubstring_CharT::Assign( const self_type& str )
|
nsTSubstring_CharT::Assign( const self_type& str )
|
||||||
|
{
|
||||||
|
if (!Assign(str, fallible_t()))
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsTSubstring_CharT::Assign( const self_type& str, const fallible_t& )
|
||||||
{
|
{
|
||||||
// |str| could be sharable. we need to check its flags to know how to
|
// |str| could be sharable. we need to check its flags to know how to
|
||||||
// deal with it.
|
// deal with it.
|
||||||
|
|
||||||
if (&str == this)
|
if (&str == this)
|
||||||
return;
|
return true;
|
||||||
|
|
||||||
if (!str.mLength)
|
if (!str.mLength)
|
||||||
{
|
{
|
||||||
Truncate();
|
Truncate();
|
||||||
mFlags |= str.mFlags & F_VOIDED;
|
mFlags |= str.mFlags & F_VOIDED;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if (str.mFlags & F_SHARED)
|
|
||||||
|
if (str.mFlags & F_SHARED)
|
||||||
{
|
{
|
||||||
// nice! we can avoid a string copy :-)
|
// nice! we can avoid a string copy :-)
|
||||||
|
|
||||||
|
@ -382,22 +411,27 @@ nsTSubstring_CharT::Assign( const self_type& str )
|
||||||
|
|
||||||
// get an owning reference to the mData
|
// get an owning reference to the mData
|
||||||
nsStringBuffer::FromData(mData)->AddRef();
|
nsStringBuffer::FromData(mData)->AddRef();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
// else, treat this like an ordinary assignment.
|
||||||
// else, treat this like an ordinary assignment.
|
return Assign(str.Data(), str.Length(), fallible_t());
|
||||||
Assign(str.Data(), str.Length());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsTSubstring_CharT::Assign( const substring_tuple_type& tuple )
|
nsTSubstring_CharT::Assign( const substring_tuple_type& tuple )
|
||||||
|
{
|
||||||
|
if (!Assign(tuple, fallible_t()))
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsTSubstring_CharT::Assign( const substring_tuple_type& tuple, const fallible_t& )
|
||||||
{
|
{
|
||||||
if (tuple.IsDependentOn(mData, mData + mLength))
|
if (tuple.IsDependentOn(mData, mData + mLength))
|
||||||
{
|
{
|
||||||
// take advantage of sharing here...
|
// take advantage of sharing here...
|
||||||
Assign(string_type(tuple));
|
return Assign(string_type(tuple), fallible_t());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type length = tuple.Length();
|
size_type length = tuple.Length();
|
||||||
|
@ -405,14 +439,16 @@ nsTSubstring_CharT::Assign( const substring_tuple_type& tuple )
|
||||||
// don't use ReplacePrep here because it changes the length
|
// don't use ReplacePrep here because it changes the length
|
||||||
char_type* oldData;
|
char_type* oldData;
|
||||||
PRUint32 oldFlags;
|
PRUint32 oldFlags;
|
||||||
if (MutatePrep(length, &oldData, &oldFlags)) {
|
if (!MutatePrep(length, &oldData, &oldFlags))
|
||||||
if (oldData)
|
return false;
|
||||||
::ReleaseData(oldData, oldFlags);
|
|
||||||
|
|
||||||
tuple.WriteTo(mData, length);
|
if (oldData)
|
||||||
mData[length] = 0;
|
::ReleaseData(oldData, oldFlags);
|
||||||
mLength = length;
|
|
||||||
}
|
tuple.WriteTo(mData, length);
|
||||||
|
mData[length] = 0;
|
||||||
|
mLength = length;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -522,8 +558,15 @@ nsTSubstring_CharT::Replace( index_type cutStart, size_type cutLength, const sub
|
||||||
tuple.WriteTo(mData + cutStart, length);
|
tuple.WriteTo(mData + cutStart, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
nsTSubstring_CharT::SetCapacity( size_type capacity )
|
nsTSubstring_CharT::SetCapacity( size_type capacity )
|
||||||
|
{
|
||||||
|
if (!SetCapacity(capacity, fallible_t()))
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsTSubstring_CharT::SetCapacity( size_type capacity, const fallible_t& )
|
||||||
{
|
{
|
||||||
// capacity does not include room for the terminating null char
|
// capacity does not include room for the terminating null char
|
||||||
|
|
||||||
|
@ -534,42 +577,48 @@ nsTSubstring_CharT::SetCapacity( size_type capacity )
|
||||||
mData = char_traits::sEmptyBuffer;
|
mData = char_traits::sEmptyBuffer;
|
||||||
mLength = 0;
|
mLength = 0;
|
||||||
SetDataFlags(F_TERMINATED);
|
SetDataFlags(F_TERMINATED);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
char_type* oldData;
|
||||||
|
PRUint32 oldFlags;
|
||||||
|
if (!MutatePrep(capacity, &oldData, &oldFlags))
|
||||||
|
return false; // out-of-memory
|
||||||
|
|
||||||
|
// compute new string length
|
||||||
|
size_type newLen = NS_MIN(mLength, capacity);
|
||||||
|
|
||||||
|
if (oldData)
|
||||||
{
|
{
|
||||||
char_type* oldData;
|
// preserve old data
|
||||||
PRUint32 oldFlags;
|
if (mLength > 0)
|
||||||
if (!MutatePrep(capacity, &oldData, &oldFlags))
|
char_traits::copy(mData, oldData, newLen);
|
||||||
return false; // out-of-memory
|
|
||||||
|
|
||||||
// compute new string length
|
::ReleaseData(oldData, oldFlags);
|
||||||
size_type newLen = NS_MIN(mLength, capacity);
|
|
||||||
|
|
||||||
if (oldData)
|
|
||||||
{
|
|
||||||
// preserve old data
|
|
||||||
if (mLength > 0)
|
|
||||||
char_traits::copy(mData, oldData, newLen);
|
|
||||||
|
|
||||||
::ReleaseData(oldData, oldFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
// adjust mLength if our buffer shrunk down in size
|
|
||||||
if (newLen < mLength)
|
|
||||||
mLength = newLen;
|
|
||||||
|
|
||||||
// always null-terminate here, even if the buffer got longer. this is
|
|
||||||
// for backwards compat with the old string implementation.
|
|
||||||
mData[capacity] = char_type(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// adjust mLength if our buffer shrunk down in size
|
||||||
|
if (newLen < mLength)
|
||||||
|
mLength = newLen;
|
||||||
|
|
||||||
|
// always null-terminate here, even if the buffer got longer. this is
|
||||||
|
// for backwards compat with the old string implementation.
|
||||||
|
mData[capacity] = char_type(0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
nsTSubstring_CharT::SetLength( size_type length )
|
nsTSubstring_CharT::SetLength( size_type length )
|
||||||
{
|
{
|
||||||
if (!SetCapacity(length))
|
SetCapacity(length);
|
||||||
|
mLength = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsTSubstring_CharT::SetLength( size_type length, const fallible_t& )
|
||||||
|
{
|
||||||
|
if (!SetCapacity(length, fallible_t()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mLength = length;
|
mLength = length;
|
||||||
|
@ -683,7 +732,8 @@ nsTSubstring_CharT::StripChar( char_type aChar, PRInt32 aOffset )
|
||||||
if (mLength == 0 || aOffset >= PRInt32(mLength))
|
if (mLength == 0 || aOffset >= PRInt32(mLength))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EnsureMutable(); // XXX do this lazily?
|
if (!EnsureMutable()) // XXX do this lazily?
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
|
||||||
// XXX(darin): this code should defer writing until necessary.
|
// XXX(darin): this code should defer writing until necessary.
|
||||||
|
|
||||||
|
@ -707,7 +757,8 @@ nsTSubstring_CharT::StripChars( const char_type* aChars, PRUint32 aOffset )
|
||||||
if (aOffset >= PRUint32(mLength))
|
if (aOffset >= PRUint32(mLength))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EnsureMutable(); // XXX do this lazily?
|
if (!EnsureMutable()) // XXX do this lazily?
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
|
||||||
// XXX(darin): this code should defer writing until necessary.
|
// XXX(darin): this code should defer writing until necessary.
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче