A more complete implementation of the CUtlBuffer class

Added the implementation file and changed more methods to be 64 bit.
This commit is contained in:
Kawe Mazidjatari 2022-11-22 08:57:33 +01:00
parent 23af39e67b
commit 843cc6f4ca
5 changed files with 2042 additions and 12 deletions

View File

@ -245,7 +245,7 @@ private:
((unsigned char*)&temp)[i] = ((unsigned char*)input)[sizeof(T) - (i + 1)];
}
#endif
Q_memcpy(output, &temp, sizeof(T));
memcpy(output, &temp, sizeof(T));
}
#if defined( _X360 )

View File

@ -62,6 +62,105 @@ char* V_stristr(char* pStr, char const* pSearch)
return (char*)V_stristr((char const*)pStr, pSearch);
}
//-----------------------------------------------------------------------------
// Finds a string in another string with a case insensitive test w/ length validation
//-----------------------------------------------------------------------------
const char* V_strnistr(const char* pStr, const char* pSearch, int n)
{
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;
}
const char* V_strnchr(const char* pStr, char c, int n)
{
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
}
//-----------------------------------------------------------------------------
// Purpose: Converts a UTF8 string into a unicode string
//-----------------------------------------------------------------------------

View File

@ -8,6 +8,16 @@
#define INCORRECT_PATH_SEPARATOR '\\'
#endif
/// Faster conversion of an ascii char to upper case. This function does not obey locale or any language
/// setting. It should not be used to convert characters for printing, but it is a better choice
/// for internal strings such as used for hash table keys, etc. It's meant to be inlined and used
/// in places like the various dictionary classes. Not obeying locale also protects you from things
/// like your hash values being different depending on the locale setting.
#define FastASCIIToUpper( c ) ( ( ( (c) >= 'a' ) && ( (c) <= 'z' ) ) ? ( (c) - 32 ) : (c) )
/// similar to FastASCIIToLower
#define FastASCIIToLower( c ) ( ( ( (c) >= 'A' ) && ( (c) <= 'Z' ) ) ? ( (c) + 32 ) : (c) )
#define V_vsnprintf vsnprintf
#define V_snprintf snprintf
#define V_strlower _strlwr
#define V_strlen strlen
@ -15,18 +25,26 @@
#define V_stricmp _stricmp
#define V_strnicmp _strnicmp
#define V_strcmp strcmp
#define V_strncmp strncmp
#define Q_vsnprintf V_vsnprintf
#define Q_snprintf V_snprintf
#define Q_strlower V_strlower
#define Q_strlen V_strlen
#define Q_strncat V_strncat
#define Q_strnistr V_strnistr
#define Q_stricmp V_stricmp
#define Q_strnicmp V_strnicmp
#define Q_strncasecmp V_strnicmp
#define Q_strcasecmp V_stricmp
#define Q_strcmp V_strcmp
#define Q_strncmp V_strncmp
char const* V_stristr(char const* pStr, char const* pSearch);
const char* V_strnistr(const char* pStr, const char* pSearch, int n);
const char* V_strnchr(const char* pStr, char c, int n);
bool V_isspace(int c);
int V_UTF8ToUnicode(const char* pUTF8, wchar_t* pwchDest, int cubDestSizeInBytes);
int V_UnicodeToUTF8(const wchar_t* pUnicode, char* pUTF8, int cubDestSizeInBytes);

1914
r5dev/tier1/utlbuffer.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,6 @@
#include "tier1/utlmemory.h"
#include "tier1/byteswap.h"
#include <stdarg.h>
#include <tier0/annotations.h>
@ -166,13 +165,13 @@ public:
};
// Overflow functions when a get or put overflows
typedef bool (CUtlBuffer::* UtlBufferOverflowFunc_t)(int nSize);
typedef bool (CUtlBuffer::* UtlBufferOverflowFunc_t)(int64 nSize);
// Constructors for growable + external buffers for serialization/unserialization
CUtlBuffer(int growSize = 0, int initSize = 0, int nFlags = 0);
CUtlBuffer(const void* pBuffer, int size, int nFlags = 0);
CUtlBuffer(int64 growSize = 0, int64 initSize = 0, int nFlags = 0);
CUtlBuffer(const void* pBuffer, int64 size, int nFlags = 0);
// This one isn't actually defined so that we catch contructors that are trying to pass a bool in as the third param.
CUtlBuffer(const void* pBuffer, int size, bool crap) = delete;
CUtlBuffer(const void* pBuffer, int64 size, bool crap) = delete;
// UtlBuffer objects should not be copyable; we do a slow copy if you use this but it asserts.
// (REI: I'd like to delete these but we have some python bindings that currently rely on being able to copy these objects)
@ -413,13 +412,13 @@ protected:
void SetOverflowFuncs(UtlBufferOverflowFunc_t getFunc, UtlBufferOverflowFunc_t putFunc);
bool OnPutOverflow(int nSize);
bool OnGetOverflow(int nSize);
bool OnPutOverflow(int64 nSize);
bool OnGetOverflow(int64 nSize);
protected:
// Checks if a get/put is ok
bool CheckPut(int size);
bool CheckGet(int size);
bool CheckPut(int64 size);
bool CheckGet(int64 size);
// NOTE: Pass in nPut here even though it is just a copy of m_Put. This is almost always called immediately
// after modifying m_Put and this lets it stay in a register
@ -434,8 +433,8 @@ protected:
void PutDelimitedCharInternal(CUtlCharConversion* pConv, char c);
// Default overflow funcs
bool PutOverflow(int nSize);
bool GetOverflow(int nSize);
bool PutOverflow(int64 nSize);
bool GetOverflow(int64 nSize);
// Does the next bytes of the buffer match a pattern?
bool PeekStringMatch(int nOffset, const char* pString, int nLen);