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.

420 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include <string.h>
  8. #include <assert.h>
  9. #include "msgbuffer.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include <tier0/memdbgon.h>
  12. #pragma warning(disable: 4244) // warning C4244: '=' : conversion from 'int' to 'unsigned char', possible loss of data
  13. //-----------------------------------------------------------------------------
  14. // Purpose: Allocate message buffer
  15. // Input : *buffername -
  16. // *ef -
  17. //-----------------------------------------------------------------------------
  18. CMsgBuffer::CMsgBuffer( const char *buffername, void (*ef)( const char *fmt, ... ) /*= NULL*/ )
  19. {
  20. m_pszBufferName = buffername;
  21. m_pfnErrorFunc = ef;
  22. m_bAllowOverflow = false; // if false, Error
  23. m_bOverFlowed = false; // set to true if the buffer size failed
  24. m_nMaxSize = NET_MAXMESSAGE;
  25. m_nPushedCount = 0;
  26. m_bPushed = false;
  27. m_nReadCount = 0;
  28. m_bBadRead = false;
  29. Clear();
  30. }
  31. //-----------------------------------------------------------------------------
  32. // Purpose:
  33. //-----------------------------------------------------------------------------
  34. CMsgBuffer::~CMsgBuffer( void )
  35. {
  36. }
  37. //-----------------------------------------------------------------------------
  38. // Purpose: Temporarily remember the read position so we can reset it
  39. //-----------------------------------------------------------------------------
  40. void CMsgBuffer::Push( void )
  41. {
  42. // ??? Allow multiple pushes without matching pops ???
  43. assert( !m_bPushed );
  44. m_nPushedCount = m_nReadCount;
  45. m_bPushed = true;
  46. }
  47. //-----------------------------------------------------------------------------
  48. // Purpose:
  49. //-----------------------------------------------------------------------------
  50. void CMsgBuffer::Pop( void )
  51. {
  52. assert( m_bPushed );
  53. m_nReadCount = m_nPushedCount;
  54. m_bPushed = false;
  55. }
  56. //-----------------------------------------------------------------------------
  57. // Purpose:
  58. // Input : allowed -
  59. //-----------------------------------------------------------------------------
  60. void CMsgBuffer::SetOverflow( bool allowed )
  61. {
  62. m_bAllowOverflow = allowed;
  63. }
  64. //-----------------------------------------------------------------------------
  65. // Purpose:
  66. // Output : int
  67. //-----------------------------------------------------------------------------
  68. int CMsgBuffer::GetMaxSize( void )
  69. {
  70. return m_nMaxSize;
  71. }
  72. //-----------------------------------------------------------------------------
  73. // Purpose:
  74. // Output : void *
  75. //-----------------------------------------------------------------------------
  76. void * CMsgBuffer::GetData( void )
  77. {
  78. return m_rgData;
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Purpose:
  82. // Output : int
  83. //-----------------------------------------------------------------------------
  84. int CMsgBuffer::GetCurSize( void )
  85. {
  86. return m_nCurSize;
  87. }
  88. //-----------------------------------------------------------------------------
  89. // Purpose:
  90. // Output : int
  91. //-----------------------------------------------------------------------------
  92. int CMsgBuffer::GetReadCount( void )
  93. {
  94. return m_nReadCount;
  95. }
  96. //-----------------------------------------------------------------------------
  97. // Purpose: data accessor
  98. //-----------------------------------------------------------------------------
  99. void CMsgBuffer::SetTime(float time)
  100. {
  101. m_fRecvTime = time;
  102. }
  103. //-----------------------------------------------------------------------------
  104. // Purpose: data accessor
  105. //-----------------------------------------------------------------------------
  106. float CMsgBuffer::GetTime()
  107. {
  108. return m_fRecvTime;
  109. }
  110. //-----------------------------------------------------------------------------
  111. // Purpose: data accessor
  112. //-----------------------------------------------------------------------------
  113. void CMsgBuffer::SetNetAddress(netadr_t &adr)
  114. {
  115. m_NetAddr = adr;
  116. }
  117. //-----------------------------------------------------------------------------
  118. // Purpose: data accessor
  119. //-----------------------------------------------------------------------------
  120. netadr_t &CMsgBuffer::GetNetAddress()
  121. {
  122. return m_NetAddr;
  123. }
  124. //-----------------------------------------------------------------------------
  125. // Purpose:
  126. //-----------------------------------------------------------------------------
  127. void CMsgBuffer::WriteByte( int c )
  128. {
  129. unsigned char *buf;
  130. buf = (unsigned char *)GetSpace( 1 );
  131. buf[0] = c;
  132. }
  133. //-----------------------------------------------------------------------------
  134. // Purpose:
  135. // Input : c -
  136. //-----------------------------------------------------------------------------
  137. void CMsgBuffer::WriteShort ( int c )
  138. {
  139. unsigned char *buf;
  140. buf = (unsigned char *)GetSpace( 2 );
  141. buf[0] = c&0xff;
  142. buf[1] = c>>8;
  143. }
  144. //-----------------------------------------------------------------------------
  145. // Purpose:
  146. // Input : c -
  147. //-----------------------------------------------------------------------------
  148. void CMsgBuffer::WriteLong (int c)
  149. {
  150. unsigned char *buf;
  151. buf = (unsigned char *)GetSpace( 4 );
  152. buf[0] = c&0xff;
  153. buf[1] = (c>>8)&0xff;
  154. buf[2] = (c>>16)&0xff;
  155. buf[3] = c>>24;
  156. }
  157. //-----------------------------------------------------------------------------
  158. // Purpose:
  159. // Input : f -
  160. //-----------------------------------------------------------------------------
  161. void CMsgBuffer::WriteFloat (float f)
  162. {
  163. union
  164. {
  165. float f;
  166. int l;
  167. } dat;
  168. dat.f = f;
  169. Write( &dat.l, 4 );
  170. }
  171. //-----------------------------------------------------------------------------
  172. // Purpose:
  173. // Input : *s -
  174. //-----------------------------------------------------------------------------
  175. void CMsgBuffer::WriteString (const char *s)
  176. {
  177. if ( !s )
  178. {
  179. Write ("", 1);
  180. }
  181. else
  182. {
  183. Write ( s, strlen( s ) + 1 );
  184. }
  185. }
  186. //-----------------------------------------------------------------------------
  187. // Purpose:
  188. // Input : iSize -
  189. // *buf -
  190. //-----------------------------------------------------------------------------
  191. void CMsgBuffer::WriteBuf( int iSize, void *buf )
  192. {
  193. if ( !buf )
  194. {
  195. return;
  196. }
  197. Write( buf, iSize );
  198. }
  199. //-----------------------------------------------------------------------------
  200. // Purpose:
  201. //-----------------------------------------------------------------------------
  202. void CMsgBuffer::BeginReading (void)
  203. {
  204. m_nReadCount = 0;
  205. m_bBadRead = false;
  206. }
  207. //-----------------------------------------------------------------------------
  208. // Purpose:
  209. // Output : int CMsgBuffer::ReadByte
  210. //-----------------------------------------------------------------------------
  211. int CMsgBuffer::ReadByte (void)
  212. {
  213. int c;
  214. if ( m_nReadCount + 1 > m_nCurSize )
  215. {
  216. m_bBadRead = true;
  217. return -1;
  218. }
  219. c = ( unsigned char )m_rgData[ m_nReadCount ];
  220. m_nReadCount++;
  221. return c;
  222. }
  223. //-----------------------------------------------------------------------------
  224. // Purpose:
  225. // Output : int CMsgBuffer::ReadShort
  226. //-----------------------------------------------------------------------------
  227. int CMsgBuffer::ReadShort (void)
  228. {
  229. int c;
  230. if ( m_nReadCount + 2 > m_nCurSize )
  231. {
  232. m_bBadRead = true;
  233. return -1;
  234. }
  235. c = (short)(m_rgData[m_nReadCount] + (m_rgData[m_nReadCount+1]<<8));
  236. m_nReadCount += 2;
  237. return c;
  238. }
  239. //-----------------------------------------------------------------------------
  240. // Purpose:
  241. // Output : int CMsgBuffer::ReadLong
  242. //-----------------------------------------------------------------------------
  243. int CMsgBuffer::ReadLong (void)
  244. {
  245. int c;
  246. if (m_nReadCount+4 > m_nCurSize)
  247. {
  248. m_bBadRead = true;
  249. return -1;
  250. }
  251. c = m_rgData[m_nReadCount]
  252. + (m_rgData[m_nReadCount+1]<<8)
  253. + (m_rgData[m_nReadCount+2]<<16)
  254. + (m_rgData[m_nReadCount+3]<<24);
  255. m_nReadCount += 4;
  256. return c;
  257. }
  258. //-----------------------------------------------------------------------------
  259. // Purpose:
  260. // Output : float CMsgBuffer::ReadFloat
  261. //-----------------------------------------------------------------------------
  262. float CMsgBuffer::ReadFloat (void)
  263. {
  264. union
  265. {
  266. unsigned char b[4];
  267. float f;
  268. } dat;
  269. dat.b[0] = m_rgData[m_nReadCount];
  270. dat.b[1] = m_rgData[m_nReadCount+1];
  271. dat.b[2] = m_rgData[m_nReadCount+2];
  272. dat.b[3] = m_rgData[m_nReadCount+3];
  273. m_nReadCount += 4;
  274. return dat.f;
  275. }
  276. //-----------------------------------------------------------------------------
  277. // Purpose:
  278. // Input : iSize -
  279. // *pbuf -
  280. // Output : int
  281. //-----------------------------------------------------------------------------
  282. int CMsgBuffer::ReadBuf( int iSize, void *pbuf )
  283. {
  284. if (m_nReadCount + iSize > m_nCurSize)
  285. {
  286. m_bBadRead = true;
  287. return -1;
  288. }
  289. memcpy( pbuf, &m_rgData[m_nReadCount], iSize );
  290. m_nReadCount += iSize;
  291. return 1;
  292. }
  293. //-----------------------------------------------------------------------------
  294. // Purpose:
  295. // Output : char *
  296. //-----------------------------------------------------------------------------
  297. char *CMsgBuffer::ReadString (void)
  298. {
  299. static char string[ NET_MAXMESSAGE ];
  300. int l,c;
  301. l = 0;
  302. do
  303. {
  304. c = (char)ReadByte();
  305. if ( c == -1 || c == 0 )
  306. break;
  307. string[l] = c;
  308. l++;
  309. } while ( l < sizeof(string)-1 );
  310. string[ l ] = 0;
  311. return string;
  312. }
  313. //-----------------------------------------------------------------------------
  314. // Purpose:
  315. //-----------------------------------------------------------------------------
  316. void CMsgBuffer::Clear( void )
  317. {
  318. m_nCurSize = 0;
  319. m_bOverFlowed = false;
  320. m_nReadCount = 0;
  321. m_bBadRead = false;
  322. memset( m_rgData, 0, sizeof( m_rgData ) );
  323. }
  324. //-----------------------------------------------------------------------------
  325. // Purpose:
  326. // Input : length -
  327. //-----------------------------------------------------------------------------
  328. void *CMsgBuffer::GetSpace( int length )
  329. {
  330. void *d;
  331. if (m_nCurSize + length > m_nMaxSize)
  332. {
  333. if ( !m_bAllowOverflow )
  334. {
  335. if ( m_pfnErrorFunc )
  336. {
  337. ( *m_pfnErrorFunc )( "CMsgBuffer(%s), no room for %i bytes, %i / %i already in use\n",
  338. m_pszBufferName, length, m_nCurSize, m_nMaxSize );
  339. }
  340. return NULL;
  341. }
  342. if (length > m_nMaxSize)
  343. {
  344. if ( m_pfnErrorFunc )
  345. {
  346. ( *m_pfnErrorFunc )( "CMsgBuffer(%s), no room for %i bytes, %i is max\n",
  347. m_pszBufferName, length, m_nMaxSize );
  348. }
  349. return NULL;
  350. }
  351. m_bOverFlowed = true;
  352. Clear();
  353. }
  354. d = m_rgData + m_nCurSize;
  355. m_nCurSize += length;
  356. return d;
  357. }
  358. //-----------------------------------------------------------------------------
  359. // Purpose:
  360. // Input : *m_rgData -
  361. // length -
  362. //-----------------------------------------------------------------------------
  363. void CMsgBuffer::Write(const void *m_rgData, int length)
  364. {
  365. memcpy( GetSpace(length), m_rgData, length );
  366. }