mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-20 04:26:03 +08:00
Update CBufferString class
This commit is contained in:

committed by
Nicholas Hastings

parent
1312e1c957
commit
b6a89a4815
@ -68,9 +68,11 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_bReliable;
|
bool m_bReliable;
|
||||||
bool m_bInitMessage;
|
int m_Unk001;
|
||||||
CUtlVector< int > m_Recipients;
|
int m_nRecipientCount;
|
||||||
|
CUtlVectorFixedGrowable< int, 64 > m_Recipients;
|
||||||
|
|
||||||
|
bool m_bInitMessage;
|
||||||
// If using prediction rules, the filter itself suppresses local player
|
// If using prediction rules, the filter itself suppresses local player
|
||||||
bool m_bUsingPredictionRules;
|
bool m_bUsingPredictionRules;
|
||||||
// If ignoring prediction cull, then external systems can determine
|
// If ignoring prediction cull, then external systems can determine
|
||||||
|
@ -521,7 +521,7 @@ public:
|
|||||||
virtual bool GetWritePath(const char*, const char*, CBufferString &) = 0;
|
virtual bool GetWritePath(const char*, const char*, CBufferString &) = 0;
|
||||||
|
|
||||||
// Returns the nSearchPathsToGet amount of paths, each path is separated by ;s. Returns true if pathID has any paths
|
// Returns the nSearchPathsToGet amount of paths, each path is separated by ;s. Returns true if pathID has any paths
|
||||||
virtual bool GetSearchPath( const char *pathID, GetSearchPathTypes_t pathType, CBufferString *pPath, int nSearchPathsToGet ) = 0;
|
virtual bool GetSearchPath( const char *pathID, GetSearchPathTypes_t pathType, CBufferString &pPath, int nSearchPathsToGet ) = 0;
|
||||||
|
|
||||||
virtual void unk003() = 0;
|
virtual void unk003() = 0;
|
||||||
virtual void unk004() = 0;
|
virtual void unk004() = 0;
|
||||||
|
@ -12,34 +12,24 @@ class IFormatOutputStream;
|
|||||||
enum EStringConvertErrorPolicy;
|
enum EStringConvertErrorPolicy;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Example usage of CBufferString class:
|
Main idea of CBufferString is to provide the base class for the CBufferStringGrowable wich implements stack allocation
|
||||||
|
with the ability to convert to the heap allocation if allowed.
|
||||||
|
|
||||||
* Stack buffer allocation:
|
Example usage of CBufferStringGrowable class:
|
||||||
```
|
|
||||||
CBufferString *buff = BUFFER_STRING_STACK(256);
|
|
||||||
buff->Insert(0, "Hello World!");
|
|
||||||
printf("Result: %s\n", buff->Get());
|
|
||||||
```
|
|
||||||
to check if the buffer is stack allocated, CBufferString::IsStackAllocated() should be used.
|
|
||||||
NOTE: As the buffer is stack allocated, it would be FREED once it's out of the scope it was defined in!
|
|
||||||
|
|
||||||
* Heap buffer allocation:
|
* Basic buffer allocation:
|
||||||
```
|
```
|
||||||
// Regular constructor would provide the heap allocated buffer!!
|
CBufferStringGrowable<256> buff;
|
||||||
CBufferString *buff = new CBufferString(256);
|
|
||||||
buff->Insert(0, "Hello World!");
|
|
||||||
printf("Result: %s\n", buff->Get());
|
|
||||||
```
|
|
||||||
alternatively CBufferString could be allocated on stack with the buffer on heap:
|
|
||||||
```
|
|
||||||
// Regular constructor would provide the heap allocated buffer!!
|
|
||||||
CBufferString buff(256);
|
|
||||||
buff.Insert(0, "Hello World!");
|
buff.Insert(0, "Hello World!");
|
||||||
printf("Result: %s\n", buff.Get());
|
printf("Result: %s\n", buff.Get());
|
||||||
```
|
```
|
||||||
to check if the buffer is heap allocated, CBufferString::IsHeapAllocated() should be used.
|
additionaly the heap allocation of the buffer could be disabled, by providing ``AllowHeapAllocation`` template argument,
|
||||||
|
by disabling heap allocation, if the buffer capacity is not enough to perform the operation, the app would exit with an Assert;
|
||||||
|
|
||||||
* Calling CBufferString::Get() would return a pointer to the data, or an empty string if it's not allocated.
|
* Additional usage:
|
||||||
|
CBufferString::IsStackAllocated() - could be used to check if the buffer is stack allocated;
|
||||||
|
CBufferString::IsHeapAllocated() - could be used to check if the buffer is heap allocated;
|
||||||
|
CBufferString::Get() - would return a pointer to the data, or an empty string if it's not allocated.
|
||||||
|
|
||||||
* Additionaly current length of the buffer could be read via CBufferString::GetTotalNumber()
|
* Additionaly current length of the buffer could be read via CBufferString::GetTotalNumber()
|
||||||
and currently allocated amount of bytes could be read via CBufferString::GetAllocatedNumber()
|
and currently allocated amount of bytes could be read via CBufferString::GetAllocatedNumber()
|
||||||
@ -47,93 +37,22 @@ enum EStringConvertErrorPolicy;
|
|||||||
* Most, if not all the functions would ensure the buffer capacity and enlarge it when needed,
|
* Most, if not all the functions would ensure the buffer capacity and enlarge it when needed,
|
||||||
in case of stack allocated buffers, it would switch to heap allocation instead.
|
in case of stack allocated buffers, it would switch to heap allocation instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class CBufferString
|
class CBufferString
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
// You shouldn't be initializing this class, use CBufferStringGrowable instead.
|
||||||
|
CBufferString() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CBufferString(int nSize): m_nAllocated(0), m_nTotalCount(0)
|
|
||||||
{
|
|
||||||
// HACK: Using game's built in allocator on windows to avoid heap corruption issues of reallocs made by the game
|
|
||||||
#if PLATFORM_WINDOWS
|
|
||||||
m_Memory.m_pString = (char *)g_pMemAlloc->IndirectAlloc(nSize);
|
|
||||||
#else
|
|
||||||
m_Memory.m_pString = new char[nSize];
|
|
||||||
#endif
|
|
||||||
m_nAllocated |= HEAP_ALLOCATION_MARKER | (nSize & LENGTH_MASK);
|
|
||||||
m_nTotalCount |= HEAP_ALLOCATION_MARKER;
|
|
||||||
}
|
|
||||||
|
|
||||||
~CBufferString()
|
|
||||||
{
|
|
||||||
if (IsHeapAllocated() && m_Memory.m_pString)
|
|
||||||
{
|
|
||||||
#if PLATFORM_WINDOWS
|
|
||||||
g_pMemAlloc->Free((void*)m_Memory.m_pString);
|
|
||||||
#else
|
|
||||||
delete[] m_Memory.m_pString;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expects a stack allocated pointer as a first param, use BUFFER_STRING_STACK macro instead
|
|
||||||
static inline CBufferString *InitStackAlloc(void *pData, int nSize)
|
|
||||||
{
|
|
||||||
CBufferString *buff = (CBufferString *)pData;
|
|
||||||
|
|
||||||
memset(buff, 0, nSize);
|
|
||||||
buff->m_nAllocated |= STACK_ALLOCATION_MARKER | (nSize & LENGTH_MASK);
|
|
||||||
buff->m_nTotalCount = 0;
|
|
||||||
|
|
||||||
return buff;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int GetAllocatedNumber() const
|
|
||||||
{
|
|
||||||
return m_nAllocated & LENGTH_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int GetTotalNumber() const
|
|
||||||
{
|
|
||||||
return m_nTotalCount & LENGTH_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsStackAllocated() const
|
|
||||||
{
|
|
||||||
return (m_nAllocated & STACK_ALLOCATION_MARKER) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsHeapAllocated() const
|
|
||||||
{
|
|
||||||
return (m_nTotalCount & HEAP_ALLOCATION_MARKER) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsInputStringUnsafe(const char *pData)
|
|
||||||
{
|
|
||||||
return ((void *)pData >= this && (void *)pData < &this[1]) ||
|
|
||||||
(GetAllocatedNumber() != 0 && pData >= Get() && pData < (Get() + GetAllocatedNumber()));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char *Get() const
|
|
||||||
{
|
|
||||||
if (IsStackAllocated())
|
|
||||||
{
|
|
||||||
return m_Memory.m_szString;
|
|
||||||
}
|
|
||||||
else if (GetAllocatedNumber() != 0)
|
|
||||||
{
|
|
||||||
return m_Memory.m_pString;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
enum EAllocationOption_t
|
enum EAllocationOption_t
|
||||||
{
|
{
|
||||||
UNK1 = -1,
|
UNK1 = -1,
|
||||||
UNK2 = 0,
|
UNK2 = 0,
|
||||||
UNK3 = (1 << 1),
|
UNK3 = (1 << 1),
|
||||||
UNK4 = (1 << 8),
|
UNK4 = (1 << 8),
|
||||||
UNK5 = (1 << 9)
|
UNK5 = (1 << 9),
|
||||||
|
ALLOW_HEAP_ALLOCATION = (1 << 31)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EAllocationFlags_t
|
enum EAllocationFlags_t
|
||||||
@ -183,7 +102,7 @@ public:
|
|||||||
DLL_CLASS_IMPORT const char *ExtractFilePath(const char *pPath, bool);
|
DLL_CLASS_IMPORT const char *ExtractFilePath(const char *pPath, bool);
|
||||||
DLL_CLASS_IMPORT const char *ExtractFirstDir(const char *pPath);
|
DLL_CLASS_IMPORT const char *ExtractFirstDir(const char *pPath);
|
||||||
|
|
||||||
DLL_CLASS_IMPORT const char *FixSlashes(char cSeparator);
|
DLL_CLASS_IMPORT const char *FixSlashes(char cSeparator = CORRECT_PATH_SEPARATOR);
|
||||||
DLL_CLASS_IMPORT const char *FixupPathName(char cSeparator);
|
DLL_CLASS_IMPORT const char *FixupPathName(char cSeparator);
|
||||||
|
|
||||||
DLL_CLASS_IMPORT int Format(const char *pFormat, ...);
|
DLL_CLASS_IMPORT int Format(const char *pFormat, ...);
|
||||||
@ -207,11 +126,11 @@ public:
|
|||||||
// Wrapper around V_MakeAbsolutePath()
|
// Wrapper around V_MakeAbsolutePath()
|
||||||
DLL_CLASS_IMPORT const char *MakeAbsolutePath(const char *pPath, const char *pStartingDir);
|
DLL_CLASS_IMPORT const char *MakeAbsolutePath(const char *pPath, const char *pStartingDir);
|
||||||
// Wrapper around V_MakeAbsolutePath() but also does separator fixup
|
// Wrapper around V_MakeAbsolutePath() but also does separator fixup
|
||||||
DLL_CLASS_IMPORT const char *MakeFixedAbsolutePath(const char *pPath, const char *pStartingDir, char cSeparator);
|
DLL_CLASS_IMPORT const char *MakeFixedAbsolutePath(const char *pPath, const char *pStartingDir, char cSeparator = CORRECT_PATH_SEPARATOR);
|
||||||
// Wrapper around V_MakeRelativePath()
|
// Wrapper around V_MakeRelativePath()
|
||||||
DLL_CLASS_IMPORT const char *MakeRelativePath(const char *pFullPath, const char *pDirectory);
|
DLL_CLASS_IMPORT const char *MakeRelativePath(const char *pFullPath, const char *pDirectory);
|
||||||
|
|
||||||
DLL_CLASS_IMPORT void MoveFrom(CBufferString& pOther);
|
DLL_CLASS_IMPORT void MoveFrom(CBufferString &pOther);
|
||||||
|
|
||||||
DLL_CLASS_IMPORT void Purge(int nLength);
|
DLL_CLASS_IMPORT void Purge(int nLength);
|
||||||
|
|
||||||
@ -224,7 +143,7 @@ public:
|
|||||||
DLL_CLASS_IMPORT int RemoveWhitespace();
|
DLL_CLASS_IMPORT int RemoveWhitespace();
|
||||||
|
|
||||||
DLL_CLASS_IMPORT const char *RemoveFilePath();
|
DLL_CLASS_IMPORT const char *RemoveFilePath();
|
||||||
DLL_CLASS_IMPORT const char *RemoveFirstDir(CBufferString* pRemovedDir);
|
DLL_CLASS_IMPORT const char *RemoveFirstDir(CBufferString *pRemovedDir);
|
||||||
DLL_CLASS_IMPORT const char *RemoveToFileBase();
|
DLL_CLASS_IMPORT const char *RemoveToFileBase();
|
||||||
|
|
||||||
DLL_CLASS_IMPORT bool RemovePartialUTF8Tail(bool);
|
DLL_CLASS_IMPORT bool RemovePartialUTF8Tail(bool);
|
||||||
@ -261,28 +180,91 @@ public:
|
|||||||
DLL_CLASS_IMPORT void ToLowerFast(int nStart);
|
DLL_CLASS_IMPORT void ToLowerFast(int nStart);
|
||||||
DLL_CLASS_IMPORT void ToUpperFast(int nStart);
|
DLL_CLASS_IMPORT void ToUpperFast(int nStart);
|
||||||
|
|
||||||
DLL_CLASS_IMPORT const char *Trim(const char *pTrimChars);
|
DLL_CLASS_IMPORT const char *Trim(const char *pTrimChars = "\t\r\n ");
|
||||||
DLL_CLASS_IMPORT const char *TrimHead(const char *pTrimChars);
|
DLL_CLASS_IMPORT const char *TrimHead(const char *pTrimChars = "\t\r\n ");
|
||||||
DLL_CLASS_IMPORT const char *TrimTail(const char *pTrimChars);
|
DLL_CLASS_IMPORT const char *TrimTail(const char *pTrimChars = "\t\r\n ");
|
||||||
|
|
||||||
DLL_CLASS_IMPORT const char *TruncateAt(int nIndex, bool bIgnoreAlignment = false);
|
DLL_CLASS_IMPORT const char *TruncateAt(int nIndex, bool bIgnoreAlignment = false);
|
||||||
DLL_CLASS_IMPORT const char *TruncateAt(const char *pStr, bool bIgnoreAlignment = false);
|
DLL_CLASS_IMPORT const char *TruncateAt(const char *pStr, bool bIgnoreAlignment = false);
|
||||||
|
|
||||||
DLL_CLASS_IMPORT int UnicodeCaseConvert(int, EStringConvertErrorPolicy eErrorPolicy);
|
DLL_CLASS_IMPORT int UnicodeCaseConvert(int, EStringConvertErrorPolicy eErrorPolicy);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<size_t MAX_SIZE, bool AllowHeapAllocation = true>
|
||||||
|
class CBufferStringGrowable : public CBufferString
|
||||||
|
{
|
||||||
|
friend class CBufferString;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CBufferStringGrowable() : m_nAllocated(STACK_ALLOCATION_MARKER | (MAX_SIZE & LENGTH_MASK)), m_nTotalCount(0), m_Memory()
|
||||||
|
{
|
||||||
|
if (AllowHeapAllocation)
|
||||||
|
{
|
||||||
|
m_nAllocated |= ALLOW_HEAP_ALLOCATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~CBufferStringGrowable()
|
||||||
|
{
|
||||||
|
if (IsHeapAllocated() && m_Memory.m_pString)
|
||||||
|
{
|
||||||
|
#if PLATFORM_WINDOWS
|
||||||
|
g_pMemAlloc->Free((void*)m_Memory.m_pString);
|
||||||
|
#else
|
||||||
|
delete[] m_Memory.m_pString;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int GetAllocatedNumber() const
|
||||||
|
{
|
||||||
|
return m_nAllocated & LENGTH_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int GetTotalNumber() const
|
||||||
|
{
|
||||||
|
return m_nTotalCount & LENGTH_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsStackAllocated() const
|
||||||
|
{
|
||||||
|
return (m_nAllocated & STACK_ALLOCATION_MARKER) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsHeapAllocated() const
|
||||||
|
{
|
||||||
|
return (m_nTotalCount & HEAP_ALLOCATION_MARKER) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsInputStringUnsafe(const char *pData) const
|
||||||
|
{
|
||||||
|
return ((void *)pData >= this && (void *)pData < &this[1]) ||
|
||||||
|
(GetAllocatedNumber() != 0 && pData >= Get() && pData < (Get() + GetAllocatedNumber()));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char *Get() const
|
||||||
|
{
|
||||||
|
if (IsStackAllocated())
|
||||||
|
{
|
||||||
|
return m_Memory.m_szString;
|
||||||
|
}
|
||||||
|
else if (GetAllocatedNumber() != 0)
|
||||||
|
{
|
||||||
|
return m_Memory.m_pString;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringFuncs<char>::EmptyString();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_nTotalCount;
|
int m_nTotalCount;
|
||||||
int m_nAllocated;
|
int m_nAllocated;
|
||||||
|
|
||||||
union CBufferStringMemory
|
union
|
||||||
{
|
{
|
||||||
const char *m_pString;
|
const char *m_pString;
|
||||||
const char m_szString[];
|
const char m_szString[MAX_SIZE];
|
||||||
|
|
||||||
CBufferStringMemory() {}
|
|
||||||
} m_Memory;
|
} m_Memory;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BUFFER_STRING_STACK(_size) CBufferString::InitStackAlloc(stackalloc(sizeof(CBufferString) + _size), ALIGN_VALUE(sizeof(CBufferString) + _size, 16 ) - sizeof(CBufferString))
|
|
||||||
|
|
||||||
#endif /* BUFFERSTRING_H */
|
#endif /* BUFFERSTRING_H */
|
@ -287,6 +287,9 @@ protected:
|
|||||||
I m_FirstFree;
|
I m_FirstFree;
|
||||||
typename M::Iterator_t m_LastAlloc; // the last index allocated
|
typename M::Iterator_t m_LastAlloc; // the last index allocated
|
||||||
|
|
||||||
|
int m_nAllocationCount;
|
||||||
|
int m_nGrowSize;
|
||||||
|
|
||||||
FORCEINLINE M const &Elements( void ) const
|
FORCEINLINE M const &Elements( void ) const
|
||||||
{
|
{
|
||||||
return m_Elements;
|
return m_Elements;
|
||||||
|
Reference in New Issue
Block a user