1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Generic named data buffer, declaration and implementation
//
//=============================================================================
#ifndef UTLMSGBUFFER_H
#define UTLMSGBUFFER_H
#ifdef _WIN32
#pragma once
#endif
#include "UtlMemory.h"
#pragma warning(disable: 4244) // warning C4244: '=' : conversion from 'int' to 'short', possible loss of data
//-----------------------------------------------------------------------------
// Purpose: Generic named data buffer
//-----------------------------------------------------------------------------
class CUtlMsgBuffer
{
public:
CUtlMsgBuffer(unsigned short msgID, int initialSize);
CUtlMsgBuffer(unsigned short msgID, void const *data, int dataSize);
~CUtlMsgBuffer();
unsigned short GetMsgID() const { return m_iMsgID; }
void SetMsgID(unsigned short msgID) { m_iMsgID = msgID; }
// read functions
bool ReadInt(const char *name, int &data);
bool ReadUInt(const char *name, unsigned int &data);
bool ReadString(const char *name, char *data, int dataBufferSize);
bool ReadBuffer(const char *name, CUtlMsgBuffer &buffer);
// returns number of bytes read, 0 on failure
int ReadBlob(const char *name, void *data, int dataBufferSize);
// reads out the next variable available in the buffer
// fills out parameters with var details and data
// returns false if no more vars available
bool ReadNextVar(char name[32], bool &stringData, void *data, int &dataSize);
// write functions
void WriteInt(const char *name, int data);
void WriteUInt(const char *name, unsigned int data);
void WriteString(const char *name, const char *data);
void WriteBlob(const char *name, const void *data, int dataSize);
void WriteBuffer(const char *name, const CUtlMsgBuffer *buffer);
// returns a pointer to the data buffer, and its size, of the specified variable
void *FindVar(const char *name, int &dataSizeOut);
// pads the buffer to the specified boundary (in bytes)
void PadBuffer(int boundary);
// makes sure the message has this much space allocated
void EnsureCapacity(int dataSize);
// returns the number of bytes used by the message
int DataSize() const;
// returns a pointer to the base data
void *Base();
// returns a const pointer to the base data
const void *Base() const;
// advances the write pointer - used when you write directly into the buffer
void SetWritePos(int size);
CUtlMsgBuffer& Copy(const CUtlMsgBuffer &rhs);
// copy constructor
CUtlMsgBuffer(const CUtlMsgBuffer &rhs)
{
m_iMsgID = rhs.m_iMsgID;
m_iWritePos = rhs.m_iWritePos;
m_iReadPos = rhs.m_iReadPos;
m_iNextVarPos = rhs.m_iNextVarPos;
m_Memory.EnsureCapacity(rhs.m_Memory.NumAllocated());
if ( rhs.m_Memory.NumAllocated() > 0 )
{
memcpy(Base(), rhs.Base(), rhs.m_Memory.NumAllocated());
}
}
private:
bool Read(void *buffer, int readAmount);
bool ReadUntilNull(void *buffer, int bufferSize);
void Write(void const *data, int size);
CUtlMemory<char> m_Memory;
unsigned short m_iMsgID;
short m_iWritePos; // position in buffer we are currently writing to
short m_iReadPos; // current reading position
short m_iNextVarPos; // a guess at which variable is most likely to be read next
};
//-----------------------------------------------------------------------------
// Purpose: returns the number of bytes used by the message
//-----------------------------------------------------------------------------
inline int CUtlMsgBuffer::DataSize() const
{
// return the highest read/write mark
if (m_iWritePos > m_iReadPos)
return m_iWritePos;
return m_iReadPos;
}
//-----------------------------------------------------------------------------
// Purpose: returns a pointer to the base data
//-----------------------------------------------------------------------------
inline void *CUtlMsgBuffer::Base()
{
return &m_Memory[0];
}
//-----------------------------------------------------------------------------
// Purpose: returns a pointer to the base data
//-----------------------------------------------------------------------------
inline const void *CUtlMsgBuffer::Base() const
{
return &m_Memory[0];
}
//-----------------------------------------------------------------------------
// Purpose: ensures capacity
//-----------------------------------------------------------------------------
inline void CUtlMsgBuffer::EnsureCapacity(int dataSize)
{
m_Memory.EnsureCapacity(dataSize);
}
//-----------------------------------------------------------------------------
// Purpose: pads the buffer to the specified boundary (in bytes)
//-----------------------------------------------------------------------------
inline void CUtlMsgBuffer::PadBuffer(int boundary)
{
// pad the buffer to be the right size for encryption
int pad = (boundary - (DataSize() % boundary));
Write("\0\0\0\0\0\0\0\0\0\0\0\0", pad);
}
//-----------------------------------------------------------------------------
// Purpose: Reads in a named 4-byte int, returns true on sucess, false on failure
//-----------------------------------------------------------------------------
inline bool CUtlMsgBuffer::ReadInt(const char *name, int &data)
{
return (ReadBlob(name, &data, 4) == 4);
}
//-----------------------------------------------------------------------------
// Purpose: Reads in a named 4-byte unsigned int, returns true on sucess, false on failure
//-----------------------------------------------------------------------------
inline bool CUtlMsgBuffer::ReadUInt(const char *name, unsigned int &data)
{
return (ReadBlob(name, &data, 4) == 4);
}
//-----------------------------------------------------------------------------
// Purpose: Reads in a named variable length character string
// returns true on sucess, false on failure
//-----------------------------------------------------------------------------
inline bool CUtlMsgBuffer::ReadString(const char *name, char *data, int dataBufferSize)
{
return (ReadBlob(name, data, dataBufferSize) > 0);
}
//-----------------------------------------------------------------------------
// Purpose: Writes out an integer to the message
//-----------------------------------------------------------------------------
inline void CUtlMsgBuffer::WriteInt(const char *name, int data)
{
WriteBlob(name, &data, 4);
}
//-----------------------------------------------------------------------------
// Purpose: Writes out an unsigned integer to the message
//-----------------------------------------------------------------------------
inline void CUtlMsgBuffer::WriteUInt(const char *name, unsigned int data)
{
WriteBlob(name, &data, 4);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
inline void CUtlMsgBuffer::SetWritePos(int size)
{
m_iWritePos = size;
}
#endif // UTLMSGBUFFER_H
|