mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-20 12:36:05 +08:00
Imported more changes from sdk2013.
This commit is contained in:
@ -992,9 +992,240 @@ char *V_pretifynum( int64 value )
|
||||
return out;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: returns true if a wide character is a "mean" space; that is,
|
||||
// if it is technically a space or punctuation, but causes disruptive
|
||||
// behavior when used in names, web pages, chat windows, etc.
|
||||
//
|
||||
// characters in this set are removed from the beginning and/or end of strings
|
||||
// by Q_AggressiveStripPrecedingAndTrailingWhitespaceW()
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_IsMeanSpaceW( wchar_t wch )
|
||||
{
|
||||
bool bIsMean = false;
|
||||
|
||||
switch ( wch )
|
||||
{
|
||||
case L'\x0082': // BREAK PERMITTED HERE
|
||||
case L'\x0083': // NO BREAK PERMITTED HERE
|
||||
case L'\x00A0': // NO-BREAK SPACE
|
||||
case L'\x034F': // COMBINING GRAPHEME JOINER
|
||||
case L'\x2000': // EN QUAD
|
||||
case L'\x2001': // EM QUAD
|
||||
case L'\x2002': // EN SPACE
|
||||
case L'\x2003': // EM SPACE
|
||||
case L'\x2004': // THICK SPACE
|
||||
case L'\x2005': // MID SPACE
|
||||
case L'\x2006': // SIX SPACE
|
||||
case L'\x2007': // figure space
|
||||
case L'\x2008': // PUNCTUATION SPACE
|
||||
case L'\x2009': // THIN SPACE
|
||||
case L'\x200A': // HAIR SPACE
|
||||
case L'\x200B': // ZERO-WIDTH SPACE
|
||||
case L'\x200C': // ZERO-WIDTH NON-JOINER
|
||||
case L'\x200D': // ZERO WIDTH JOINER
|
||||
case L'\x200E': // LEFT-TO-RIGHT MARK
|
||||
case L'\x2028': // LINE SEPARATOR
|
||||
case L'\x2029': // PARAGRAPH SEPARATOR
|
||||
case L'\x202F': // NARROW NO-BREAK SPACE
|
||||
case L'\x2060': // word joiner
|
||||
case L'\xFEFF': // ZERO-WIDTH NO BREAK SPACE
|
||||
case L'\xFFFC': // OBJECT REPLACEMENT CHARACTER
|
||||
bIsMean = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return bIsMean;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Converts a UTF8 string into a unicode string
|
||||
// Purpose: strips trailing whitespace; returns pointer inside string just past
|
||||
// any leading whitespace.
|
||||
//
|
||||
// bAggresive = true causes this function to also check for "mean" spaces,
|
||||
// which we don't want in persona names or chat strings as they're disruptive
|
||||
// to the user experience.
|
||||
//-----------------------------------------------------------------------------
|
||||
static wchar_t *StripWhitespaceWorker( int cchLength, wchar_t *pwch, bool *pbStrippedWhitespace, bool bAggressive )
|
||||
{
|
||||
// walk backwards from the end of the string, killing any whitespace
|
||||
*pbStrippedWhitespace = false;
|
||||
|
||||
wchar_t *pwchEnd = pwch + cchLength;
|
||||
while ( --pwchEnd >= pwch )
|
||||
{
|
||||
if ( !iswspace( *pwchEnd ) && ( !bAggressive || !Q_IsMeanSpaceW( *pwchEnd ) ) )
|
||||
break;
|
||||
|
||||
*pwchEnd = 0;
|
||||
*pbStrippedWhitespace = true;
|
||||
}
|
||||
|
||||
// walk forward in the string
|
||||
while ( pwch < pwchEnd )
|
||||
{
|
||||
if ( !iswspace( *pwch ) )
|
||||
break;
|
||||
|
||||
*pbStrippedWhitespace = true;
|
||||
pwch++;
|
||||
}
|
||||
|
||||
return pwch;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Strips all evil characters (ie. zero-width no-break space)
|
||||
// from a string.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_RemoveAllEvilCharacters( char *pch )
|
||||
{
|
||||
// convert to unicode
|
||||
int cch = Q_strlen( pch );
|
||||
int cubDest = (cch + 1 ) * sizeof( wchar_t );
|
||||
wchar_t *pwch = (wchar_t *)stackalloc( cubDest );
|
||||
int cwch = Q_UTF8ToUnicode( pch, pwch, cubDest ) / sizeof( wchar_t );
|
||||
|
||||
bool bStrippedWhitespace = false;
|
||||
|
||||
// Walk through and skip over evil characters
|
||||
int nWalk = 0;
|
||||
for( int i=0; i<cwch; ++i )
|
||||
{
|
||||
if( !Q_IsMeanSpaceW( pwch[i] ) )
|
||||
{
|
||||
pwch[nWalk] = pwch[i];
|
||||
++nWalk;
|
||||
}
|
||||
else
|
||||
{
|
||||
bStrippedWhitespace = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Null terminate
|
||||
pwch[nWalk-1] = L'\0';
|
||||
|
||||
|
||||
// copy back, if necessary
|
||||
if ( bStrippedWhitespace )
|
||||
{
|
||||
Q_UnicodeToUTF8( pwch, pch, cch );
|
||||
}
|
||||
|
||||
return bStrippedWhitespace;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: strips leading and trailing whitespace
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_StripPrecedingAndTrailingWhitespaceW( wchar_t *pwch )
|
||||
{
|
||||
int cch = Q_wcslen( pwch );
|
||||
|
||||
// Early out and don't convert if we don't have any chars or leading/trailing ws.
|
||||
if ( ( cch < 1 ) || ( !iswspace( pwch[ 0 ] ) && !iswspace( pwch[ cch - 1 ] ) ) )
|
||||
return false;
|
||||
|
||||
// duplicate on stack
|
||||
int cubDest = ( cch + 1 ) * sizeof( wchar_t );
|
||||
wchar_t *pwchT = (wchar_t *)stackalloc( cubDest );
|
||||
Q_wcsncpy( pwchT, pwch, cubDest );
|
||||
|
||||
bool bStrippedWhitespace = false;
|
||||
pwchT = StripWhitespaceWorker( cch, pwch, &bStrippedWhitespace, false /* not aggressive */ );
|
||||
|
||||
// copy back, if necessary
|
||||
if ( bStrippedWhitespace )
|
||||
{
|
||||
Q_wcsncpy( pwch, pwchT, cubDest );
|
||||
}
|
||||
|
||||
return bStrippedWhitespace;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: strips leading and trailing whitespace,
|
||||
// and also strips punctuation and formatting characters with "clear"
|
||||
// representations.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_AggressiveStripPrecedingAndTrailingWhitespaceW( wchar_t *pwch )
|
||||
{
|
||||
// duplicate on stack
|
||||
int cch = Q_wcslen( pwch );
|
||||
int cubDest = ( cch + 1 ) * sizeof( wchar_t );
|
||||
wchar_t *pwchT = (wchar_t *)stackalloc( cubDest );
|
||||
Q_wcsncpy( pwchT, pwch, cubDest );
|
||||
|
||||
bool bStrippedWhitespace = false;
|
||||
pwchT = StripWhitespaceWorker( cch, pwch, &bStrippedWhitespace, true /* is aggressive */ );
|
||||
|
||||
// copy back, if necessary
|
||||
if ( bStrippedWhitespace )
|
||||
{
|
||||
Q_wcsncpy( pwch, pwchT, cubDest );
|
||||
}
|
||||
|
||||
return bStrippedWhitespace;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: strips leading and trailing whitespace
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_StripPrecedingAndTrailingWhitespace( char *pch )
|
||||
{
|
||||
int cch = Q_strlen( pch );
|
||||
|
||||
// Early out and don't convert if we don't have any chars or leading/trailing ws.
|
||||
if ( ( cch < 1 ) || ( !isspace( (unsigned char)pch[ 0 ] ) && !isspace( (unsigned char)pch[ cch - 1 ] ) ) )
|
||||
return false;
|
||||
|
||||
// convert to unicode
|
||||
int cubDest = (cch + 1 ) * sizeof( wchar_t );
|
||||
wchar_t *pwch = (wchar_t *)stackalloc( cubDest );
|
||||
int cwch = Q_UTF8ToUnicode( pch, pwch, cubDest ) / sizeof( wchar_t );
|
||||
|
||||
bool bStrippedWhitespace = false;
|
||||
pwch = StripWhitespaceWorker( cwch-1, pwch, &bStrippedWhitespace, false /* not aggressive */ );
|
||||
|
||||
// copy back, if necessary
|
||||
if ( bStrippedWhitespace )
|
||||
{
|
||||
Q_UnicodeToUTF8( pwch, pch, cch );
|
||||
}
|
||||
|
||||
return bStrippedWhitespace;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: strips leading and trailing whitespace
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Q_AggressiveStripPrecedingAndTrailingWhitespace( char *pch )
|
||||
{
|
||||
// convert to unicode
|
||||
int cch = Q_strlen( pch );
|
||||
int cubDest = (cch + 1 ) * sizeof( wchar_t );
|
||||
wchar_t *pwch = (wchar_t *)stackalloc( cubDest );
|
||||
int cwch = Q_UTF8ToUnicode( pch, pwch, cubDest ) / sizeof( wchar_t );
|
||||
|
||||
bool bStrippedWhitespace = false;
|
||||
pwch = StripWhitespaceWorker( cwch-1, pwch, &bStrippedWhitespace, true /* is aggressive */ );
|
||||
|
||||
// copy back, if necessary
|
||||
if ( bStrippedWhitespace )
|
||||
{
|
||||
Q_UnicodeToUTF8( pwch, pch, cch );
|
||||
}
|
||||
|
||||
return bStrippedWhitespace;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Converts a ucs2 string to a unicode (wchar_t) one, no-op on win32
|
||||
//-----------------------------------------------------------------------------
|
||||
int V_UTF8ToUnicode( const char *pUTF8, wchar_t *pwchDest, int cubDestSizeInBytes )
|
||||
{
|
||||
|
Reference in New Issue
Block a user