hl2_src-leak-2017/src/external/vpc/public/tier1/fmtstr.h

180 lines
4.6 KiB
C++

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: A simple class for performing safe and in-expression sprintf-style
// string formatting
//
// $NoKeywords: $
//=============================================================================//
#ifndef FMTSTR_H
#define FMTSTR_H
#include <stdarg.h>
#include <stdio.h>
#include "tier0/platform.h"
#include "tier0/dbg.h"
#include "tier1/strtools.h"
#if defined( _WIN32 )
#pragma once
#endif
//=============================================================================
// using macro to be compatable with GCC
#define FmtStrVSNPrintf( szBuf, nBufSize, bQuietTruncation, ppszFormat ) \
do \
{ \
int result; \
va_list arg_ptr; \
bool bTruncated = false; \
static int scAsserted = 0; \
\
va_start(arg_ptr, (*(ppszFormat))); \
result = V_vsnprintfRet( (szBuf), (nBufSize)-1, (*(ppszFormat)), arg_ptr, &bTruncated ); \
va_end(arg_ptr); \
\
(szBuf)[(nBufSize)-1] = 0; \
if ( bTruncated && !(bQuietTruncation) && scAsserted < 5 ) \
{ \
Assert( !bTruncated ); \
scAsserted++; \
} \
} \
while (0)
//-----------------------------------------------------------------------------
//
// Purpose: String formatter with specified size
//
template <int SIZE_BUF>
class CFmtStrN
{
public:
CFmtStrN()
{
InitQuietTruncation();
m_szBuf[0] = 0;
m_nLength = 0;
}
// Standard C formatting
CFmtStrN(const char *pszFormat, ...) FMTFUNCTION( 2, 3 )
{
InitQuietTruncation();
FmtStrVSNPrintf(m_szBuf, SIZE_BUF, m_bQuietTruncation, &pszFormat);
FixLength();
}
// Use this for pass-through formatting
CFmtStrN(const char ** ppszFormat, ...)
{
InitQuietTruncation();
FmtStrVSNPrintf(m_szBuf, SIZE_BUF, m_bQuietTruncation, ppszFormat);
FixLength();
}
// Explicit reformat
const char *sprintf(const char *pszFormat, ...) FMTFUNCTION( 2, 3 )
{
InitQuietTruncation();
FmtStrVSNPrintf(m_szBuf, SIZE_BUF, m_bQuietTruncation, &pszFormat);
FixLength();
return m_szBuf;
}
// Use this for pass-through formatting
void VSprintf(const char **ppszFormat, ...)
{
InitQuietTruncation();
FmtStrVSNPrintf(m_szBuf, SIZE_BUF, m_bQuietTruncation, ppszFormat);
FixLength();
}
// Use for access
operator const char *() const { return m_szBuf; }
char *Access() { return m_szBuf; }
CFmtStrN<SIZE_BUF> & operator=( const char *pchValue ) { sprintf( pchValue ); return *this; }
CFmtStrN<SIZE_BUF> & operator+=( const char *pchValue ) { Append( pchValue ); return *this; }
int Length() const { return m_nLength; }
void Clear() { m_szBuf[0] = 0; m_nLength = 0; }
void AppendFormat( const char *pchFormat, ... ) { char *pchEnd = m_szBuf + m_nLength; FmtStrVSNPrintf( pchEnd, SIZE_BUF - m_nLength, m_bQuietTruncation, &pchFormat ); FixLength(); }
void AppendFormatV( const char *pchFormat, va_list args );
void Append( const char *pchValue ) { AppendFormat( pchValue ); }
void AppendIndent( uint32 unCount, char chIndent = '\t' );
protected:
virtual void InitQuietTruncation()
{
#ifdef _DEBUG
m_bQuietTruncation = false;
#else
m_bQuietTruncation = true; // Force quiet for release builds
#endif
}
bool m_bQuietTruncation;
void FixLength() { m_nLength = V_strlen(m_szBuf); }
private:
char m_szBuf[SIZE_BUF];
int m_nLength;
};
// Version which will not assert if strings are truncated
template <int SIZE_BUF>
class CFmtStrQuietTruncationN : public CFmtStrN<SIZE_BUF>
{
protected:
virtual void InitQuietTruncation() { this->m_bQuietTruncation = true; }
};
template< int SIZE_BUF >
void CFmtStrN<SIZE_BUF>::AppendIndent( uint32 unCount, char chIndent )
{
Assert( Length() + unCount < SIZE_BUF );
if( Length() + unCount >= SIZE_BUF )
unCount = SIZE_BUF - (1+Length());
for ( uint32 x = 0; x < unCount; x++ )
{
m_szBuf[ m_nLength++ ] = chIndent;
}
m_szBuf[ m_nLength ] = '\0';
}
template< int SIZE_BUF >
void CFmtStrN<SIZE_BUF>::AppendFormatV( const char *pchFormat, va_list args )
{
int cubPrinted = V_vsnprintf( m_szBuf+Length(), SIZE_BUF - Length(), pchFormat, args );
m_nLength += cubPrinted;
}
//-----------------------------------------------------------------------------
//
// Purpose: Default-sized string formatter
//
#define FMTSTR_STD_LEN 1024
typedef CFmtStrN<FMTSTR_STD_LEN> CFmtStr;
typedef CFmtStrQuietTruncationN<FMTSTR_STD_LEN> CFmtStrQuietTruncation;
typedef CFmtStrN<1024> CFmtStr1024;
typedef CFmtStrN<8192> CFmtStrMax;
//=============================================================================
const int k_cchFormattedDate = 64;
const int k_cchFormattedTime = 32;
bool BGetLocalFormattedTime( time_t timeVal, char *pchDate, int cubDate, char *pchTime, int cubTime );
#endif // FMTSTR_H