Counter Strike : Global Offensive Source Code
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.

1448 lines
38 KiB

  1. //====== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. =======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. // Serialization/unserialization buffer
  8. //=============================================================================//
  9. #ifndef UTLBUFFER_H
  10. #define UTLBUFFER_H
  11. #ifdef _WIN32
  12. #pragma once
  13. #endif
  14. #include "unitlib/unitlib.h" // just here for tests - remove before checking in!!!
  15. #include "tier1/utlmemory.h"
  16. #include "tier1/byteswap.h"
  17. #include <stdarg.h>
  18. //-----------------------------------------------------------------------------
  19. // Forward declarations
  20. //-----------------------------------------------------------------------------
  21. struct characterset_t;
  22. //-----------------------------------------------------------------------------
  23. // Description of character conversions for string output
  24. // Here's an example of how to use the macros to define a character conversion
  25. // BEGIN_CHAR_CONVERSION( CStringConversion, '\\' )
  26. // { '\n', "n" },
  27. // { '\t', "t" }
  28. // END_CHAR_CONVERSION( CStringConversion, '\\' )
  29. //-----------------------------------------------------------------------------
  30. class CUtlCharConversion
  31. {
  32. public:
  33. struct ConversionArray_t
  34. {
  35. char m_nActualChar;
  36. char *m_pReplacementString;
  37. };
  38. CUtlCharConversion( char nEscapeChar, const char *pDelimiter, int nCount, ConversionArray_t *pArray );
  39. char GetEscapeChar() const;
  40. const char *GetDelimiter() const;
  41. int GetDelimiterLength() const;
  42. const char *GetConversionString( char c ) const;
  43. int GetConversionLength( char c ) const;
  44. int MaxConversionLength() const;
  45. // Finds a conversion for the passed-in string, returns length
  46. virtual char FindConversion( const char *pString, int *pLength );
  47. protected:
  48. struct ConversionInfo_t
  49. {
  50. int m_nLength;
  51. char *m_pReplacementString;
  52. };
  53. char m_nEscapeChar;
  54. const char *m_pDelimiter;
  55. int m_nDelimiterLength;
  56. int m_nCount;
  57. int m_nMaxConversionLength;
  58. char m_pList[256];
  59. ConversionInfo_t m_pReplacements[256];
  60. };
  61. #define BEGIN_CHAR_CONVERSION( _name, _delimiter, _escapeChar ) \
  62. static CUtlCharConversion::ConversionArray_t s_pConversionArray ## _name[] = {
  63. #define END_CHAR_CONVERSION( _name, _delimiter, _escapeChar ) \
  64. }; \
  65. CUtlCharConversion _name( _escapeChar, _delimiter, sizeof( s_pConversionArray ## _name ) / sizeof( CUtlCharConversion::ConversionArray_t ), s_pConversionArray ## _name );
  66. #define BEGIN_CUSTOM_CHAR_CONVERSION( _className, _name, _delimiter, _escapeChar ) \
  67. static CUtlCharConversion::ConversionArray_t s_pConversionArray ## _name[] = {
  68. #define END_CUSTOM_CHAR_CONVERSION( _className, _name, _delimiter, _escapeChar ) \
  69. }; \
  70. _className _name( _escapeChar, _delimiter, sizeof( s_pConversionArray ## _name ) / sizeof( CUtlCharConversion::ConversionArray_t ), s_pConversionArray ## _name );
  71. //-----------------------------------------------------------------------------
  72. // Character conversions for C strings
  73. //-----------------------------------------------------------------------------
  74. CUtlCharConversion *GetCStringCharConversion();
  75. //-----------------------------------------------------------------------------
  76. // Character conversions for quoted strings, with no escape sequences
  77. //-----------------------------------------------------------------------------
  78. CUtlCharConversion *GetNoEscCharConversion();
  79. //-----------------------------------------------------------------------------
  80. // Macro to set overflow functions easily
  81. //-----------------------------------------------------------------------------
  82. #define SetUtlBufferOverflowFuncs( _get, _put ) \
  83. SetOverflowFuncs( static_cast <UtlBufferOverflowFunc_t>( _get ), static_cast <UtlBufferOverflowFunc_t>( _put ) )
  84. typedef unsigned short ushort;
  85. template < class A >
  86. static const char *GetFmtStr( int nRadix = 10, bool bPrint = true ) { Assert( 0 ); return ""; }
  87. #if defined( LINUX ) || defined( __clang__ ) || ( defined( _MSC_VER ) && _MSC_VER >= 1900 )
  88. template <> const char *GetFmtStr< short > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%hd"; }
  89. template <> const char *GetFmtStr< ushort > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%hu"; }
  90. template <> const char *GetFmtStr< int > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%d"; }
  91. template <> const char *GetFmtStr< uint > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 || nRadix == 16 ); return nRadix == 16 ? "%x" : "%u"; }
  92. template <> const char *GetFmtStr< int64 > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%lld"; }
  93. template <> const char *GetFmtStr< float > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%f"; }
  94. template <> const char *GetFmtStr< double > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return bPrint ? "%.15lf" : "%lf"; } // force Printf to print DBL_DIG=15 digits of precision for doubles - defaults to FLT_DIG=6
  95. #else
  96. template <> static const char *GetFmtStr< short > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%hd"; }
  97. template <> static const char *GetFmtStr< ushort > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%hu"; }
  98. template <> static const char *GetFmtStr< int > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%d"; }
  99. template <> static const char *GetFmtStr< uint > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 || nRadix == 16 ); return nRadix == 16 ? "%x" : "%u"; }
  100. template <> static const char *GetFmtStr< int64 > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%lld"; }
  101. template <> static const char *GetFmtStr< float > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return "%f"; }
  102. template <> static const char *GetFmtStr< double > ( int nRadix, bool bPrint ) { Assert( nRadix == 10 ); return bPrint ? "%.15lf" : "%lf"; } // force Printf to print DBL_DIG=15 digits of precision for doubles - defaults to FLT_DIG=6
  103. #endif
  104. //-----------------------------------------------------------------------------
  105. // Command parsing..
  106. //-----------------------------------------------------------------------------
  107. class CUtlBuffer
  108. {
  109. // Brian has on his todo list to revisit this as there are issues in some cases with CUtlVector using operator = instead of copy construtor in InsertMultiple, etc.
  110. // The unsafe case is something like this:
  111. // CUtlVector< CUtlBuffer > vecFoo;
  112. //
  113. // CUtlBuffer buf;
  114. // buf.Put( xxx );
  115. // vecFoo.Insert( buf );
  116. //
  117. // This will cause memory corruption when vecFoo is cleared
  118. //
  119. //private:
  120. // // Disallow copying
  121. // CUtlBuffer( const CUtlBuffer & );// { Assert( 0 ); }
  122. // CUtlBuffer &operator=( const CUtlBuffer & );// { Assert( 0 ); return *this; }
  123. public:
  124. enum SeekType_t
  125. {
  126. SEEK_HEAD = 0,
  127. SEEK_CURRENT,
  128. SEEK_TAIL
  129. };
  130. // flags
  131. enum BufferFlags_t
  132. {
  133. TEXT_BUFFER = 0x1, // Describes how get + put work (as strings, or binary)
  134. EXTERNAL_GROWABLE = 0x2, // This is used w/ external buffers and causes the utlbuf to switch to reallocatable memory if an overflow happens when Putting.
  135. CONTAINS_CRLF = 0x4, // For text buffers only, does this contain \n or \n\r?
  136. READ_ONLY = 0x8, // For external buffers; prevents null termination from happening.
  137. AUTO_TABS_DISABLED = 0x10, // Used to disable/enable push/pop tabs
  138. };
  139. // Overflow functions when a get or put overflows
  140. typedef bool (CUtlBuffer::*UtlBufferOverflowFunc_t)( int nSize );
  141. // Constructors for growable + external buffers for serialization/unserialization
  142. CUtlBuffer( int growSize = 0, int initSize = 0, int nFlags = 0 );
  143. CUtlBuffer( const void* pBuffer, int size, int nFlags = 0 );
  144. // This one isn't actually defined so that we catch contructors that are trying to pass a bool in as the third param.
  145. CUtlBuffer( const void *pBuffer, int size, bool crap ) = delete;
  146. // UtlBuffer objects should not be copyable; we do a slow copy if you use this but it asserts.
  147. // (REI: I'd like to delete these but we have some python bindings that currently rely on being able to copy these objects)
  148. CUtlBuffer( const CUtlBuffer& ); // = delete;
  149. CUtlBuffer& operator= ( const CUtlBuffer& ); // = delete;
  150. #if VALVE_CPP11
  151. // UtlBuffer is non-copyable (same as CUtlMemory), but it is moveable. We would like to declare these with '= default'
  152. // but unfortunately VS2013 isn't fully C++11 compliant, so we have to manually declare these in the boilerplate way.
  153. CUtlBuffer( CUtlBuffer&& moveFrom ); // = default;
  154. CUtlBuffer& operator= ( CUtlBuffer&& moveFrom ); // = default;
  155. #endif
  156. unsigned char GetFlags() const;
  157. // NOTE: This will assert if you attempt to recast it in a way that
  158. // is not compatible. The only valid conversion is binary-> text w/CRLF
  159. void SetBufferType( bool bIsText, bool bContainsCRLF );
  160. // Makes sure we've got at least this much memory
  161. void EnsureCapacity( int num );
  162. // Access for direct read into buffer
  163. void * AccessForDirectRead( int nBytes );
  164. // Attaches the buffer to external memory....
  165. void SetExternalBuffer( void* pMemory, int nSize, int nInitialPut, int nFlags = 0 );
  166. bool IsExternallyAllocated() const;
  167. void AssumeMemory( void *pMemory, int nSize, int nInitialPut, int nFlags = 0 );
  168. void *Detach();
  169. void* DetachMemory();
  170. // copies data from another buffer
  171. void CopyBuffer( const CUtlBuffer &buffer );
  172. void CopyBuffer( const void *pubData, int cubData );
  173. void Swap( CUtlBuffer &buf );
  174. void Swap( CUtlMemory<uint8> &mem );
  175. FORCEINLINE void ActivateByteSwappingIfBigEndian( void )
  176. {
  177. if ( ( IsX360() || IsPS3() ) )
  178. ActivateByteSwapping( true );
  179. }
  180. // Controls endian-ness of binary utlbufs - default matches the current platform
  181. void ActivateByteSwapping( bool bActivate );
  182. void SetBigEndian( bool bigEndian );
  183. bool IsBigEndian( void );
  184. // Resets the buffer; but doesn't free memory
  185. void Clear();
  186. // Clears out the buffer; frees memory
  187. void Purge();
  188. // Dump the buffer to stdout
  189. void Spew( );
  190. // Read stuff out.
  191. // Binary mode: it'll just read the bits directly in, and characters will be
  192. // read for strings until a null character is reached.
  193. // Text mode: it'll parse the file, turning text #s into real numbers.
  194. // GetString will read a string until a space is reached
  195. char GetChar( );
  196. unsigned char GetUnsignedChar( );
  197. short GetShort( );
  198. unsigned short GetUnsignedShort( );
  199. int GetInt( );
  200. int64 GetInt64( );
  201. unsigned int GetIntHex( );
  202. unsigned int GetUnsignedInt( );
  203. uint64 GetUnsignedInt64( );
  204. float GetFloat( );
  205. double GetDouble( );
  206. void * GetPtr();
  207. void GetString( char* pString, int nMaxChars );
  208. bool Get( void* pMem, int size );
  209. void GetLine( char* pLine, int nMaxChars );
  210. // Used for getting objects that have a byteswap datadesc defined
  211. template <typename T> void GetObjects( T *dest, int count = 1 );
  212. // This will get at least 1 byte and up to nSize bytes.
  213. // It will return the number of bytes actually read.
  214. int GetUpTo( void *pMem, int nSize );
  215. // This version of GetString converts \" to \\ and " to \, etc.
  216. // It also reads a " at the beginning and end of the string
  217. void GetDelimitedString( CUtlCharConversion *pConv, char *pString, int nMaxChars = 0 );
  218. char GetDelimitedChar( CUtlCharConversion *pConv );
  219. // This will return the # of characters of the string about to be read out
  220. // NOTE: The count will *include* the terminating 0!!
  221. // In binary mode, it's the number of characters until the next 0
  222. // In text mode, it's the number of characters until the next space.
  223. int PeekStringLength();
  224. // This version of PeekStringLength converts \" to \\ and " to \, etc.
  225. // It also reads a " at the beginning and end of the string
  226. // NOTE: The count will *include* the terminating 0!!
  227. // In binary mode, it's the number of characters until the next 0
  228. // In text mode, it's the number of characters between "s (checking for \")
  229. // Specifying false for bActualSize will return the pre-translated number of characters
  230. // including the delimiters and the escape characters. So, \n counts as 2 characters when bActualSize == false
  231. // and only 1 character when bActualSize == true
  232. int PeekDelimitedStringLength( CUtlCharConversion *pConv, bool bActualSize = true );
  233. // Just like scanf, but doesn't work in binary mode
  234. int Scanf( SCANF_FORMAT_STRING const char* pFmt, ... );
  235. int VaScanf( const char* pFmt, va_list list );
  236. // Eats white space, advances Get index
  237. void EatWhiteSpace();
  238. // Eats C++ style comments
  239. bool EatCPPComment();
  240. // (For text buffers only)
  241. // Parse a token from the buffer:
  242. // Grab all text that lies between a starting delimiter + ending delimiter
  243. // (skipping whitespace that leads + trails both delimiters).
  244. // If successful, the get index is advanced and the function returns true,
  245. // otherwise the index is not advanced and the function returns false.
  246. bool ParseToken( const char *pStartingDelim, const char *pEndingDelim, char* pString, int nMaxLen );
  247. // Advance the get index until after the particular string is found
  248. // Do not eat whitespace before starting. Return false if it failed
  249. // String test is case-insensitive.
  250. bool GetToken( const char *pToken );
  251. // Parses the next token, given a set of character breaks to stop at
  252. // Returns the length of the token parsed in bytes (-1 if none parsed)
  253. int ParseToken( characterset_t *pBreaks, char *pTokenBuf, int nMaxLen, bool bParseComments = true );
  254. // Write stuff in
  255. // Binary mode: it'll just write the bits directly in, and strings will be
  256. // written with a null terminating character
  257. // Text mode: it'll convert the numbers to text versions
  258. // PutString will not write a terminating character
  259. void PutChar( char c );
  260. void PutUnsignedChar( unsigned char uc );
  261. void PutShort( short s );
  262. void PutUnsignedShort( unsigned short us );
  263. void PutInt( int i );
  264. void PutInt64( int64 i );
  265. void PutUnsignedInt( unsigned int u );
  266. void PutUnsignedInt64( uint64 u );
  267. void PutFloat( float f );
  268. void PutDouble( double d );
  269. void PutPtr( void * ); // Writes the pointer, not the pointed to
  270. void PutString( const char* pString );
  271. void Put( const void* pMem, int size );
  272. // Used for putting objects that have a byteswap datadesc defined
  273. template <typename T> void PutObjects( T *src, int count = 1 );
  274. // This version of PutString converts \ to \\ and " to \", etc.
  275. // It also places " at the beginning and end of the string
  276. void PutDelimitedString( CUtlCharConversion *pConv, const char *pString );
  277. void PutDelimitedChar( CUtlCharConversion *pConv, char c );
  278. // Just like printf, writes a terminating zero in binary mode
  279. void Printf( PRINTF_FORMAT_STRING const char* pFmt, ... ) FMTFUNCTION( 2, 3 );
  280. void VaPrintf( const char* pFmt, va_list list );
  281. // What am I writing (put)/reading (get)?
  282. void* PeekPut( int offset = 0 );
  283. const void* PeekGet( int offset = 0 ) const;
  284. const void* PeekGet( int nMaxSize, int nOffset );
  285. // Where am I writing (put)/reading (get)?
  286. int TellPut( ) const;
  287. int TellGet( ) const;
  288. // What's the most I've ever written?
  289. int TellMaxPut( ) const;
  290. // How many bytes remain to be read?
  291. // NOTE: This is not accurate for streaming text files; it overshoots
  292. int GetBytesRemaining() const;
  293. // Change where I'm writing (put)/reading (get)
  294. void SeekPut( SeekType_t type, int offset );
  295. void SeekGet( SeekType_t type, int offset );
  296. // Buffer base
  297. const void* Base() const;
  298. void* Base();
  299. // memory allocation size, does *not* reflect size written or read,
  300. // use TellPut or TellGet for that
  301. int Size() const;
  302. // Am I a text buffer?
  303. bool IsText() const;
  304. // Can I grow if I'm externally allocated?
  305. bool IsGrowable() const;
  306. // Am I valid? (overflow or underflow error), Once invalid it stays invalid
  307. bool IsValid() const;
  308. // Do I contain carriage return/linefeeds?
  309. bool ContainsCRLF() const;
  310. // Am I read-only
  311. bool IsReadOnly() const;
  312. // Converts a buffer from a CRLF buffer to a CR buffer (and back)
  313. // Returns false if no conversion was necessary (and outBuf is left untouched)
  314. // If the conversion occurs, outBuf will be cleared.
  315. bool ConvertCRLF( CUtlBuffer &outBuf );
  316. // Push/pop pretty-printing tabs
  317. void PushTab();
  318. void PopTab();
  319. // Temporarily disables pretty print
  320. void EnableTabs( bool bEnable );
  321. #if !defined( _GAMECONSOLE )
  322. // Swap my internal memory with another buffer,
  323. // and copy all of its other members
  324. void SwapCopy( CUtlBuffer &other ) ;
  325. #endif
  326. protected:
  327. // error flags
  328. enum
  329. {
  330. PUT_OVERFLOW = 0x1,
  331. GET_OVERFLOW = 0x2,
  332. MAX_ERROR_FLAG = GET_OVERFLOW,
  333. };
  334. void SetOverflowFuncs( UtlBufferOverflowFunc_t getFunc, UtlBufferOverflowFunc_t putFunc );
  335. bool OnPutOverflow( int nSize );
  336. bool OnGetOverflow( int nSize );
  337. protected:
  338. // Checks if a get/put is ok
  339. bool CheckPut( int size );
  340. bool CheckGet( int size );
  341. // NOTE: Pass in nPut here even though it is just a copy of m_Put. This is almost always called immediately
  342. // after modifying m_Put and this lets it stay in a register
  343. void AddNullTermination( int nPut );
  344. // Methods to help with pretty-printing
  345. bool WasLastCharacterCR();
  346. void PutTabs();
  347. // Help with delimited stuff
  348. char GetDelimitedCharInternal( CUtlCharConversion *pConv );
  349. void PutDelimitedCharInternal( CUtlCharConversion *pConv, char c );
  350. // Default overflow funcs
  351. bool PutOverflow( int nSize );
  352. bool GetOverflow( int nSize );
  353. // Does the next bytes of the buffer match a pattern?
  354. bool PeekStringMatch( int nOffset, const char *pString, int nLen );
  355. // Peek size of line to come, check memory bound
  356. int PeekLineLength();
  357. // How much whitespace should I skip?
  358. int PeekWhiteSpace( int nOffset );
  359. // Checks if a peek get is ok
  360. bool CheckPeekGet( int nOffset, int nSize );
  361. // Call this to peek arbitrarily long into memory. It doesn't fail unless
  362. // it can't read *anything* new
  363. bool CheckArbitraryPeekGet( int nOffset, int &nIncrement );
  364. template <typename T> void GetType( T& dest );
  365. template <typename T> void GetTypeBin( T& dest );
  366. template <typename T> bool GetTypeText( T &value, int nRadix = 10 );
  367. template <typename T> void GetObject( T *src );
  368. template <typename T> void PutType( T src );
  369. template <typename T> void PutTypeBin( T src );
  370. template <typename T> void PutObject( T *src );
  371. // be sure to also update the copy constructor
  372. // and SwapCopy() when adding members.
  373. CUtlMemory<unsigned char> m_Memory;
  374. int m_Get;
  375. int m_Put;
  376. unsigned char m_Error;
  377. unsigned char m_Flags;
  378. unsigned char m_Reserved;
  379. #if defined( _GAMECONSOLE )
  380. unsigned char pad;
  381. #endif
  382. int m_nTab;
  383. int m_nMaxPut;
  384. int m_nOffset;
  385. UtlBufferOverflowFunc_t m_GetOverflowFunc;
  386. UtlBufferOverflowFunc_t m_PutOverflowFunc;
  387. CByteswap m_Byteswap;
  388. };
  389. // Stream style output operators for CUtlBuffer
  390. inline CUtlBuffer &operator<<( CUtlBuffer &b, char v )
  391. {
  392. b.PutChar( v );
  393. return b;
  394. }
  395. inline CUtlBuffer &operator<<( CUtlBuffer &b, unsigned char v )
  396. {
  397. b.PutUnsignedChar( v );
  398. return b;
  399. }
  400. inline CUtlBuffer &operator<<( CUtlBuffer &b, short v )
  401. {
  402. b.PutShort( v );
  403. return b;
  404. }
  405. inline CUtlBuffer &operator<<( CUtlBuffer &b, unsigned short v )
  406. {
  407. b.PutUnsignedShort( v );
  408. return b;
  409. }
  410. inline CUtlBuffer &operator<<( CUtlBuffer &b, int v )
  411. {
  412. b.PutInt( v );
  413. return b;
  414. }
  415. inline CUtlBuffer &operator<<( CUtlBuffer &b, unsigned int v )
  416. {
  417. b.PutUnsignedInt( v );
  418. return b;
  419. }
  420. inline CUtlBuffer &operator<<( CUtlBuffer &b, float v )
  421. {
  422. b.PutFloat( v );
  423. return b;
  424. }
  425. inline CUtlBuffer &operator<<( CUtlBuffer &b, double v )
  426. {
  427. b.PutDouble( v );
  428. return b;
  429. }
  430. inline CUtlBuffer &operator<<( CUtlBuffer &b, const char *pv )
  431. {
  432. b.PutString( pv );
  433. return b;
  434. }
  435. inline CUtlBuffer &operator<<( CUtlBuffer &b, const Vector &v )
  436. {
  437. b << v.x << " " << v.y << " " << v.z;
  438. return b;
  439. }
  440. inline CUtlBuffer &operator<<( CUtlBuffer &b, const Vector2D &v )
  441. {
  442. b << v.x << " " << v.y;
  443. return b;
  444. }
  445. class CUtlInplaceBuffer : public CUtlBuffer
  446. {
  447. public:
  448. CUtlInplaceBuffer( int growSize = 0, int initSize = 0, int nFlags = 0 );
  449. //
  450. // Routines returning buffer-inplace-pointers
  451. //
  452. public:
  453. //
  454. // Upon success, determines the line length, fills out the pointer to the
  455. // beginning of the line and the line length, advances the "get" pointer
  456. // offset by the line length and returns "true".
  457. //
  458. // If end of file is reached or upon error returns "false".
  459. //
  460. // Note: the returned length of the line is at least one character because the
  461. // trailing newline characters are also included as part of the line.
  462. //
  463. // Note: the pointer returned points into the local memory of this buffer, in
  464. // case the buffer gets relocated or destroyed the pointer becomes invalid.
  465. //
  466. // e.g.: -------------
  467. //
  468. // char *pszLine;
  469. // int nLineLen;
  470. // while ( pUtlInplaceBuffer->InplaceGetLinePtr( &pszLine, &nLineLen ) )
  471. // {
  472. // ...
  473. // }
  474. //
  475. // -------------
  476. //
  477. // @param ppszInBufferPtr on return points into this buffer at start of line
  478. // @param pnLineLength on return holds num bytes accessible via (*ppszInBufferPtr)
  479. //
  480. // @returns true if line was successfully read
  481. // false when EOF is reached or error occurs
  482. //
  483. bool InplaceGetLinePtr( /* out */ char **ppszInBufferPtr, /* out */ int *pnLineLength );
  484. //
  485. // Determines the line length, advances the "get" pointer offset by the line length,
  486. // replaces the newline character with null-terminator and returns the initial pointer
  487. // to now null-terminated line.
  488. //
  489. // If end of file is reached or upon error returns NULL.
  490. //
  491. // Note: the pointer returned points into the local memory of this buffer, in
  492. // case the buffer gets relocated or destroyed the pointer becomes invalid.
  493. //
  494. // e.g.: -------------
  495. //
  496. // while ( char *pszLine = pUtlInplaceBuffer->InplaceGetLinePtr() )
  497. // {
  498. // ...
  499. // }
  500. //
  501. // -------------
  502. //
  503. // @returns ptr-to-zero-terminated-line if line was successfully read and buffer modified
  504. // NULL when EOF is reached or error occurs
  505. //
  506. char * InplaceGetLinePtr( void );
  507. };
  508. //-----------------------------------------------------------------------------
  509. // Where am I reading?
  510. //-----------------------------------------------------------------------------
  511. inline int CUtlBuffer::TellGet( ) const
  512. {
  513. return m_Get;
  514. }
  515. //-----------------------------------------------------------------------------
  516. // How many bytes remain to be read?
  517. //-----------------------------------------------------------------------------
  518. inline int CUtlBuffer::GetBytesRemaining() const
  519. {
  520. return m_nMaxPut - TellGet();
  521. }
  522. //-----------------------------------------------------------------------------
  523. // What am I reading?
  524. //-----------------------------------------------------------------------------
  525. inline const void* CUtlBuffer::PeekGet( int offset ) const
  526. {
  527. return &m_Memory[ m_Get + offset - m_nOffset ];
  528. }
  529. //-----------------------------------------------------------------------------
  530. // Unserialization
  531. //-----------------------------------------------------------------------------
  532. template <typename T>
  533. inline void CUtlBuffer::GetObject( T *dest )
  534. {
  535. if ( CheckGet( sizeof(T) ) )
  536. {
  537. if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) )
  538. {
  539. *dest = *(T *)PeekGet();
  540. }
  541. else
  542. {
  543. m_Byteswap.SwapFieldsToTargetEndian<T>( dest, (T*)PeekGet() );
  544. }
  545. m_Get += sizeof(T);
  546. }
  547. else
  548. {
  549. Q_memset( &dest, 0, sizeof(T) );
  550. }
  551. }
  552. template <typename T>
  553. inline void CUtlBuffer::GetObjects( T *dest, int count )
  554. {
  555. for ( int i = 0; i < count; ++i, ++dest )
  556. {
  557. GetObject<T>( dest );
  558. }
  559. }
  560. template <typename T>
  561. inline void CUtlBuffer::GetTypeBin( T &dest )
  562. {
  563. if ( CheckGet( sizeof(T) ) )
  564. {
  565. if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) )
  566. {
  567. dest = *(T *)PeekGet();
  568. }
  569. else
  570. {
  571. m_Byteswap.SwapBufferToTargetEndian<T>( &dest, (T*)PeekGet() );
  572. }
  573. m_Get += sizeof(T);
  574. }
  575. else
  576. {
  577. dest = 0;
  578. }
  579. }
  580. template <>
  581. inline void CUtlBuffer::GetTypeBin< float >( float &dest )
  582. {
  583. if ( CheckGet( sizeof( float ) ) )
  584. {
  585. uintp pData = (uintp)PeekGet();
  586. if ( ( IsX360() || IsPS3() ) && ( pData & 0x03 ) )
  587. {
  588. // handle unaligned read
  589. ((unsigned char*)&dest)[0] = ((unsigned char*)pData)[0];
  590. ((unsigned char*)&dest)[1] = ((unsigned char*)pData)[1];
  591. ((unsigned char*)&dest)[2] = ((unsigned char*)pData)[2];
  592. ((unsigned char*)&dest)[3] = ((unsigned char*)pData)[3];
  593. }
  594. else
  595. {
  596. // aligned read
  597. dest = *(float *)pData;
  598. }
  599. if ( m_Byteswap.IsSwappingBytes() )
  600. {
  601. m_Byteswap.SwapBufferToTargetEndian< float >( &dest, &dest );
  602. }
  603. m_Get += sizeof( float );
  604. }
  605. else
  606. {
  607. dest = 0;
  608. }
  609. }
  610. template <>
  611. inline void CUtlBuffer::GetTypeBin< double >( double &dest )
  612. {
  613. if ( CheckGet( sizeof( double ) ) )
  614. {
  615. uintp pData = (uintp)PeekGet();
  616. if ( ( IsX360() || IsPS3() ) && ( pData & 0x07 ) )
  617. {
  618. // handle unaligned read
  619. ((unsigned char*)&dest)[0] = ((unsigned char*)pData)[0];
  620. ((unsigned char*)&dest)[1] = ((unsigned char*)pData)[1];
  621. ((unsigned char*)&dest)[2] = ((unsigned char*)pData)[2];
  622. ((unsigned char*)&dest)[3] = ((unsigned char*)pData)[3];
  623. ((unsigned char*)&dest)[4] = ((unsigned char*)pData)[4];
  624. ((unsigned char*)&dest)[5] = ((unsigned char*)pData)[5];
  625. ((unsigned char*)&dest)[6] = ((unsigned char*)pData)[6];
  626. ((unsigned char*)&dest)[7] = ((unsigned char*)pData)[7];
  627. }
  628. else
  629. {
  630. // aligned read
  631. dest = *(double *)pData;
  632. }
  633. if ( m_Byteswap.IsSwappingBytes() )
  634. {
  635. m_Byteswap.SwapBufferToTargetEndian< double >( &dest, &dest );
  636. }
  637. m_Get += sizeof( double );
  638. }
  639. else
  640. {
  641. dest = 0;
  642. }
  643. }
  644. template < class T >
  645. inline T StringToNumber( char *pString, char **ppEnd, int nRadix )
  646. {
  647. Assert( 0 );
  648. *ppEnd = pString;
  649. return 0;
  650. }
  651. template <>
  652. inline int8 StringToNumber( char *pString, char **ppEnd, int nRadix )
  653. {
  654. return ( int8 )strtol( pString, ppEnd, nRadix );
  655. }
  656. template <>
  657. inline uint8 StringToNumber( char *pString, char **ppEnd, int nRadix )
  658. {
  659. return ( uint8 )strtoul( pString, ppEnd, nRadix );
  660. }
  661. template <>
  662. inline int16 StringToNumber( char *pString, char **ppEnd, int nRadix )
  663. {
  664. return ( int16 )strtol( pString, ppEnd, nRadix );
  665. }
  666. template <>
  667. inline uint16 StringToNumber( char *pString, char **ppEnd, int nRadix )
  668. {
  669. return ( uint16 )strtoul( pString, ppEnd, nRadix );
  670. }
  671. template <>
  672. inline int32 StringToNumber( char *pString, char **ppEnd, int nRadix )
  673. {
  674. return ( int32 )strtol( pString, ppEnd, nRadix );
  675. }
  676. template <>
  677. inline uint32 StringToNumber( char *pString, char **ppEnd, int nRadix )
  678. {
  679. return ( uint32 )strtoul( pString, ppEnd, nRadix );
  680. }
  681. template <>
  682. inline int64 StringToNumber( char *pString, char **ppEnd, int nRadix )
  683. {
  684. #if defined(_PS3) || defined(POSIX)
  685. return ( int64 )strtoll( pString, ppEnd, nRadix );
  686. #else // !_PS3
  687. return ( int64 )_strtoi64( pString, ppEnd, nRadix );
  688. #endif // _PS3
  689. }
  690. template <>
  691. inline float StringToNumber( char *pString, char **ppEnd, int nRadix )
  692. {
  693. NOTE_UNUSED( nRadix );
  694. return ( float )strtod( pString, ppEnd );
  695. }
  696. template <>
  697. inline double StringToNumber( char *pString, char **ppEnd, int nRadix )
  698. {
  699. NOTE_UNUSED( nRadix );
  700. return ( double )strtod( pString, ppEnd );
  701. }
  702. template <typename T>
  703. inline bool CUtlBuffer::GetTypeText( T &value, int nRadix /*= 10*/ )
  704. {
  705. // NOTE: This is not bullet-proof; it assumes numbers are < 128 characters
  706. int nLength = 128;
  707. if ( !CheckArbitraryPeekGet( 0, nLength ) )
  708. {
  709. value = 0;
  710. return false;
  711. }
  712. char *pStart = (char*)PeekGet();
  713. char* pEnd = pStart;
  714. value = StringToNumber< T >( pStart, &pEnd, nRadix );
  715. int nBytesRead = (int)( pEnd - pStart );
  716. if ( nBytesRead == 0 )
  717. return false;
  718. m_Get += nBytesRead;
  719. return true;
  720. }
  721. template <typename T>
  722. inline void CUtlBuffer::GetType( T &dest )
  723. {
  724. if (!IsText())
  725. {
  726. GetTypeBin( dest );
  727. }
  728. else
  729. {
  730. GetTypeText( dest );
  731. }
  732. }
  733. inline char CUtlBuffer::GetChar( )
  734. {
  735. // LEGACY WARNING: this behaves differently than GetUnsignedChar()
  736. char c;
  737. GetTypeBin( c ); // always reads as binary
  738. return c;
  739. }
  740. inline unsigned char CUtlBuffer::GetUnsignedChar( )
  741. {
  742. // LEGACY WARNING: this behaves differently than GetChar()
  743. unsigned char c;
  744. if (!IsText())
  745. {
  746. GetTypeBin( c );
  747. }
  748. else
  749. {
  750. c = ( unsigned char )GetUnsignedShort();
  751. }
  752. return c;
  753. }
  754. inline short CUtlBuffer::GetShort( )
  755. {
  756. short s;
  757. GetType( s );
  758. return s;
  759. }
  760. inline unsigned short CUtlBuffer::GetUnsignedShort( )
  761. {
  762. unsigned short s;
  763. GetType( s );
  764. return s;
  765. }
  766. inline int CUtlBuffer::GetInt( )
  767. {
  768. int i;
  769. GetType( i );
  770. return i;
  771. }
  772. inline int64 CUtlBuffer::GetInt64( )
  773. {
  774. int64 i;
  775. GetType( i );
  776. return i;
  777. }
  778. inline unsigned int CUtlBuffer::GetIntHex( )
  779. {
  780. uint i;
  781. if (!IsText())
  782. {
  783. GetTypeBin( i );
  784. }
  785. else
  786. {
  787. GetTypeText( i, 16 );
  788. }
  789. return i;
  790. }
  791. inline unsigned int CUtlBuffer::GetUnsignedInt( )
  792. {
  793. unsigned int i;
  794. GetType( i );
  795. return i;
  796. }
  797. inline uint64 CUtlBuffer::GetUnsignedInt64()
  798. {
  799. uint64 i;
  800. GetType( i );
  801. return i;
  802. }
  803. inline float CUtlBuffer::GetFloat( )
  804. {
  805. float f;
  806. GetType( f );
  807. return f;
  808. }
  809. inline double CUtlBuffer::GetDouble( )
  810. {
  811. double d;
  812. GetType( d );
  813. return d;
  814. }
  815. inline void *CUtlBuffer::GetPtr( )
  816. {
  817. void *p;
  818. // LEGACY WARNING: in text mode, PutPtr writes 32 bit pointers in hex, while GetPtr reads 32 or 64 bit pointers in decimal
  819. #if !defined(X64BITS) && !defined(PLATFORM_64BITS)
  820. p = ( void* )GetUnsignedInt();
  821. #else
  822. p = ( void* )GetInt64();
  823. #endif
  824. return p;
  825. }
  826. //-----------------------------------------------------------------------------
  827. // Where am I writing?
  828. //-----------------------------------------------------------------------------
  829. inline unsigned char CUtlBuffer::GetFlags() const
  830. {
  831. return m_Flags;
  832. }
  833. //-----------------------------------------------------------------------------
  834. //
  835. //-----------------------------------------------------------------------------
  836. inline bool CUtlBuffer::IsExternallyAllocated() const
  837. {
  838. return m_Memory.IsExternallyAllocated();
  839. }
  840. //-----------------------------------------------------------------------------
  841. // Where am I writing?
  842. //-----------------------------------------------------------------------------
  843. inline int CUtlBuffer::TellPut( ) const
  844. {
  845. return m_Put;
  846. }
  847. //-----------------------------------------------------------------------------
  848. // What's the most I've ever written?
  849. //-----------------------------------------------------------------------------
  850. inline int CUtlBuffer::TellMaxPut( ) const
  851. {
  852. return m_nMaxPut;
  853. }
  854. //-----------------------------------------------------------------------------
  855. // What am I reading?
  856. //-----------------------------------------------------------------------------
  857. inline void* CUtlBuffer::PeekPut( int offset )
  858. {
  859. return &m_Memory[m_Put + offset - m_nOffset];
  860. }
  861. //-----------------------------------------------------------------------------
  862. // Various put methods
  863. //-----------------------------------------------------------------------------
  864. template <typename T>
  865. inline void CUtlBuffer::PutObject( T *src )
  866. {
  867. if ( CheckPut( sizeof(T) ) )
  868. {
  869. if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) )
  870. {
  871. *(T *)PeekPut() = *src;
  872. }
  873. else
  874. {
  875. m_Byteswap.SwapFieldsToTargetEndian<T>( (T*)PeekPut(), src );
  876. }
  877. m_Put += sizeof(T);
  878. AddNullTermination( m_Put );
  879. }
  880. }
  881. template <typename T>
  882. inline void CUtlBuffer::PutObjects( T *src, int count )
  883. {
  884. for ( int i = 0; i < count; ++i, ++src )
  885. {
  886. PutObject<T>( src );
  887. }
  888. }
  889. template <typename T>
  890. inline void CUtlBuffer::PutTypeBin( T src )
  891. {
  892. if ( CheckPut( sizeof(T) ) )
  893. {
  894. if ( !m_Byteswap.IsSwappingBytes() || ( sizeof( T ) == 1 ) )
  895. {
  896. *(T *)PeekPut() = src;
  897. }
  898. else
  899. {
  900. m_Byteswap.SwapBufferToTargetEndian<T>( (T*)PeekPut(), &src );
  901. }
  902. m_Put += sizeof(T);
  903. AddNullTermination( m_Put );
  904. }
  905. }
  906. #if defined( _GAMECONSOLE )
  907. template <>
  908. inline void CUtlBuffer::PutTypeBin< float >( float src )
  909. {
  910. if ( CheckPut( sizeof( src ) ) )
  911. {
  912. if ( m_Byteswap.IsSwappingBytes() )
  913. {
  914. m_Byteswap.SwapBufferToTargetEndian<float>( &src, &src );
  915. }
  916. //
  917. // Write the data
  918. //
  919. unsigned pData = (unsigned)PeekPut();
  920. if ( pData & 0x03 )
  921. {
  922. // handle unaligned write
  923. byte* dst = (byte*)pData;
  924. byte* srcPtr = (byte*)&src;
  925. dst[0] = srcPtr[0];
  926. dst[1] = srcPtr[1];
  927. dst[2] = srcPtr[2];
  928. dst[3] = srcPtr[3];
  929. }
  930. else
  931. {
  932. *(float *)pData = src;
  933. }
  934. m_Put += sizeof(float);
  935. AddNullTermination( m_Put );
  936. }
  937. }
  938. template <>
  939. inline void CUtlBuffer::PutTypeBin< double >( double src )
  940. {
  941. if ( CheckPut( sizeof( src ) ) )
  942. {
  943. if ( m_Byteswap.IsSwappingBytes() )
  944. {
  945. m_Byteswap.SwapBufferToTargetEndian<double>( &src, &src );
  946. }
  947. //
  948. // Write the data
  949. //
  950. unsigned pData = (unsigned)PeekPut();
  951. if ( pData & 0x07 )
  952. {
  953. // handle unaligned write
  954. byte* dst = (byte*)pData;
  955. byte* srcPtr = (byte*)&src;
  956. dst[0] = srcPtr[0];
  957. dst[1] = srcPtr[1];
  958. dst[2] = srcPtr[2];
  959. dst[3] = srcPtr[3];
  960. dst[4] = srcPtr[4];
  961. dst[5] = srcPtr[5];
  962. dst[6] = srcPtr[6];
  963. dst[7] = srcPtr[7];
  964. }
  965. else
  966. {
  967. *(double *)pData = src;
  968. }
  969. m_Put += sizeof(double);
  970. AddNullTermination( m_Put );
  971. }
  972. }
  973. #endif
  974. template <typename T>
  975. inline void CUtlBuffer::PutType( T src )
  976. {
  977. if (!IsText())
  978. {
  979. PutTypeBin( src );
  980. }
  981. else
  982. {
  983. Printf( GetFmtStr< T >(), src );
  984. }
  985. }
  986. //-----------------------------------------------------------------------------
  987. // Methods to help with pretty-printing
  988. //-----------------------------------------------------------------------------
  989. inline bool CUtlBuffer::WasLastCharacterCR()
  990. {
  991. if ( !IsText() || (TellPut() == 0) )
  992. return false;
  993. return ( *( const char * )PeekPut( -1 ) == '\n' );
  994. }
  995. inline void CUtlBuffer::PutTabs()
  996. {
  997. int nTabCount = ( m_Flags & AUTO_TABS_DISABLED ) ? 0 : m_nTab;
  998. for (int i = nTabCount; --i >= 0; )
  999. {
  1000. PutTypeBin<char>( '\t' );
  1001. }
  1002. }
  1003. //-----------------------------------------------------------------------------
  1004. // Push/pop pretty-printing tabs
  1005. //-----------------------------------------------------------------------------
  1006. inline void CUtlBuffer::PushTab( )
  1007. {
  1008. ++m_nTab;
  1009. }
  1010. inline void CUtlBuffer::PopTab()
  1011. {
  1012. if ( --m_nTab < 0 )
  1013. {
  1014. m_nTab = 0;
  1015. }
  1016. }
  1017. //-----------------------------------------------------------------------------
  1018. // Temporarily disables pretty print
  1019. //-----------------------------------------------------------------------------
  1020. inline void CUtlBuffer::EnableTabs( bool bEnable )
  1021. {
  1022. if ( bEnable )
  1023. {
  1024. m_Flags &= ~AUTO_TABS_DISABLED;
  1025. }
  1026. else
  1027. {
  1028. m_Flags |= AUTO_TABS_DISABLED;
  1029. }
  1030. }
  1031. inline void CUtlBuffer::PutChar( char c )
  1032. {
  1033. if ( WasLastCharacterCR() )
  1034. {
  1035. PutTabs();
  1036. }
  1037. PutTypeBin( c );
  1038. }
  1039. inline void CUtlBuffer::PutUnsignedChar( unsigned char c )
  1040. {
  1041. if (!IsText())
  1042. {
  1043. PutTypeBin( c );
  1044. }
  1045. else
  1046. {
  1047. PutUnsignedShort( c );
  1048. }
  1049. }
  1050. inline void CUtlBuffer::PutShort( short s )
  1051. {
  1052. PutType( s );
  1053. }
  1054. inline void CUtlBuffer::PutUnsignedShort( unsigned short s )
  1055. {
  1056. PutType( s );
  1057. }
  1058. inline void CUtlBuffer::PutInt( int i )
  1059. {
  1060. PutType( i );
  1061. }
  1062. inline void CUtlBuffer::PutInt64( int64 i )
  1063. {
  1064. PutType( i );
  1065. }
  1066. inline void CUtlBuffer::PutUnsignedInt( unsigned int u )
  1067. {
  1068. PutType( u );
  1069. }
  1070. inline void CUtlBuffer::PutUnsignedInt64( uint64 i )
  1071. {
  1072. PutType( i );
  1073. }
  1074. inline void CUtlBuffer::PutFloat( float f )
  1075. {
  1076. PutType( f );
  1077. }
  1078. inline void CUtlBuffer::PutDouble( double d )
  1079. {
  1080. PutType( d );
  1081. }
  1082. inline void CUtlBuffer::PutPtr( void *p )
  1083. {
  1084. // LEGACY WARNING: in text mode, PutPtr writes 32 bit pointers in hex, while GetPtr reads 32 or 64 bit pointers in decimal
  1085. if (!IsText())
  1086. {
  1087. PutTypeBin( p );
  1088. }
  1089. else
  1090. {
  1091. Printf( "0x%p", p );
  1092. }
  1093. }
  1094. //-----------------------------------------------------------------------------
  1095. // Am I a text buffer?
  1096. //-----------------------------------------------------------------------------
  1097. inline bool CUtlBuffer::IsText() const
  1098. {
  1099. return (m_Flags & TEXT_BUFFER) != 0;
  1100. }
  1101. //-----------------------------------------------------------------------------
  1102. // Can I grow if I'm externally allocated?
  1103. //-----------------------------------------------------------------------------
  1104. inline bool CUtlBuffer::IsGrowable() const
  1105. {
  1106. return (m_Flags & EXTERNAL_GROWABLE) != 0;
  1107. }
  1108. //-----------------------------------------------------------------------------
  1109. // Am I valid? (overflow or underflow error), Once invalid it stays invalid
  1110. //-----------------------------------------------------------------------------
  1111. inline bool CUtlBuffer::IsValid() const
  1112. {
  1113. return m_Error == 0;
  1114. }
  1115. //-----------------------------------------------------------------------------
  1116. // Do I contain carriage return/linefeeds?
  1117. //-----------------------------------------------------------------------------
  1118. inline bool CUtlBuffer::ContainsCRLF() const
  1119. {
  1120. return IsText() && ((m_Flags & CONTAINS_CRLF) != 0);
  1121. }
  1122. //-----------------------------------------------------------------------------
  1123. // Am I read-only
  1124. //-----------------------------------------------------------------------------
  1125. inline bool CUtlBuffer::IsReadOnly() const
  1126. {
  1127. return (m_Flags & READ_ONLY) != 0;
  1128. }
  1129. //-----------------------------------------------------------------------------
  1130. // Buffer base and size
  1131. //-----------------------------------------------------------------------------
  1132. inline const void* CUtlBuffer::Base() const
  1133. {
  1134. return m_Memory.Base();
  1135. }
  1136. inline void* CUtlBuffer::Base()
  1137. {
  1138. return m_Memory.Base();
  1139. }
  1140. inline int CUtlBuffer::Size() const
  1141. {
  1142. return m_Memory.NumAllocated();
  1143. }
  1144. //-----------------------------------------------------------------------------
  1145. // Clears out the buffer; frees memory
  1146. //-----------------------------------------------------------------------------
  1147. inline void CUtlBuffer::Clear()
  1148. {
  1149. m_Get = 0;
  1150. m_Put = 0;
  1151. m_Error = 0;
  1152. m_nOffset = 0;
  1153. m_nMaxPut = -1;
  1154. AddNullTermination( m_Put );
  1155. }
  1156. inline void CUtlBuffer::Purge()
  1157. {
  1158. m_Get = 0;
  1159. m_Put = 0;
  1160. m_nOffset = 0;
  1161. m_nMaxPut = 0;
  1162. m_Error = 0;
  1163. m_Memory.Purge();
  1164. }
  1165. //-----------------------------------------------------------------------------
  1166. //
  1167. //-----------------------------------------------------------------------------
  1168. inline void *CUtlBuffer::AccessForDirectRead( int nBytes )
  1169. {
  1170. Assert( m_Get == 0 && m_Put == 0 && m_nMaxPut == 0 );
  1171. EnsureCapacity( nBytes );
  1172. m_nMaxPut = nBytes;
  1173. return Base();
  1174. }
  1175. inline void *CUtlBuffer::Detach()
  1176. {
  1177. void *p = m_Memory.Detach();
  1178. Clear();
  1179. return p;
  1180. }
  1181. //-----------------------------------------------------------------------------
  1182. inline void CUtlBuffer::Spew( )
  1183. {
  1184. SeekGet( CUtlBuffer::SEEK_HEAD, 0 );
  1185. char pTmpLine[1024];
  1186. while( IsValid() && GetBytesRemaining() )
  1187. {
  1188. V_memset( pTmpLine, 0, sizeof(pTmpLine) );
  1189. Get( pTmpLine, MIN( ( size_t )GetBytesRemaining(), sizeof(pTmpLine)-1 ) );
  1190. Msg( _T( "%s" ), pTmpLine );
  1191. }
  1192. }
  1193. #if !defined(_GAMECONSOLE)
  1194. inline void CUtlBuffer::SwapCopy( CUtlBuffer &other )
  1195. {
  1196. m_Get = other.m_Get;
  1197. m_Put = other.m_Put;
  1198. m_Error = other.m_Error;
  1199. m_Flags = other.m_Flags;
  1200. m_Reserved = other.m_Reserved;
  1201. m_nTab = other.m_nTab;
  1202. m_nMaxPut = other.m_nMaxPut;
  1203. m_nOffset = other.m_nOffset;
  1204. m_GetOverflowFunc = other.m_GetOverflowFunc;
  1205. m_PutOverflowFunc = other.m_PutOverflowFunc;
  1206. m_Byteswap = other.m_Byteswap;
  1207. m_Memory.Swap( other.m_Memory );
  1208. }
  1209. #endif
  1210. inline void CUtlBuffer::CopyBuffer( const CUtlBuffer &buffer )
  1211. {
  1212. CopyBuffer( buffer.Base(), buffer.TellPut() );
  1213. }
  1214. inline void CUtlBuffer::CopyBuffer( const void *pubData, int cubData )
  1215. {
  1216. Clear();
  1217. if ( cubData )
  1218. {
  1219. Put( pubData, cubData );
  1220. }
  1221. }
  1222. #endif // UTLBUFFER_H