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.

179 lines
4.6 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: A simple class for performing safe and in-expression sprintf-style
  4. // string formatting
  5. //
  6. // $NoKeywords: $
  7. //=============================================================================//
  8. #ifndef FMTSTR_H
  9. #define FMTSTR_H
  10. #include <stdarg.h>
  11. #include <stdio.h>
  12. #include "tier0/platform.h"
  13. #include "tier0/dbg.h"
  14. #include "tier1/strtools.h"
  15. #if defined( _WIN32 )
  16. #pragma once
  17. #endif
  18. //=============================================================================
  19. // using macro to be compatable with GCC
  20. #define FmtStrVSNPrintf( szBuf, nBufSize, bQuietTruncation, ppszFormat ) \
  21. do \
  22. { \
  23. int result; \
  24. va_list arg_ptr; \
  25. bool bTruncated = false; \
  26. static int scAsserted = 0; \
  27. \
  28. va_start(arg_ptr, (*(ppszFormat))); \
  29. result = V_vsnprintfRet( (szBuf), (nBufSize)-1, (*(ppszFormat)), arg_ptr, &bTruncated ); \
  30. va_end(arg_ptr); \
  31. \
  32. (szBuf)[(nBufSize)-1] = 0; \
  33. if ( bTruncated && !(bQuietTruncation) && scAsserted < 5 ) \
  34. { \
  35. Assert( !bTruncated ); \
  36. scAsserted++; \
  37. } \
  38. } \
  39. while (0)
  40. //-----------------------------------------------------------------------------
  41. //
  42. // Purpose: String formatter with specified size
  43. //
  44. template <int SIZE_BUF>
  45. class CFmtStrN
  46. {
  47. public:
  48. CFmtStrN()
  49. {
  50. InitQuietTruncation();
  51. m_szBuf[0] = 0;
  52. m_nLength = 0;
  53. }
  54. // Standard C formatting
  55. CFmtStrN(const char *pszFormat, ...) FMTFUNCTION( 2, 3 )
  56. {
  57. InitQuietTruncation();
  58. FmtStrVSNPrintf(m_szBuf, SIZE_BUF, m_bQuietTruncation, &pszFormat);
  59. FixLength();
  60. }
  61. // Use this for pass-through formatting
  62. CFmtStrN(const char ** ppszFormat, ...)
  63. {
  64. InitQuietTruncation();
  65. FmtStrVSNPrintf(m_szBuf, SIZE_BUF, m_bQuietTruncation, ppszFormat);
  66. FixLength();
  67. }
  68. // Explicit reformat
  69. const char *sprintf(const char *pszFormat, ...) FMTFUNCTION( 2, 3 )
  70. {
  71. InitQuietTruncation();
  72. FmtStrVSNPrintf(m_szBuf, SIZE_BUF, m_bQuietTruncation, &pszFormat);
  73. FixLength();
  74. return m_szBuf;
  75. }
  76. // Use this for pass-through formatting
  77. void VSprintf(const char **ppszFormat, ...)
  78. {
  79. InitQuietTruncation();
  80. FmtStrVSNPrintf(m_szBuf, SIZE_BUF, m_bQuietTruncation, ppszFormat);
  81. FixLength();
  82. }
  83. // Use for access
  84. operator const char *() const { return m_szBuf; }
  85. char *Access() { return m_szBuf; }
  86. CFmtStrN<SIZE_BUF> & operator=( const char *pchValue ) { sprintf( pchValue ); return *this; }
  87. CFmtStrN<SIZE_BUF> & operator+=( const char *pchValue ) { Append( pchValue ); return *this; }
  88. int Length() const { return m_nLength; }
  89. void Clear() { m_szBuf[0] = 0; m_nLength = 0; }
  90. void AppendFormat( const char *pchFormat, ... ) { char *pchEnd = m_szBuf + m_nLength; FmtStrVSNPrintf( pchEnd, SIZE_BUF - m_nLength, m_bQuietTruncation, &pchFormat ); FixLength(); }
  91. void AppendFormatV( const char *pchFormat, va_list args );
  92. void Append( const char *pchValue ) { AppendFormat( pchValue ); }
  93. void AppendIndent( uint32 unCount, char chIndent = '\t' );
  94. protected:
  95. virtual void InitQuietTruncation()
  96. {
  97. #ifdef _DEBUG
  98. m_bQuietTruncation = false;
  99. #else
  100. m_bQuietTruncation = true; // Force quiet for release builds
  101. #endif
  102. }
  103. bool m_bQuietTruncation;
  104. void FixLength() { m_nLength = V_strlen(m_szBuf); }
  105. private:
  106. char m_szBuf[SIZE_BUF];
  107. int m_nLength;
  108. };
  109. // Version which will not assert if strings are truncated
  110. template <int SIZE_BUF>
  111. class CFmtStrQuietTruncationN : public CFmtStrN<SIZE_BUF>
  112. {
  113. protected:
  114. virtual void InitQuietTruncation() { this->m_bQuietTruncation = true; }
  115. };
  116. template< int SIZE_BUF >
  117. void CFmtStrN<SIZE_BUF>::AppendIndent( uint32 unCount, char chIndent )
  118. {
  119. Assert( Length() + unCount < SIZE_BUF );
  120. if( Length() + unCount >= SIZE_BUF )
  121. unCount = SIZE_BUF - (1+Length());
  122. for ( uint32 x = 0; x < unCount; x++ )
  123. {
  124. m_szBuf[ m_nLength++ ] = chIndent;
  125. }
  126. m_szBuf[ m_nLength ] = '\0';
  127. }
  128. template< int SIZE_BUF >
  129. void CFmtStrN<SIZE_BUF>::AppendFormatV( const char *pchFormat, va_list args )
  130. {
  131. int cubPrinted = V_vsnprintf( m_szBuf+Length(), SIZE_BUF - Length(), pchFormat, args );
  132. m_nLength += cubPrinted;
  133. }
  134. //-----------------------------------------------------------------------------
  135. //
  136. // Purpose: Default-sized string formatter
  137. //
  138. #define FMTSTR_STD_LEN 1024
  139. typedef CFmtStrN<FMTSTR_STD_LEN> CFmtStr;
  140. typedef CFmtStrQuietTruncationN<FMTSTR_STD_LEN> CFmtStrQuietTruncation;
  141. typedef CFmtStrN<1024> CFmtStr1024;
  142. typedef CFmtStrN<8192> CFmtStrMax;
  143. //=============================================================================
  144. const int k_cchFormattedDate = 64;
  145. const int k_cchFormattedTime = 32;
  146. bool BGetLocalFormattedTime( time_t timeVal, char *pchDate, int cubDate, char *pchTime, int cubTime );
  147. #endif // FMTSTR_H