2012-02-01 04:12:54 -05:00
// StringUtils.cpp
// Implements the various string helper functions:
# include "Globals.h"
AString & AppendVPrintf ( AString & str , const char * format , va_list args )
{
ASSERT ( format ! = NULL ) ;
char buffer [ 2048 ] ;
size_t len ;
2012-02-01 04:33:37 -05:00
# ifdef _MSC_VER
// MS CRT provides secure printf that doesn't behave like in the C99 standard
2012-02-01 04:12:54 -05:00
if ( ( len = _vsnprintf_s ( buffer , ARRAYCOUNT ( buffer ) , _TRUNCATE , format , args ) ) ! = - 1 )
2012-02-01 04:33:37 -05:00
# else // _MSC_VER
if ( ( len = vsnprintf ( buffer , ARRAYCOUNT ( buffer ) , format , args ) ) < ARRAYCOUNT ( buffer ) )
# endif // else _MSC_VER
2012-02-01 04:12:54 -05:00
{
2012-02-01 04:33:37 -05:00
// The result did fit into the static buffer
2012-02-01 04:12:54 -05:00
str . append ( buffer , len ) ;
return str ;
}
2012-02-01 04:33:37 -05:00
// The result did not fit into the static buffer
# ifdef _MSC_VER
// for MS CRT, we need to calculate the result length
2012-02-01 04:12:54 -05:00
len = _vscprintf ( format , args ) ;
if ( len = = - 1 )
{
return str ;
}
2012-02-01 04:33:37 -05:00
# endif // _MSC_VER
// Allocate a buffer and printf into it:
2012-05-25 03:18:52 -04:00
str . resize ( len + 1 ) ;
// HACK: we're accessing AString's internal buffer in a way that is NOT guaranteed to always work. But it works on all STL implementations tested.
// I can't think of any other way that is safe, doesn't allocate twice as much space as needed and doesn't use C++11 features like the move constructor
2012-02-01 04:33:37 -05:00
# ifdef _MSC_VER
2012-05-25 03:18:52 -04:00
vsprintf_s ( ( char * ) str . data ( ) , len + 1 , format , args ) ;
2012-02-01 04:33:37 -05:00
# else // _MSC_VER
2012-05-25 03:18:52 -04:00
vsnprintf ( ( char * ) str . data ( ) , len + 1 , format , args ) ;
2012-02-01 04:33:37 -05:00
# endif // else _MSC_VER
2012-05-25 03:18:52 -04:00
str . resize ( len ) ;
2012-02-01 04:12:54 -05:00
return str ;
}
AString & Printf ( AString & str , const char * format , . . . )
{
str . clear ( ) ;
va_list args ;
va_start ( args , format ) ;
std : : string & retval = AppendVPrintf ( str , format , args ) ;
va_end ( args ) ;
return retval ;
}
AString & AppendPrintf ( AString & str , const char * format , . . . )
{
va_list args ;
va_start ( args , format ) ;
std : : string & retval = AppendVPrintf ( str , format , args ) ;
va_end ( args ) ;
return retval ;
}
AStringVector StringSplit ( const AString & str , const AString & delim )
{
AStringVector results ;
size_t cutAt = 0 ;
size_t Prev = 0 ;
while ( ( cutAt = str . find_first_of ( delim , Prev ) ) ! = str . npos )
{
if ( cutAt > 0 )
{
2012-02-01 04:33:37 -05:00
results . push_back ( str . substr ( Prev , cutAt - Prev ) ) ;
2012-02-01 04:12:54 -05:00
}
Prev = cutAt + delim . length ( ) ;
}
if ( Prev < str . length ( ) )
{
results . push_back ( str . substr ( Prev ) ) ;
}
return results ;
}
AString & StrToUpper ( AString & s )
{
AString : : iterator i = s . begin ( ) ;
AString : : iterator end = s . end ( ) ;
while ( i ! = end )
{
* i = ( char ) toupper ( * i ) ;
+ + i ;
}
return s ;
}
int NoCaseCompare ( const AString & s1 , const AString & s2 )
{
# ifdef _MSC_VER
// MSVC has stricmp that compares case-insensitive:
2012-02-01 04:33:37 -05:00
return _stricmp ( s1 . c_str ( ) , s2 . c_str ( ) ) ;
2012-02-01 04:12:54 -05:00
# else
// Do it the hard way:
AString s1Copy ( s1 ) ;
AString s2Copy ( s2 ) ;
return StrToUpper ( s1Copy ) . compare ( StrToUpper ( s2Copy ) ) ;
# endif // else _MSC_VER
}
2012-02-01 17:38:03 -05:00
void ReplaceString ( AString & iHayStack , const AString & iNeedle , const AString & iReplaceWith )
{
size_t pos1 = iHayStack . find ( iNeedle ) ;
while ( pos1 ! = AString : : npos )
{
iHayStack . replace ( pos1 , iNeedle . size ( ) , iReplaceWith ) ;
pos1 = iHayStack . find ( iNeedle , pos1 ) ;
}
}
2012-03-25 10:24:51 -04:00
AStringList GetDirectoryContents ( const char * a_Directory )
{
AStringList AllFiles ;
# ifdef _WIN32
AString FileFilter = AString ( a_Directory ) + " *.* " ;
HANDLE hFind ;
WIN32_FIND_DATA FindFileData ;
if ( ( hFind = FindFirstFile ( FileFilter . c_str ( ) , & FindFileData ) ) ! = INVALID_HANDLE_VALUE )
{
do
{
AllFiles . push_back ( FindFileData . cFileName ) ;
} while ( FindNextFile ( hFind , & FindFileData ) ) ;
FindClose ( hFind ) ;
}
# else // _WIN32
DIR * dp ;
struct dirent * dirp ;
2012-04-04 06:50:43 -04:00
if ( * a_Directory = = 0 )
{
a_Directory = " . " ;
}
2012-03-25 10:24:51 -04:00
if ( ( dp = opendir ( a_Directory ) ) = = NULL )
{
2012-04-04 06:50:43 -04:00
LOGERROR ( " Error (%i) opening directory \" %s \" \n " , errno , a_Directory ) ;
2012-03-25 10:24:51 -04:00
}
else
{
while ( ( dirp = readdir ( dp ) ) ! = NULL )
{
AllFiles . push_back ( dirp - > d_name ) ;
}
closedir ( dp ) ;
}
# endif // else _WIN32
return AllFiles ;
}