2022-05-28 16:12:37 +02:00
# include "core/stdafx.h"
2022-11-07 22:25:20 +01:00
# include "tier1/strtools.h"
2022-05-28 16:12:37 +02:00
2022-08-13 12:39:57 +02:00
FORCEINLINE unsigned char tolower_fast ( unsigned char c )
{
if ( ( c > = ' A ' ) & & ( c < = ' Z ' ) )
return c + ( ' a ' - ' A ' ) ;
return c ;
}
//-----------------------------------------------------------------------------
// Finds a string in another string with a case insensitive test
//-----------------------------------------------------------------------------
char const * V_stristr ( char const * pStr , char const * pSearch )
{
AssertValidStringPtr ( reinterpret_cast < const TCHAR * > ( pStr ) ) ;
AssertValidStringPtr ( reinterpret_cast < const TCHAR * > ( pSearch ) ) ;
if ( ! pStr | | ! pSearch )
return 0 ;
char const * pLetter = pStr ;
// Check the entire string
while ( * pLetter ! = 0 )
{
// Skip over non-matches
if ( tolower_fast ( ( unsigned char ) * pLetter ) = = tolower_fast ( ( unsigned char ) * pSearch ) )
{
// Check for match
char const * pMatch = pLetter + 1 ;
char const * pTest = pSearch + 1 ;
while ( * pTest ! = 0 )
{
// We've run off the end; don't bother.
if ( * pMatch = = 0 )
return 0 ;
if ( tolower_fast ( ( unsigned char ) * pMatch ) ! = tolower_fast ( ( unsigned char ) * pTest ) )
break ;
+ + pMatch ;
+ + pTest ;
}
// Found a match!
if ( * pTest = = 0 )
return pLetter ;
}
+ + pLetter ;
}
return 0 ;
}
char * V_stristr ( char * pStr , char const * pSearch )
{
AssertValidStringPtr ( reinterpret_cast < const TCHAR * > ( pStr ) ) ;
AssertValidStringPtr ( reinterpret_cast < const TCHAR * > ( pSearch ) ) ;
return ( char * ) V_stristr ( ( char const * ) pStr , pSearch ) ;
}
2022-05-28 16:12:37 +02:00
2022-11-22 08:57:33 +01:00
//-----------------------------------------------------------------------------
// Finds a string in another string with a case insensitive test w/ length validation
//-----------------------------------------------------------------------------
2023-02-12 17:54:15 +01:00
const char * V_strnistr ( const char * pStr , const char * pSearch , int64_t n )
2022-11-22 08:57:33 +01:00
{
Assert ( pStr ) ;
Assert ( pSearch ) ;
if ( ! pStr | | ! pSearch )
return 0 ;
const char * pLetter = pStr ;
// Check the entire string
while ( * pLetter ! = 0 )
{
if ( n < = 0 )
return 0 ;
// Skip over non-matches
if ( FastASCIIToLower ( * pLetter ) = = FastASCIIToLower ( * pSearch ) )
{
int n1 = n - 1 ;
// Check for match
const char * pMatch = pLetter + 1 ;
const char * pTest = pSearch + 1 ;
while ( * pTest ! = 0 )
{
if ( n1 < = 0 )
return 0 ;
// We've run off the end; don't bother.
if ( * pMatch = = 0 )
return 0 ;
if ( FastASCIIToLower ( * pMatch ) ! = FastASCIIToLower ( * pTest ) )
break ;
+ + pMatch ;
+ + pTest ;
- - n1 ;
}
// Found a match!
if ( * pTest = = 0 )
return pLetter ;
}
+ + pLetter ;
- - n ;
}
return 0 ;
}
2023-02-12 17:54:15 +01:00
const char * V_strnchr ( const char * pStr , char c , int64_t n )
2022-11-22 08:57:33 +01:00
{
const char * pLetter = pStr ;
const char * pLast = pStr + n ;
// Check the entire string
while ( ( pLetter < pLast ) & & ( * pLetter ! = 0 ) )
{
if ( * pLetter = = c )
return pLetter ;
+ + pLetter ;
}
return NULL ;
}
bool V_isspace ( int c )
{
// The standard white-space characters are the following: space, tab, carriage-return, newline, vertical tab, and form-feed. In the C locale, V_isspace() returns true only for the standard white-space characters.
//return c == ' ' || c == 9 /*horizontal tab*/ || c == '\r' || c == '\n' || c == 11 /*vertical tab*/ || c == '\f';
// codes of whitespace symbols: 9 HT, 10 \n, 11 VT, 12 form feed, 13 \r, 32 space
// easy to understand version, validated:
// return ((1 << (c-1)) & 0x80001F00) != 0 && ((c-1)&0xE0) == 0;
// 5% faster on Core i7, 35% faster on Xbox360, no branches, validated:
# ifdef _X360
return ( ( 1 < < ( c - 1 ) ) & 0x80001F00 & ~ ( - int ( ( c - 1 ) & 0xE0 ) ) ) ! = 0 ;
# else
// this is 11% faster on Core i7 than the previous, VC2005 compiler generates a seemingly unbalanced search tree that's faster
switch ( c )
{
case ' ' :
case 9 :
case ' \r ' :
case ' \n ' :
case 11 :
case ' \f ' :
return true ;
default :
return false ;
}
# endif
}
2022-05-28 16:12:37 +02:00
//-----------------------------------------------------------------------------
// Purpose: Converts a UTF8 string into a unicode string
//-----------------------------------------------------------------------------
int V_UTF8ToUnicode ( const char * pUTF8 , wchar_t * pwchDest , int cubDestSizeInBytes )
{
Assert ( cubDestSizeInBytes > = sizeof ( * pwchDest ) ) ;
pwchDest [ 0 ] = 0 ;
if ( ! pUTF8 )
return 0 ;
# ifdef _WIN32
int cchResult = MultiByteToWideChar ( CP_UTF8 , 0 , pUTF8 , - 1 , pwchDest , cubDestSizeInBytes / sizeof ( wchar_t ) ) ;
# elif POSIX
int cchResult = mbstowcs ( pwchDest , pUTF8 , cubDestSizeInBytes / sizeof ( wchar_t ) ) ;
# endif
pwchDest [ ( cubDestSizeInBytes / sizeof ( wchar_t ) ) - 1 ] = 0 ;
return cchResult ;
}
//-----------------------------------------------------------------------------
// Purpose: Converts a unicode string into a UTF8 (standard) string
//-----------------------------------------------------------------------------
int V_UnicodeToUTF8 ( const wchar_t * pUnicode , char * pUTF8 , int cubDestSizeInBytes )
{
if ( cubDestSizeInBytes > 0 )
pUTF8 [ 0 ] = 0 ;
# ifdef _WIN32
int cchResult = WideCharToMultiByte ( CP_UTF8 , 0 , pUnicode , - 1 , pUTF8 , cubDestSizeInBytes , NULL , NULL ) ;
# elif POSIX
int cchResult = 0 ;
if ( pUnicode & & pUTF8 )
cchResult = wcstombs ( pUTF8 , pUnicode , cubDestSizeInBytes ) ;
# endif
if ( cubDestSizeInBytes > 0 )
pUTF8 [ cubDestSizeInBytes - 1 ] = 0 ;
return cchResult ;
2022-11-07 22:25:20 +01:00
}
//-----------------------------------------------------------------------------
// Purpose: Changes all '/' or '\' characters into separator
// Input : *pName -
// cSeparator -
//-----------------------------------------------------------------------------
void V_FixSlashes ( char * pName , char cSeperator /* = CORRECT_PATH_SEPARATOR */ )
{
while ( * pName )
{
if ( * pName = = INCORRECT_PATH_SEPARATOR | | * pName = = CORRECT_PATH_SEPARATOR )
{
* pName = cSeperator ;
}
pName + + ;
}
2022-05-28 16:12:37 +02:00
}