Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
6.8 KiB

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