2012-02-01 09:12:54 +00: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 09:33:37 +00:00
#ifdef _MSC_VER
// MS CRT provides secure printf that doesn't behave like in the C99 standard
2012-02-01 09:12:54 +00:00
if (( len = _vsnprintf_s ( buffer , ARRAYCOUNT ( buffer ), _TRUNCATE , format , args )) != - 1 )
2012-02-01 09:33:37 +00:00
#else // _MSC_VER
if (( len = vsnprintf ( buffer , ARRAYCOUNT ( buffer ), format , args )) < ARRAYCOUNT ( buffer ))
#endif // else _MSC_VER
2012-02-01 09:12:54 +00:00
{
2012-02-01 09:33:37 +00:00
// The result did fit into the static buffer
2012-02-01 09:12:54 +00:00
str . append ( buffer , len );
return str ;
}
2012-02-01 09:33:37 +00: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 09:12:54 +00:00
len = _vscprintf ( format , args );
if ( len == - 1 )
{
return str ;
}
2012-02-01 09:33:37 +00:00
#endif // _MSC_VER
// Allocate a buffer and printf into it:
2012-05-25 07:18:52 +00: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 09:33:37 +00:00
#ifdef _MSC_VER
2012-05-25 07:18:52 +00:00
vsprintf_s (( char * ) str . data (), len + 1 , format , args );
2012-02-01 09:33:37 +00:00
#else // _MSC_VER
2012-05-25 07:18:52 +00:00
vsnprintf (( char * ) str . data (), len + 1 , format , args );
2012-02-01 09:33:37 +00:00
#endif // else _MSC_VER
2012-05-25 07:18:52 +00:00
str . resize ( len );
2012-02-01 09:12:54 +00: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 )
{
2012-06-04 12:08:20 +00:00
results . push_back ( str . substr ( Prev , cutAt - Prev ));
2012-02-01 09:12:54 +00:00
Prev = cutAt + delim . length ();
}
if ( Prev < str . length ())
{
results . push_back ( str . substr ( Prev ));
}
return results ;
}
2012-06-04 12:08:20 +00:00
AString TrimString ( const AString & str )
{
size_t len = str . length ();
size_t start = 0 ;
while ( start < len )
{
if ( str [ start ] > 32 )
{
break ;
}
++ start ;
}
if ( start == len )
{
return "" ;
}
size_t end = len ;
while ( end >= start )
{
if ( str [ end ] > 32 )
{
break ;
}
-- end ;
}
return str . substr ( start , end - start + 1 );
}
2012-02-01 09:12:54 +00:00
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 09:33:37 +00:00
return _stricmp ( s1 . c_str (), s2 . c_str ());
2012-02-01 09:12:54 +00: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 22:38:03 +00: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 14:24:51 +00: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 10:50:43 +00:00
if ( * a_Directory == 0 )
{
a_Directory = "." ;
}
2012-03-25 14:24:51 +00:00
if (( dp = opendir ( a_Directory )) == NULL )
{
2012-04-04 10:50:43 +00:00
LOGERROR ( "Error (%i) opening directory \" %s \"\n " , errno , a_Directory );
2012-03-25 14:24:51 +00:00
}
else
{
while (( dirp = readdir ( dp )) != NULL )
{
AllFiles . push_back ( dirp -> d_name );
}
closedir ( dp );
}
#endif // else _WIN32
return AllFiles ;
}