|
@@ -254,13 +254,14 @@ class String::StringData : protected StringDataImpl
|
|
public:
|
|
public:
|
|
|
|
|
|
///
|
|
///
|
|
- StringData( const StringChar* data, bool interned = false )
|
|
|
|
|
|
+ StringData( const StringChar* data, U32 length, bool interned = false )
|
|
{
|
|
{
|
|
mRefCount = 1;
|
|
mRefCount = 1;
|
|
mNumChars = U32_MAX;
|
|
mNumChars = U32_MAX;
|
|
mHashCase = U32_MAX;
|
|
mHashCase = U32_MAX;
|
|
mHashNoCase = U32_MAX;
|
|
mHashNoCase = U32_MAX;
|
|
mUTF16 = NULL;
|
|
mUTF16 = NULL;
|
|
|
|
+ mLength = length;
|
|
mIsInterned = interned;
|
|
mIsInterned = interned;
|
|
|
|
|
|
// mLength is initialized by operator new()
|
|
// mLength is initialized by operator new()
|
|
@@ -280,13 +281,33 @@ class String::StringData : protected StringDataImpl
|
|
|
|
|
|
~StringData()
|
|
~StringData()
|
|
{
|
|
{
|
|
|
|
+ AssertFatal( mRefCount == 0, "StringData::~StringData invalid refcount" );
|
|
|
|
+
|
|
if( mUTF16 )
|
|
if( mUTF16 )
|
|
delete [] mUTF16;
|
|
delete [] mUTF16;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ static StringData* Create(const StringChar* data, U32 len, bool interned = false)
|
|
|
|
+ {
|
|
|
|
+ void* memory = dMalloc(sizeof(StringData) + sizeof(StringChar) * len);
|
|
|
|
+ StringData* result = new(memory) StringData(data, len, interned);
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static StringData* Create(const StringChar* data, U32 len, DataChunker& chunker, bool interned = false)
|
|
|
|
+ {
|
|
|
|
+ // StringData *str = static_cast<StringData*>( chunker.alloc( size + len * sizeof(StringChar) ) );
|
|
|
|
+
|
|
|
|
+ // str->mLength = len;
|
|
|
|
+
|
|
|
|
+ void* memory = chunker.alloc( sizeof(StringData) + len * sizeof(StringChar)); //dMalloc(sizeof(StringData) + sizeof(Stringchar) * len);
|
|
|
|
+ StringData* result = new(memory) StringData(data, len, interned);
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
|
|
- void* operator new(size_t size, U32 len);
|
|
|
|
- void* operator new( size_t size, U32 len, DataChunker& chunker );
|
|
|
|
- void operator delete(void *);
|
|
|
|
|
|
+ // void* operator new(size_t size, U32 len);
|
|
|
|
+ // void* operator new( size_t size, U32 len, DataChunker& chunker );
|
|
|
|
+ // void operator delete(void *);
|
|
|
|
|
|
bool isShared() const
|
|
bool isShared() const
|
|
{
|
|
{
|
|
@@ -492,6 +513,7 @@ DefineEngineFunction( dumpStringMemStats, void, (), , "()"
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
+/*
|
|
void* String::StringData::operator new( size_t size, U32 len )
|
|
void* String::StringData::operator new( size_t size, U32 len )
|
|
{
|
|
{
|
|
AssertFatal( len != 0, "String::StringData::operator new() - string must not be empty" );
|
|
AssertFatal( len != 0, "String::StringData::operator new() - string must not be empty" );
|
|
@@ -506,7 +528,9 @@ void* String::StringData::operator new( size_t size, U32 len )
|
|
|
|
|
|
return str;
|
|
return str;
|
|
}
|
|
}
|
|
|
|
+*/
|
|
|
|
|
|
|
|
+/*
|
|
void String::StringData::operator delete(void *ptr)
|
|
void String::StringData::operator delete(void *ptr)
|
|
{
|
|
{
|
|
StringData* sub = static_cast<StringData *>(ptr);
|
|
StringData* sub = static_cast<StringData *>(ptr);
|
|
@@ -519,7 +543,9 @@ void String::StringData::operator delete(void *ptr)
|
|
|
|
|
|
dFree( ptr );
|
|
dFree( ptr );
|
|
}
|
|
}
|
|
|
|
+*/
|
|
|
|
|
|
|
|
+/*
|
|
void* String::StringData::operator new( size_t size, U32 len, DataChunker& chunker )
|
|
void* String::StringData::operator new( size_t size, U32 len, DataChunker& chunker )
|
|
{
|
|
{
|
|
AssertFatal( len != 0, "String::StringData::operator new() - string must not be empty" );
|
|
AssertFatal( len != 0, "String::StringData::operator new() - string must not be empty" );
|
|
@@ -534,6 +560,7 @@ void* String::StringData::operator new( size_t size, U32 len, DataChunker& chunk
|
|
|
|
|
|
return str;
|
|
return str;
|
|
}
|
|
}
|
|
|
|
+*/
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
@@ -556,7 +583,8 @@ String::String(const StringChar *str)
|
|
if( str && *str )
|
|
if( str && *str )
|
|
{
|
|
{
|
|
U32 len = dStrlen(str);
|
|
U32 len = dStrlen(str);
|
|
- _string = new ( len ) StringData( str );
|
|
|
|
|
|
+ // _string = new ( len ) StringData( str );
|
|
|
|
+ _string = StringData::Create(str, len);
|
|
}
|
|
}
|
|
else
|
|
else
|
|
_string = StringData::Empty();
|
|
_string = StringData::Empty();
|
|
@@ -567,7 +595,7 @@ String::String(const StringChar *str, SizeType len)
|
|
PROFILE_SCOPE(String_char_len_constructor);
|
|
PROFILE_SCOPE(String_char_len_constructor);
|
|
if (str && *str && len!=0)
|
|
if (str && *str && len!=0)
|
|
{
|
|
{
|
|
- _string = new ( len ) StringData( str );
|
|
|
|
|
|
+ _string = StringData::Create(str, len);
|
|
}
|
|
}
|
|
else
|
|
else
|
|
_string = StringData::Empty();
|
|
_string = StringData::Empty();
|
|
@@ -581,7 +609,7 @@ String::String(const UTF16 *str)
|
|
{
|
|
{
|
|
UTF8* utf8 = createUTF8string( str );
|
|
UTF8* utf8 = createUTF8string( str );
|
|
U32 len = dStrlen( utf8 );
|
|
U32 len = dStrlen( utf8 );
|
|
- _string = new ( len ) StringData( utf8 );
|
|
|
|
|
|
+ _string = StringData::Create(utf8, len);
|
|
delete [] utf8;
|
|
delete [] utf8;
|
|
}
|
|
}
|
|
else
|
|
else
|
|
@@ -619,7 +647,9 @@ String String::intern() const
|
|
|
|
|
|
// Create new.
|
|
// Create new.
|
|
|
|
|
|
- StringData* data = new ( length(), sInternTable->mChunker ) StringData( c_str(), true );
|
|
|
|
|
|
+ StringData* data = StringData::Create(c_str(), length(), sInternTable->mChunker);
|
|
|
|
+
|
|
|
|
+ //StringData* data = new ( length(), sInternTable->mChunker ) StringData( c_str(), true );
|
|
iter = sInternTable->insertUnique( data, data );
|
|
iter = sInternTable->insertUnique( data, data );
|
|
|
|
|
|
return ( *iter ).value;
|
|
return ( *iter ).value;
|
|
@@ -710,7 +740,8 @@ String& String::operator=(StringChar c)
|
|
{
|
|
{
|
|
_string->release();
|
|
_string->release();
|
|
|
|
|
|
- _string = new ( 2 ) StringData( 0 );
|
|
|
|
|
|
+ //_string = new ( 2 ) StringData( 0 );
|
|
|
|
+ _string = StringData::Create(NULL, 2);
|
|
_string->utf8()[ 0 ] = c;
|
|
_string->utf8()[ 0 ] = c;
|
|
_string->utf8()[ 1 ] = '\0';
|
|
_string->utf8()[ 1 ] = '\0';
|
|
|
|
|
|
@@ -721,8 +752,9 @@ String& String::operator+=(StringChar c)
|
|
{
|
|
{
|
|
// Append the given string into a new string
|
|
// Append the given string into a new string
|
|
U32 len = _string->getLength();
|
|
U32 len = _string->getLength();
|
|
- StringData* sub = new ( len + 1 ) StringData( NULL );
|
|
|
|
-
|
|
|
|
|
|
+ // StringData* sub = new ( len + 1 ) StringData( NULL );
|
|
|
|
+ StringData* sub = StringData::Create(NULL, len + 1);
|
|
|
|
+
|
|
copy( sub->utf8(), _string->utf8(), len );
|
|
copy( sub->utf8(), _string->utf8(), len );
|
|
sub->utf8()[len] = c;
|
|
sub->utf8()[len] = c;
|
|
sub->utf8()[len+1] = 0;
|
|
sub->utf8()[len+1] = 0;
|
|
@@ -748,7 +780,8 @@ String& String::operator=(const StringChar *str)
|
|
if (str && *str)
|
|
if (str && *str)
|
|
{
|
|
{
|
|
U32 len = dStrlen(str);
|
|
U32 len = dStrlen(str);
|
|
- _string = new ( len ) StringData( str );
|
|
|
|
|
|
+ // _string = new ( len ) StringData( str );
|
|
|
|
+ _string = StringData::Create(str, len);
|
|
}
|
|
}
|
|
else
|
|
else
|
|
_string = StringData::Empty();
|
|
_string = StringData::Empty();
|
|
@@ -782,7 +815,8 @@ String& String::operator+=(const StringChar *src)
|
|
sub = StringData::Empty();
|
|
sub = StringData::Empty();
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- sub = new ( newlen ) StringData( NULL );
|
|
|
|
|
|
+ // sub = new ( newlen ) StringData( NULL );
|
|
|
|
+ sub = StringData::Create(NULL, newlen);
|
|
|
|
|
|
copy(sub->utf8(),_string->utf8(),lena);
|
|
copy(sub->utf8(),_string->utf8(),lena);
|
|
copy(sub->utf8() + lena,src,lenb + 1);
|
|
copy(sub->utf8() + lena,src,lenb + 1);
|
|
@@ -809,7 +843,8 @@ String& String::operator+=(const String &src)
|
|
sub = StringData::Empty();
|
|
sub = StringData::Empty();
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- sub = new ( newlen ) StringData( NULL );
|
|
|
|
|
|
+ //sub = new ( newlen ) StringData( NULL );
|
|
|
|
+ sub = StringData::Create(NULL, newlen);
|
|
|
|
|
|
copy(sub->utf8(),_string->utf8(),lena);
|
|
copy(sub->utf8(),_string->utf8(),lena);
|
|
copy(sub->utf8() + lena,src._string->utf8(),lenb + 1);
|
|
copy(sub->utf8() + lena,src._string->utf8(),lenb + 1);
|
|
@@ -835,7 +870,8 @@ String operator+(const String &a, const String &b)
|
|
U32 lena = a.length();
|
|
U32 lena = a.length();
|
|
U32 lenb = b.length();
|
|
U32 lenb = b.length();
|
|
|
|
|
|
- String::StringData *sub = new ( lena + lenb ) String::StringData( NULL );
|
|
|
|
|
|
+ //String::StringData *sub = new ( lena + lenb ) String::StringData( NULL );
|
|
|
|
+ String::StringData* sub = String::StringData::Create(NULL, lena + lenb);
|
|
|
|
|
|
String::copy(sub->utf8(),a._string->utf8(),lena);
|
|
String::copy(sub->utf8(),a._string->utf8(),lena);
|
|
String::copy(sub->utf8() + lena,b._string->utf8(),lenb + 1);
|
|
String::copy(sub->utf8() + lena,b._string->utf8(),lenb + 1);
|
|
@@ -848,7 +884,8 @@ String operator+(const String &a, StringChar c)
|
|
//PROFILE_SCOPE( String_String_plus_Char );
|
|
//PROFILE_SCOPE( String_String_plus_Char );
|
|
|
|
|
|
U32 lena = a.length();
|
|
U32 lena = a.length();
|
|
- String::StringData *sub = new ( lena + 1 ) String::StringData( NULL );
|
|
|
|
|
|
+ // String::StringData *sub = new ( lena + 1 ) String::StringData( NULL );
|
|
|
|
+ String::StringData* sub = String::StringData::Create(NULL, lena + 1);
|
|
|
|
|
|
String::copy(sub->utf8(),a._string->utf8(),lena);
|
|
String::copy(sub->utf8(),a._string->utf8(),lena);
|
|
|
|
|
|
@@ -863,7 +900,8 @@ String operator+(StringChar c, const String &a)
|
|
//PROFILE_SCOPE( String_Char_plus_String );
|
|
//PROFILE_SCOPE( String_Char_plus_String );
|
|
|
|
|
|
U32 lena = a.length();
|
|
U32 lena = a.length();
|
|
- String::StringData *sub = new ( lena + 1 ) String::StringData( NULL );
|
|
|
|
|
|
+ // String::StringData *sub = new ( lena + 1 ) String::StringData( NULL );
|
|
|
|
+ String::StringData* sub = String::StringData::Create(NULL, lena + 1);
|
|
|
|
|
|
String::copy(sub->utf8() + 1,a._string->utf8(),lena + 1);
|
|
String::copy(sub->utf8() + 1,a._string->utf8(),lena + 1);
|
|
sub->utf8()[0] = c;
|
|
sub->utf8()[0] = c;
|
|
@@ -886,7 +924,8 @@ String operator+(const String &a, const StringChar *b)
|
|
if( !lenb )
|
|
if( !lenb )
|
|
return a;
|
|
return a;
|
|
|
|
|
|
- String::StringData *sub = new ( lena + lenb ) String::StringData( NULL );
|
|
|
|
|
|
+ // String::StringData *sub = new ( lena + lenb ) String::StringData( NULL );
|
|
|
|
+ String::StringData* sub = String::StringData::Create(NULL, lena + lenb);
|
|
|
|
|
|
String::copy(sub->utf8(),a._string->utf8(),lena);
|
|
String::copy(sub->utf8(),a._string->utf8(),lena);
|
|
String::copy(sub->utf8() + lena,b,lenb + 1);
|
|
String::copy(sub->utf8() + lena,b,lenb + 1);
|
|
@@ -908,7 +947,8 @@ String operator+(const StringChar *a, const String &b)
|
|
|
|
|
|
U32 lenb = b.length();
|
|
U32 lenb = b.length();
|
|
|
|
|
|
- String::StringData* sub = new ( lena + lenb ) String::StringData( NULL );
|
|
|
|
|
|
+ //String::StringData* sub = new ( lena + lenb ) String::StringData( NULL );
|
|
|
|
+ String::StringData* sub = String::StringData::Create(NULL, lena + lenb);
|
|
|
|
|
|
String::copy(sub->utf8(),a,lena);
|
|
String::copy(sub->utf8(),a,lena);
|
|
String::copy(sub->utf8() + lena,b._string->utf8(),lenb + 1);
|
|
String::copy(sub->utf8() + lena,b._string->utf8(),lenb + 1);
|
|
@@ -1117,7 +1157,8 @@ String& String::insert(SizeType pos, const StringChar *str, SizeType len)
|
|
sub = StringData::Empty();
|
|
sub = StringData::Empty();
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- sub = new ( newlen ) StringData( NULL );
|
|
|
|
|
|
+ // sub = new ( newlen ) StringData( NULL );
|
|
|
|
+ sub = StringData::Create(NULL, newlen);
|
|
|
|
|
|
String::copy(sub->utf8(),_string->utf8(),pos);
|
|
String::copy(sub->utf8(),_string->utf8(),pos);
|
|
String::copy(sub->utf8() + pos,str,len);
|
|
String::copy(sub->utf8() + pos,str,len);
|
|
@@ -1146,7 +1187,8 @@ String& String::erase(SizeType pos, SizeType len)
|
|
sub = StringData::Empty();
|
|
sub = StringData::Empty();
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- sub = new ( newlen ) StringData( NULL );
|
|
|
|
|
|
+// sub = new ( newlen ) StringData( NULL );
|
|
|
|
+ sub = StringData::Create(NULL, newlen);
|
|
|
|
|
|
if (pos > 0)
|
|
if (pos > 0)
|
|
String::copy(sub->utf8(),_string->utf8(),pos);
|
|
String::copy(sub->utf8(),_string->utf8(),pos);
|
|
@@ -1176,7 +1218,8 @@ String& String::replace(SizeType pos, SizeType len, const StringChar *str)
|
|
sub = StringData::Empty();
|
|
sub = StringData::Empty();
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- sub = new ( newlen ) StringData( NULL );
|
|
|
|
|
|
+ // sub = new ( newlen ) StringData( NULL );
|
|
|
|
+ sub = StringData::Create(NULL, newlen);
|
|
|
|
|
|
String::copy(sub->utf8(),_string->utf8(), pos);
|
|
String::copy(sub->utf8(),_string->utf8(), pos);
|
|
String::copy(sub->utf8() + pos,str,rlen);
|
|
String::copy(sub->utf8() + pos,str,rlen);
|
|
@@ -1207,7 +1250,9 @@ String& String::replace( StringChar c1, StringChar c2 )
|
|
{
|
|
{
|
|
if( !foundReplacement )
|
|
if( !foundReplacement )
|
|
{
|
|
{
|
|
- sub = new ( length() ) StringData( _string->utf8() );
|
|
|
|
|
|
+ //sub = new ( length() ) StringData( _string->utf8() );
|
|
|
|
+ sub = StringData::Create(_string->utf8(), length());
|
|
|
|
+
|
|
c = &sub->utf8()[ c - _string->utf8() ];
|
|
c = &sub->utf8()[ c - _string->utf8() ];
|
|
foundReplacement = true;
|
|
foundReplacement = true;
|
|
}
|
|
}
|
|
@@ -1261,7 +1306,8 @@ String &String::replace(const String &s1, const String &s2)
|
|
sub = StringData::Empty();
|
|
sub = StringData::Empty();
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- sub = new (newSize - 1 ) StringData( NULL );
|
|
|
|
|
|
+ //sub = new (newSize - 1 ) StringData( NULL );
|
|
|
|
+ sub = StringData::Create(NULL, newSize - 1);
|
|
|
|
|
|
// Now assemble the new string from the pieces of the old...
|
|
// Now assemble the new string from the pieces of the old...
|
|
|
|
|
|
@@ -1327,7 +1373,9 @@ String String::substr(SizeType pos, SizeType len) const
|
|
if( !len )
|
|
if( !len )
|
|
sub = StringData::Empty();
|
|
sub = StringData::Empty();
|
|
else
|
|
else
|
|
- sub = new ( len ) StringData( _string->utf8() + pos );
|
|
|
|
|
|
+ sub = StringData::Create(_string->utf8() + pos, len);
|
|
|
|
+
|
|
|
|
+ //sub = new ( len ) StringData( _string->utf8() + pos );
|
|
|
|
|
|
return sub;
|
|
return sub;
|
|
}
|
|
}
|
|
@@ -1356,7 +1404,9 @@ String String::trim() const
|
|
if( !len )
|
|
if( !len )
|
|
sub = StringData::Empty();
|
|
sub = StringData::Empty();
|
|
else
|
|
else
|
|
- sub = new ( len ) StringData( start );
|
|
|
|
|
|
+ sub = StringData::Create(start, len);
|
|
|
|
+
|
|
|
|
+ //sub = new ( len ) StringData( start );
|
|
|
|
|
|
return sub;
|
|
return sub;
|
|
}
|
|
}
|
|
@@ -1573,7 +1623,8 @@ String String::VToString(const char* str, va_list args)
|
|
sub = StringData::Empty();
|
|
sub = StringData::Empty();
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- sub = new ( len ) StringData( NULL );
|
|
|
|
|
|
+ //sub = new ( len ) StringData( NULL );
|
|
|
|
+ sub = StringData::Create(NULL, len);
|
|
|
|
|
|
format.copy( sub->utf8() );
|
|
format.copy( sub->utf8() );
|
|
sub->utf8()[ len ] = 0;
|
|
sub->utf8()[ len ] = 0;
|
|
@@ -1590,7 +1641,8 @@ String String::SpanToString(const char *start, const char *end)
|
|
AssertFatal( end > start, "Invalid arguments to String::SpanToString - end is before start" );
|
|
AssertFatal( end > start, "Invalid arguments to String::SpanToString - end is before start" );
|
|
|
|
|
|
U32 len = U32(end - start);
|
|
U32 len = U32(end - start);
|
|
- StringData* sub = new ( len ) StringData( start );
|
|
|
|
|
|
+ //StringData* sub = new ( len ) StringData( start );
|
|
|
|
+ String::StringData* sub = StringData::Create(start, len);
|
|
|
|
|
|
return sub;
|
|
return sub;
|
|
}
|
|
}
|
|
@@ -1600,7 +1652,9 @@ String String::ToLower(const String &string)
|
|
if ( string.isEmpty() )
|
|
if ( string.isEmpty() )
|
|
return String();
|
|
return String();
|
|
|
|
|
|
- StringData* sub = new ( string.length() ) StringData( string );
|
|
|
|
|
|
+ //StringData* sub = new ( string.length() ) StringData( string );
|
|
|
|
+ String::StringData* sub = StringData::Create(string, string.length());
|
|
|
|
+
|
|
dStrlwr( sub->utf8() );
|
|
dStrlwr( sub->utf8() );
|
|
|
|
|
|
return sub;
|
|
return sub;
|
|
@@ -1611,7 +1665,9 @@ String String::ToUpper(const String &string)
|
|
if ( string.isEmpty() )
|
|
if ( string.isEmpty() )
|
|
return String();
|
|
return String();
|
|
|
|
|
|
- StringData* sub = new ( string.length() ) StringData( string );
|
|
|
|
|
|
+ // StringData* sub = new ( string.length() ) StringData( string );
|
|
|
|
+ String::StringData* sub = StringData::Create(string, string.length());
|
|
|
|
+
|
|
dStrupr( sub->utf8() );
|
|
dStrupr( sub->utf8() );
|
|
|
|
|
|
return sub;
|
|
return sub;
|