ReGameDLL_CS/regamedll/public/utlbuffer.h
2015-06-30 15:46:07 +06:00

342 lines
8.1 KiB
C++

//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// Serialization/unserialization buffer
//=============================================================================
#ifndef UTLBUFFER_H
#define UTLBUFFER_H
#include "osconfig.h"
#include "utlmemory.h"
#include <stdarg.h>
//-----------------------------------------------------------------------------
// Command parsing..
//-----------------------------------------------------------------------------
class CUtlBuffer
{
public:
enum SeekType_t
{
SEEK_HEAD = 0,
SEEK_CURRENT,
SEEK_TAIL
};
CUtlBuffer(int growSize = 0, int initSize = 0, bool text = false);
CUtlBuffer(void const* pBuffer, int size, bool text = false);
// Makes sure we've got at least this much memory
void EnsureCapacity(int num);
// Attaches the buffer to external memory....
void SetExternalBuffer(void* pMemory, int numElements, bool text = false);
// Read stuff out.
// Binary mode: it'll just read the bits directly in, and characters will be
// read for strings until a null character is reached.
// Text mode: it'll parse the file, turning text #s into real numbers.
// GetString will read a string until a space is reaced
char GetChar();
unsigned char GetUnsignedChar();
short GetShort();
unsigned short GetUnsignedShort();
int GetInt();
int GetIntHex();
unsigned int GetUnsignedInt();
float GetFloat();
double GetDouble();
void GetString(char* pString, int nMaxLen = 0);
void Get(void* pMem, int size);
// Just like scanf, but doesn't work in binary mode
int Scanf(char const* pFmt, ...);
int VaScanf(char const* pFmt, va_list list);
// Eats white space, advances Get index
void EatWhiteSpace();
// Write stuff in
// Binary mode: it'll just write the bits directly in, and strings will be
// written with a null terminating character
// Text mode: it'll convert the numbers to text versions
// PutString will not write a terminating character
void PutChar(char c);
void PutUnsignedChar(unsigned char uc);
void PutShort(short s);
void PutUnsignedShort(unsigned short us);
void PutInt(int i);
void PutUnsignedInt(unsigned int u);
void PutFloat(float f);
void PutDouble(double d);
void PutString(char const* pString);
void Put(void const* pMem, int size);
// Just like printf, writes a terminating zero in binary mode
void Printf(char const* pFmt, ...);
void VaPrintf(char const* pFmt, va_list list);
// What am I writing (put)/reading (get)?
void* PeekPut(int offset = 0);
void const* PeekGet(int offset = 0) const;
// Where am I writing (put)/reading (get)?
int TellPut() const;
int TellGet() const;
// Change where I'm writing (put)/reading (get)
void SeekPut(SeekType_t type, int offset);
void SeekGet(SeekType_t type, int offset);
// Buffer base
void const* Base() const;
void* Base();
// memory allocation size, does *not* reflect size written or read,
// use TellPut or TellGet for that
int Size() const;
// Am I a text buffer?
inline bool IsText() const { return (m_Flags & TEXT_BUFFER) != 0; }
// Am I valid? (overflow or underflow error), Once invalid it stays invalid
inline bool IsValid() const { return m_Error == 0; }
private:
// error flags
enum
{
PUT_OVERFLOW = 0x1,
GET_OVERFLOW = 0x2,
};
// flags
enum
{
TEXT_BUFFER = 0x1,
};
// Checks if a get/put is ok
bool CheckPut(int size);
bool CheckGet(int size);
CUtlMemory<unsigned char> m_Memory;
int m_Get;
int m_Put;
unsigned char m_Error;
unsigned char m_Flags;
};
//-----------------------------------------------------------------------------
// Where am I reading?
//-----------------------------------------------------------------------------
inline int CUtlBuffer::TellGet() const
{
return m_Get;
}
//-----------------------------------------------------------------------------
// What am I reading?
//-----------------------------------------------------------------------------
inline void const* CUtlBuffer::PeekGet(int offset) const
{
return &m_Memory[m_Get + offset];
}
//-----------------------------------------------------------------------------
// Unserialization
//-----------------------------------------------------------------------------
#define GET_TYPE( _type, _val, _fmt ) \
if (!IsText()) \
{ \
if (CheckGet( sizeof(_type) )) \
{ \
_val = *(_type *)PeekGet(); \
m_Get += sizeof(_type); \
} \
else \
{ \
_val = 0; \
} \
} \
else \
{ \
_val = 0; \
Scanf( _fmt, &_val ); \
}
inline char CUtlBuffer::GetChar()
{
char c;
GET_TYPE(char, c, "%c");
return c;
}
inline unsigned char CUtlBuffer::GetUnsignedChar()
{
unsigned char c;
GET_TYPE(unsigned char, c, "%u");
return c;
}
inline short CUtlBuffer::GetShort()
{
short s;
GET_TYPE(short, s, "%d");
return s;
}
inline unsigned short CUtlBuffer::GetUnsignedShort()
{
unsigned short s;
GET_TYPE(unsigned short, s, "%u");
return s;
}
inline int CUtlBuffer::GetInt()
{
int i;
GET_TYPE(int, i, "%d");
return i;
}
inline int CUtlBuffer::GetIntHex()
{
int i;
GET_TYPE(int, i, "%x");
return i;
}
inline unsigned int CUtlBuffer::GetUnsignedInt()
{
unsigned int u;
GET_TYPE(unsigned int, u, "%u");
return u;
}
inline float CUtlBuffer::GetFloat()
{
float f;
GET_TYPE(float, f, "%f");
return f;
}
inline double CUtlBuffer::GetDouble()
{
double d;
GET_TYPE(double, d, "%f");
return d;
}
//-----------------------------------------------------------------------------
// Where am I writing?
//-----------------------------------------------------------------------------
inline int CUtlBuffer::TellPut() const
{
return m_Put;
}
//-----------------------------------------------------------------------------
// What am I reading?
//-----------------------------------------------------------------------------
inline void* CUtlBuffer::PeekPut(int offset)
{
return &m_Memory[m_Put + offset];
}
//-----------------------------------------------------------------------------
// Various put methods
//-----------------------------------------------------------------------------
#define PUT_TYPE( _type, _val, _fmt ) \
if (!IsText()) \
{ \
if (CheckPut( sizeof(_type) )) \
{ \
*(_type *)PeekPut() = _val; \
m_Put += sizeof(_type); \
} \
} \
else \
{ \
Printf( _fmt, _val ); \
}
inline void CUtlBuffer::PutChar(char c)
{
PUT_TYPE(char, c, "%c");
}
inline void CUtlBuffer::PutUnsignedChar(unsigned char c)
{
PUT_TYPE(unsigned char, c, "%u");
}
inline void CUtlBuffer::PutShort(short s)
{
PUT_TYPE(short, s, "%d");
}
inline void CUtlBuffer::PutUnsignedShort(unsigned short s)
{
PUT_TYPE(unsigned short, s, "%u");
}
inline void CUtlBuffer::PutInt(int i)
{
PUT_TYPE(int, i, "%d");
}
inline void CUtlBuffer::PutUnsignedInt(unsigned int u)
{
PUT_TYPE(unsigned int, u, "%u");
}
inline void CUtlBuffer::PutFloat(float f)
{
PUT_TYPE(float, f, "%f");
}
inline void CUtlBuffer::PutDouble(double d)
{
PUT_TYPE(double, d, "%f");
}
//-----------------------------------------------------------------------------
// Buffer base and size
//-----------------------------------------------------------------------------
inline void const* CUtlBuffer::Base() const
{
return m_Memory.Base();
}
inline void* CUtlBuffer::Base()
{
return m_Memory.Base();
}
inline int CUtlBuffer::Size() const
{
return m_Memory.NumAllocated();
}
#endif // UTLBUFFER_H