CUtlString modifications

* Promote all size types to int64 to accomodate in-memory structure size of the game itself.
* Explicitly call destructors for members. Due to the way we hook the game and utilize the global memory allocation singleton, the destructor of the objects aren't called. CUtlVector does call the destructor of CUtlString. Explicitly defined a destructor that also destructs its underlying memory to avoid any memory leaks.
This commit is contained in:
Kawe Mazidjatari 2023-03-17 00:12:37 +01:00
parent b030344c10
commit 650b89fa25
2 changed files with 88 additions and 70 deletions

View File

@ -4,13 +4,14 @@
// //
//============================================================================= //=============================================================================
#include "core/stdafx.h"
#include "tier1/utlstring.h" #include "tier1/utlstring.h"
#include "tier1/utlvector.h" #include "tier1/utlvector.h"
#include "tier1/strtools.h" #include "tier1/strtools.h"
#include <ctype.h> #include <ctype.h>
// NOTE: This has to be the last file included! // NOTE: This has to be the last file included!
#include "tier0/memdbgon.h" //#include "tier0/memdbgon.h"
static const int64 k_nMillion = 1000000; static const int64 k_nMillion = 1000000;
@ -65,20 +66,20 @@ int V_vscprintf(const char *format, va_list params)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Base class, containing simple memory management // Base class, containing simple memory management
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
CUtlBinaryBlock::CUtlBinaryBlock( int growSize, int initSize ) CUtlBinaryBlock::CUtlBinaryBlock( int64 growSize, int64 initSize )
{ {
MEM_ALLOC_CREDIT(); //MEM_ALLOC_CREDIT();
m_Memory.Init( growSize, initSize ); m_Memory.Init( growSize, initSize );
m_nActualLength = 0; m_nActualLength = 0;
} }
CUtlBinaryBlock::CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Memory( (unsigned char*)pMemory, nSizeInBytes ) CUtlBinaryBlock::CUtlBinaryBlock( void* pMemory, int64 nSizeInBytes, int64 nInitialLength ) : m_Memory( (unsigned char*)pMemory, nSizeInBytes )
{ {
m_nActualLength = nInitialLength; m_nActualLength = nInitialLength;
} }
CUtlBinaryBlock::CUtlBinaryBlock( const void* pMemory, int nSizeInBytes ) : m_Memory( (const unsigned char*)pMemory, nSizeInBytes ) CUtlBinaryBlock::CUtlBinaryBlock( const void* pMemory, int64 nSizeInBytes ) : m_Memory( (const unsigned char*)pMemory, nSizeInBytes )
{ {
m_nActualLength = nSizeInBytes; m_nActualLength = nSizeInBytes;
} }
@ -88,7 +89,7 @@ CUtlBinaryBlock::CUtlBinaryBlock( const CUtlBinaryBlock& src )
Set( src.Get(), src.Length() ); Set( src.Get(), src.Length() );
} }
void CUtlBinaryBlock::Get( void *pValue, int nLen ) const void CUtlBinaryBlock::Get( void *pValue, int64 nLen ) const
{ {
Assert( nLen > 0 ); Assert( nLen > 0 );
if ( m_nActualLength < nLen ) if ( m_nActualLength < nLen )
@ -102,15 +103,15 @@ void CUtlBinaryBlock::Get( void *pValue, int nLen ) const
} }
} }
void CUtlBinaryBlock::SetLength( int nLength ) void CUtlBinaryBlock::SetLength(int64 nLength )
{ {
MEM_ALLOC_CREDIT(); //MEM_ALLOC_CREDIT();
Assert( !m_Memory.IsReadOnly() ); Assert( !m_Memory.IsReadOnly() );
m_nActualLength = nLength; m_nActualLength = nLength;
if ( nLength > m_Memory.NumAllocated() ) if ( nLength > m_Memory.NumAllocated() )
{ {
int nOverFlow = nLength - m_Memory.NumAllocated(); int64 nOverFlow = nLength - m_Memory.NumAllocated();
m_Memory.Grow( nOverFlow ); m_Memory.Grow( nOverFlow );
// If the reallocation failed, clamp length // If the reallocation failed, clamp length
@ -129,7 +130,7 @@ void CUtlBinaryBlock::SetLength( int nLength )
} }
void CUtlBinaryBlock::Set( const void *pValue, int nLen ) void CUtlBinaryBlock::Set( const void *pValue, int64 nLen )
{ {
Assert( !m_Memory.IsReadOnly() ); Assert( !m_Memory.IsReadOnly() );
@ -190,11 +191,11 @@ CUtlString::CUtlString( const CUtlString& string )
} }
// Attaches the string to external memory. Useful for avoiding a copy // Attaches the string to external memory. Useful for avoiding a copy
CUtlString::CUtlString( void* pMemory, int nSizeInBytes, int nInitialLength ) : m_Storage( pMemory, nSizeInBytes, nInitialLength ) CUtlString::CUtlString( void* pMemory, int64 nSizeInBytes, int64 nInitialLength ) : m_Storage( pMemory, nSizeInBytes, nInitialLength )
{ {
} }
CUtlString::CUtlString( const void* pMemory, int nSizeInBytes ) : m_Storage( pMemory, nSizeInBytes ) CUtlString::CUtlString( const void* pMemory, int64 nSizeInBytes ) : m_Storage( pMemory, nSizeInBytes )
{ {
} }
@ -202,7 +203,7 @@ CUtlString::CUtlString( const void* pMemory, int nSizeInBytes ) : m_Storage( pMe
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: Set directly and don't look for a null terminator in pValue. // Purpose: Set directly and don't look for a null terminator in pValue.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CUtlString::SetDirect( const char *pValue, int nChars ) void CUtlString::SetDirect( const char *pValue, int64 nChars )
{ {
if ( nChars > 0 ) if ( nChars > 0 )
{ {
@ -220,19 +221,19 @@ void CUtlString::SetDirect( const char *pValue, int nChars )
void CUtlString::Set( const char *pValue ) void CUtlString::Set( const char *pValue )
{ {
Assert( !m_Storage.IsReadOnly() ); Assert( !m_Storage.IsReadOnly() );
int nLen = pValue ? Q_strlen(pValue) + 1 : 0; int64 nLen = pValue ? Q_strlen(pValue) + 1 : 0;
m_Storage.Set( pValue, nLen ); m_Storage.Set( pValue, nLen );
} }
// Returns strlen // Returns strlen
int CUtlString::Length() const int64 CUtlString::Length() const
{ {
return m_Storage.Length() ? m_Storage.Length() - 1 : 0; return m_Storage.Length() ? m_Storage.Length() - 1 : 0;
} }
// Sets the length (used to serialize into the buffer ) // Sets the length (used to serialize into the buffer )
void CUtlString::SetLength( int nLen ) void CUtlString::SetLength( int64 nLen )
{ {
Assert( !m_Storage.IsReadOnly() ); Assert( !m_Storage.IsReadOnly() );
@ -278,7 +279,7 @@ void CUtlString::Purge()
void CUtlString::ToUpper() void CUtlString::ToUpper()
{ {
for (int nLength = Length() - 1; nLength >= 0; nLength--) for ( int64 nLength = Length() - 1; nLength >= 0; nLength--)
{ {
m_Storage[nLength] = toupper(m_Storage[nLength]); m_Storage[nLength] = toupper(m_Storage[nLength]);
} }
@ -286,7 +287,7 @@ void CUtlString::ToUpper()
void CUtlString::ToLower() void CUtlString::ToLower()
{ {
for( int nLength = Length() - 1; nLength >= 0; nLength-- ) for( int64 nLength = Length() - 1; nLength >= 0; nLength-- )
{ {
m_Storage[ nLength ] = tolower( m_Storage[ nLength ] ); m_Storage[ nLength ] = tolower( m_Storage[ nLength ] );
} }
@ -362,7 +363,7 @@ CUtlString &CUtlString::operator+=( char c )
return *this; return *this;
} }
CUtlString &CUtlString::operator+=( int rhs ) CUtlString &CUtlString::operator+=( int64 rhs )
{ {
Assert( !m_Storage.IsReadOnly() ); Assert( !m_Storage.IsReadOnly() );
Assert( sizeof( rhs ) == 4 ); Assert( sizeof( rhs ) == 4 );
@ -653,9 +654,9 @@ void CUtlString::Append( const char *pchAddition )
(*this) += pchAddition; (*this) += pchAddition;
} }
void CUtlString::Append(const char *pchAddition, int nMaxChars) void CUtlString::Append(const char *pchAddition, int64 nMaxChars)
{ {
const int nLen = V_strlen(pchAddition); const int64 nLen = V_strlen(pchAddition);
if (nMaxChars < 0 || nLen <= nMaxChars) if (nMaxChars < 0 || nLen <= nMaxChars)
{ {
Append(pchAddition); Append(pchAddition);
@ -799,7 +800,7 @@ char *CUtlStringBuilder::InternalPrepareBuffer(size_t nChars, bool bCopyOld, siz
if (bWasHeap && bCopyOld) if (bWasHeap && bCopyOld)
{ {
// maybe we'll get lucky and get the same buffer back. // maybe we'll get lucky and get the same buffer back.
pszString = (char*)realloc(pszOld, nNewSize + 1); pszString = MemAllocSingleton()->Realloc(pszOld, nNewSize + 1);
if (!pszString) if (!pszString)
{ {
SetError(); SetError();
@ -813,9 +814,9 @@ char *CUtlStringBuilder::InternalPrepareBuffer(size_t nChars, bool bCopyOld, siz
// if we aren't doing a copy, don't use realloc since it will // if we aren't doing a copy, don't use realloc since it will
// copy the data if it needs to make a new allocation. // copy the data if it needs to make a new allocation.
if (bWasHeap) if (bWasHeap)
free(pszOld); MemAllocSingleton()->Free(pszOld);
pszString = (char*)malloc(nNewSize + 1); pszString = MemAllocSingleton()->Alloc<char>(nNewSize + 1);
if (!pszString) if (!pszString)
{ {
SetError(); SetError();
@ -851,7 +852,7 @@ char *CUtlStringBuilder::InternalPrepareBuffer(size_t nChars, bool bCopyOld, siz
if (bCopyOld) if (bCopyOld)
memcpy(pszString, pszOldString, nChars); // null will be added at end of func. memcpy(pszString, pszOldString, nChars); // null will be added at end of func.
free(pszOldString); MemAllocSingleton()->Free(pszOldString);
} }
} }
@ -866,7 +867,7 @@ char *CUtlStringBuilder::InternalPrepareBuffer(size_t nChars, bool bCopyOld, siz
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
size_t CUtlStringBuilder::Replace(const char *pstrTarget, const char *pstrReplacement) size_t CUtlStringBuilder::Replace(const char *pstrTarget, const char *pstrReplacement)
{ {
return ReplaceInternal(pstrTarget, pstrReplacement, (const char *(*)(const char *, const char *))_V_strstr); return ReplaceInternal(pstrTarget, pstrReplacement, (const char *(*)(const char *, const char *))V_strstr);
} }
@ -876,7 +877,7 @@ size_t CUtlStringBuilder::Replace(const char *pstrTarget, const char *pstrReplac
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
size_t CUtlStringBuilder::ReplaceFastCaseless(const char *pstrTarget, const char *pstrReplacement) size_t CUtlStringBuilder::ReplaceFastCaseless(const char *pstrTarget, const char *pstrReplacement)
{ {
return ReplaceInternal(pstrTarget, pstrReplacement, V_stristr_fast); return ReplaceInternal(pstrTarget, pstrReplacement, V_stristr);
} }
@ -933,7 +934,7 @@ size_t CUtlStringBuilder::ReplaceInternal(const char *pstrTarget, const char *ps
char *pstrNew; char *pstrNew;
if (nNewLength > Capacity()) if (nNewLength > Capacity())
{ {
pstrNew = (char*)malloc(nNewLength + 1); pstrNew = MemAllocSingleton()->Alloc<char>(nNewLength + 1);
if (!pstrNew) if (!pstrNew)
{ {
SetError(); SetError();
@ -1150,8 +1151,8 @@ void CUtlStringBuilder::Data::SetError(bool bEnableAssert)
// This is not meant to be used as a status bit. Setting the error state should // This is not meant to be used as a status bit. Setting the error state should
// mean something very unexpected happened that you would want a call stack for. // mean something very unexpected happened that you would want a call stack for.
// That is why this asserts unconditionally when the state is being flipped. // That is why this asserts unconditionally when the state is being flipped.
if (bEnableAssert) //if (bEnableAssert)
AssertMsg(false, "Error State on string being set."); // AssertMsg(false, "Error State on string being set.");
MoveToHeap(); MoveToHeap();
@ -1186,7 +1187,7 @@ bool CUtlStringBuilder::Data::MoveToHeap()
{ {
// try to recover the string at the point of failure, to help with debugging // try to recover the string at the point of failure, to help with debugging
size_t nLen = Length(); size_t nLen = Length();
char *pszHeapString = (char*)malloc(nLen + 1); char *pszHeapString = MemAllocSingleton()->Alloc<char>(nLen + 1);
if (pszHeapString) if (pszHeapString)
{ {
// get the string copy before corrupting the stack union // get the string copy before corrupting the stack union

View File

@ -10,7 +10,6 @@
#pragma once #pragma once
#endif #endif
#include "tier1/utlmemory.h" #include "tier1/utlmemory.h"
#include "tier1/strtools.h" #include "tier1/strtools.h"
#include "limits.h" #include "limits.h"
@ -25,7 +24,7 @@
class CUtlBinaryBlock class CUtlBinaryBlock
{ {
public: public:
CUtlBinaryBlock( int growSize = 0, int initSize = 0 ); CUtlBinaryBlock( int64 growSize = 0, int64 initSize = 0 );
~CUtlBinaryBlock() ~CUtlBinaryBlock()
{ {
#ifdef _DEBUG #ifdef _DEBUG
@ -33,11 +32,19 @@ public:
#else #else
m_nActualLength = 0; m_nActualLength = 0;
#endif #endif
// Has to be explicitly called due to the
// current design of our SDK. Unlike other
// Source Engine games, we couldn't import
// the memalloc singleton; we obtain it post
// init (too late for binding it against the
// new/delete operators..).
m_Memory.~CUtlMemory();
} }
// NOTE: nInitialLength indicates how much of the buffer starts full // NOTE: nInitialLength indicates how much of the buffer starts full
CUtlBinaryBlock( void* pMemory, int nSizeInBytes, int nInitialLength ); CUtlBinaryBlock( void* pMemory, int64 nSizeInBytes, int64 nInitialLength );
CUtlBinaryBlock( const void* pMemory, int nSizeInBytes ); CUtlBinaryBlock( const void* pMemory, int64 nSizeInBytes );
CUtlBinaryBlock( const CUtlBinaryBlock& src ); CUtlBinaryBlock( const CUtlBinaryBlock& src );
CUtlBinaryBlock &operator=( const CUtlBinaryBlock &src ); CUtlBinaryBlock &operator=( const CUtlBinaryBlock &src );
@ -47,16 +54,16 @@ public:
CUtlBinaryBlock &operator=( CUtlBinaryBlock&& src ); CUtlBinaryBlock &operator=( CUtlBinaryBlock&& src );
#endif #endif
void Get( void *pValue, int nMaxLen ) const; void Get( void *pValue, int64 nMaxLen ) const;
void Set( const void *pValue, int nLen ); void Set( const void *pValue, int64 nLen );
const void *Get( ) const; const void *Get( ) const;
void *Get( ); void *Get( );
unsigned char& operator[]( int i ); unsigned char& operator[]( int64 i );
const unsigned char& operator[]( int i ) const; const unsigned char& operator[]( int64 i ) const;
int Length() const; int64 Length() const;
void SetLength( int nLength ); // Undefined memory will result void SetLength( int64 nLength ); // Undefined memory will result
bool IsEmpty() const; bool IsEmpty() const;
void Clear(); void Clear();
void Purge(); void Purge();
@ -69,7 +76,7 @@ public:
private: private:
CUtlMemory<unsigned char> m_Memory; CUtlMemory<unsigned char> m_Memory;
int m_nActualLength; int64 m_nActualLength;
}; };
@ -87,7 +94,7 @@ inline CUtlBinaryBlock::CUtlBinaryBlock( CUtlBinaryBlock&& src )
inline CUtlBinaryBlock& CUtlBinaryBlock::operator= ( CUtlBinaryBlock&& src ) inline CUtlBinaryBlock& CUtlBinaryBlock::operator= ( CUtlBinaryBlock&& src )
{ {
int length = src.m_nActualLength; int64 length = src.m_nActualLength;
src.m_nActualLength = 0; src.m_nActualLength = 0;
m_Memory = Move( src.m_Memory ); m_Memory = Move( src.m_Memory );
@ -107,17 +114,17 @@ inline void *CUtlBinaryBlock::Get( )
return m_Memory.Base(); return m_Memory.Base();
} }
inline int CUtlBinaryBlock::Length() const inline int64 CUtlBinaryBlock::Length() const
{ {
return m_nActualLength; return m_nActualLength;
} }
inline unsigned char& CUtlBinaryBlock::operator[]( int i ) inline unsigned char& CUtlBinaryBlock::operator[]( int64 i )
{ {
return m_Memory[i]; return m_Memory[i];
} }
inline const unsigned char& CUtlBinaryBlock::operator[]( int i ) const inline const unsigned char& CUtlBinaryBlock::operator[]( int64 i ) const
{ {
return m_Memory[i]; return m_Memory[i];
} }
@ -155,8 +162,8 @@ public:
CUtlString( const char *pString ); // initialize from c-style string CUtlString( const char *pString ); // initialize from c-style string
// Attaches the string to external memory. Useful for avoiding a copy // Attaches the string to external memory. Useful for avoiding a copy
CUtlString( void* pMemory, int nSizeInBytes, int nInitialLength ); CUtlString( void* pMemory, int64 nSizeInBytes, int64 nInitialLength );
CUtlString( const void* pMemory, int nSizeInBytes ); CUtlString( const void* pMemory, int64 nSizeInBytes );
// Copy/move constructor/assignment // Copy/move constructor/assignment
// Moves are extremely efficient as the underlying memory is not copied, just the pointers. // Moves are extremely efficient as the underlying memory is not copied, just the pointers.
@ -167,6 +174,16 @@ public:
CUtlString( CUtlString&& moveFrom ); // = default; CUtlString( CUtlString&& moveFrom ); // = default;
CUtlString &operator=( CUtlString&& moveFrom ); // = default; CUtlString &operator=( CUtlString&& moveFrom ); // = default;
#endif #endif
~CUtlString()
{
// Has to be explicitly called due to the
// current design of our SDK. Unlike other
// Source Engine games, we couldn't import
// the memalloc singleton; we obtain it post
// init (too late for binding it against the
// new/delete operators..).
m_Storage.~CUtlBinaryBlock();
}
// Also can assign from a regular C-style string // Also can assign from a regular C-style string
CUtlString &operator=( const char *src ); CUtlString &operator=( const char *src );
@ -186,7 +203,7 @@ public:
const char *String() const { return Get(); } const char *String() const { return Get(); }
// Returns strlen // Returns strlen
int Length() const; int64 Length() const;
bool IsEmpty() const; bool IsEmpty() const;
// GS - Added for chromehtml // GS - Added for chromehtml
@ -198,7 +215,7 @@ public:
// Sets the length (used to serialize into the buffer ) // Sets the length (used to serialize into the buffer )
// Note: If nLen != 0, then this adds an extra byte for a null-terminator. // Note: If nLen != 0, then this adds an extra byte for a null-terminator.
void Set( const char *pValue ); void Set( const char *pValue );
void SetLength( int nLen ); void SetLength( int64 nLen );
void Purge(); void Purge();
void Swap(CUtlString &src); void Swap(CUtlString &src);
@ -207,7 +224,7 @@ public:
void ToUpper(); void ToUpper();
void ToLower( ); void ToLower( );
void Append( const char *pchAddition ); void Append( const char *pchAddition );
void Append(const char *pchAddition, int nMaxChars); void Append(const char *pchAddition, int64 nMaxChars);
void Append(char chAddition) { void Append(char chAddition) {
char temp[2] = { chAddition, 0 }; char temp[2] = { chAddition, 0 };
Append(temp); Append(temp);
@ -216,8 +233,8 @@ public:
// Strips the trailing slash // Strips the trailing slash
void StripTrailingSlash(); void StripTrailingSlash();
char operator[] ( int idx ) const; char operator[] ( int64 idx ) const;
char& operator[] ( int idx ); char& operator[] ( int64 idx );
// Test for equality // Test for equality
bool operator==( const CUtlString &src ) const; bool operator==( const CUtlString &src ) const;
@ -233,11 +250,11 @@ public:
CUtlString &operator+=( const CUtlString &rhs ); CUtlString &operator+=( const CUtlString &rhs );
CUtlString &operator+=( const char *rhs ); CUtlString &operator+=( const char *rhs );
CUtlString &operator+=( char c ); CUtlString &operator+=( char c );
CUtlString &operator+=( int rhs ); CUtlString &operator+=( int64 rhs );
CUtlString &operator+=( double rhs ); CUtlString &operator+=( double rhs );
CUtlString operator+( const char *pOther )const; CUtlString operator+( const char *pOther )const;
CUtlString operator+( int rhs )const; //CUtlString operator+( int64 rhs )const;
bool MatchesPattern( const CUtlString &Pattern, int nFlags = 0 ); // case SENSITIVE, use * for wildcard in pattern string bool MatchesPattern( const CUtlString &Pattern, int nFlags = 0 ); // case SENSITIVE, use * for wildcard in pattern string
@ -250,7 +267,7 @@ public:
int FormatV( const char *pFormat, va_list marker ); int FormatV( const char *pFormat, va_list marker );
#endif #endif
void SetDirect( const char *pValue, int nChars ); void SetDirect( const char *pValue, int64 nChars );
// Defining AltArgumentType_t hints that associative container classes should // Defining AltArgumentType_t hints that associative container classes should
// also implement Find/Insert/Remove functions that take const char* params. // also implement Find/Insert/Remove functions that take const char* params.
@ -273,7 +290,7 @@ public:
/// Replace one string with the other (single pass). Passing a NULL to pchTo is same as calling Remove /// Replace one string with the other (single pass). Passing a NULL to pchTo is same as calling Remove
CUtlString Replace( char const *pchFrom, const char *pchTo, bool bCaseSensitive = false ) const; CUtlString Replace( char const *pchFrom, const char *pchTo, bool bCaseSensitive = false ) const;
/// helper func for caseless replace /// helper func for caseless replace
CUtlString ReplaceCaseless( char const *pchFrom, const char *pchTo ) const { return Replace( pchFrom, pchTo, false ); } CUtlString ReplaceCaseless( char const *pchFrom, const char *pchTo ) const { return Replace( pchFrom, pchTo, false ); }
void RemoveDotSlashes(char separator = CORRECT_PATH_SEPARATOR); void RemoveDotSlashes(char separator = CORRECT_PATH_SEPARATOR);
@ -318,14 +335,14 @@ public:
static CUtlString PathJoin( const char *pStr1, const char *pStr2 ); static CUtlString PathJoin( const char *pStr1, const char *pStr2 );
// These can be used for utlvector sorts. // These can be used for utlvector sorts.
static int __cdecl SortCaseInsensitive( const CUtlString *pString1, const CUtlString *pString2 ); static int64 __cdecl SortCaseInsensitive( const CUtlString *pString1, const CUtlString *pString2 );
static int __cdecl SortCaseSensitive( const CUtlString *pString1, const CUtlString *pString2 ); static int64 __cdecl SortCaseSensitive( const CUtlString *pString1, const CUtlString *pString2 );
// From Src2 // From Src2
void FixSlashes( char cSeparator = CORRECT_PATH_SEPARATOR ) void FixSlashes( char cSeparator = CORRECT_PATH_SEPARATOR )
{ {
for ( int nLength = Length() - 1; nLength >= 0; nLength-- ) for ( int64 nLength = Length() - 1; nLength >= 0; nLength-- )
{ {
char *pname = (char*)&m_Storage[ nLength ]; char *pname = (char*)&m_Storage[ nLength ];
if ( *pname == INCORRECT_PATH_SEPARATOR || *pname == CORRECT_PATH_SEPARATOR ) if ( *pname == INCORRECT_PATH_SEPARATOR || *pname == CORRECT_PATH_SEPARATOR )
@ -380,22 +397,22 @@ inline bool CUtlString::IsEmpty() const
return Length() == 0; return Length() == 0;
} }
inline int __cdecl CUtlString::SortCaseInsensitive( const CUtlString *pString1, const CUtlString *pString2 ) inline int64 __cdecl CUtlString::SortCaseInsensitive( const CUtlString *pString1, const CUtlString *pString2 )
{ {
return V_stricmp( pString1->String(), pString2->String() ); return V_stricmp( pString1->String(), pString2->String() );
} }
inline int __cdecl CUtlString::SortCaseSensitive( const CUtlString *pString1, const CUtlString *pString2 ) inline int64 __cdecl CUtlString::SortCaseSensitive( const CUtlString *pString1, const CUtlString *pString2 )
{ {
return V_strcmp( pString1->String(), pString2->String() ); return V_strcmp( pString1->String(), pString2->String() );
} }
inline char CUtlString::operator [] ( int index ) const inline char CUtlString::operator [] ( int64 index ) const
{ {
return Get()[index]; return Get()[index];
} }
inline char& CUtlString::operator[] ( int index ) inline char& CUtlString::operator[] ( int64 index )
{ {
return Access()[index]; return Access()[index];
} }
@ -425,7 +442,7 @@ template < >
class StringFuncs<char> class StringFuncs<char>
{ {
public: public:
static char *Duplicate( const char *pValue ) { return strdup( pValue ); } static char *Duplicate( const char *pValue ) { return _strdup( pValue ); }
static void Copy( char *out_pOut, const char *pIn, int iLength ) { strncpy( out_pOut, pIn, iLength ); } static void Copy( char *out_pOut, const char *pIn, int iLength ) { strncpy( out_pOut, pIn, iLength ); }
static int Compare( const char *pLhs, const char *pRhs ) { return strcmp( pLhs, pRhs ); } static int Compare( const char *pLhs, const char *pRhs ) { return strcmp( pLhs, pRhs ); }
static int Length( const char *pValue ) { return (int)strlen( pValue ); } static int Length( const char *pValue ) { return (int)strlen( pValue ); }
@ -437,7 +454,7 @@ template < >
class StringFuncs<wchar_t> class StringFuncs<wchar_t>
{ {
public: public:
static wchar_t *Duplicate( const wchar_t *pValue ) { return wcsdup( pValue ); } static wchar_t *Duplicate( const wchar_t *pValue ) { return _wcsdup( pValue ); }
static void Copy( wchar_t *out_pOut, const wchar_t *pIn, int iLength ) { wcsncpy( out_pOut, pIn, iLength ); } static void Copy( wchar_t *out_pOut, const wchar_t *pIn, int iLength ) { wcsncpy( out_pOut, pIn, iLength ); }
static int Compare( const wchar_t *pLhs, const wchar_t *pRhs ) { return wcscmp( pLhs, pRhs ); } static int Compare( const wchar_t *pLhs, const wchar_t *pRhs ) { return wcscmp( pLhs, pRhs ); }
static int Length( const wchar_t *pValue ) { return (int) wcslen( pValue ); } static int Length( const wchar_t *pValue ) { return (int) wcslen( pValue ); }
@ -608,7 +625,7 @@ public:
void Append(const CUtlStringBuilder &str) { Append(str.String(), str.Length()); } void Append(const CUtlStringBuilder &str) { Append(str.String(), str.Length()); }
//void Append( IFillStringFunctor& func ); //void Append( IFillStringFunctor& func );
void AppendChar(char ch) { Append(&ch, 1); } void AppendChar(char ch) { Append(&ch, 1); }
void AppendRepeat(char ch, int cCount); void AppendRepeat(char ch, int64 cCount);
// sets the string // sets the string
void SetValue(const char *pchString); void SetValue(const char *pchString);
@ -808,7 +825,7 @@ private:
void FreeHeap() void FreeHeap()
{ {
if (IsHeap() && Heap.m_pchString) if (IsHeap() && Heap.m_pchString)
MemAlloc_Free(Heap.m_pchString); MemAllocSingleton()->Free(Heap.m_pchString);
} }
// Back to a clean state, but retain the error state. // Back to a clean state, but retain the error state.
@ -1188,7 +1205,7 @@ inline void CUtlStringBuilder::SetPtr(char *pchString, size_t nLength)
if (!pchString || !nLength) if (!pchString || !nLength)
{ {
if (pchString) if (pchString)
MemAlloc_Free(pchString); // we don't hang onto empty strings. MemAllocSingleton()->Free(pchString); // we don't hang onto empty strings.
return; return;
} }
@ -1358,7 +1375,7 @@ inline void CUtlStringBuilder::Append(const char *pchAddition, size_t cbLen)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: append a repeated series of a single character // Purpose: append a repeated series of a single character
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
inline void CUtlStringBuilder::AppendRepeat(char ch, int cCount) inline void CUtlStringBuilder::AppendRepeat(char ch, int64 cCount)
{ {
size_t cbOld = Length(); size_t cbOld = Length();
char *pstrNew = PrepareBuffer(cbOld + cCount, true); char *pstrNew = PrepareBuffer(cbOld + cCount, true);