From fc3506ac1ea61e97e905b5ae1a54457e52d37e56 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Mon, 18 Sep 2006 23:08:43 +0000 Subject: [PATCH] move code into RageUtil --- stepmania/src/RageUtil.cpp | 74 +++++++++++++++++++++++++++++- stepmania/src/StdString.h | 94 -------------------------------------- 2 files changed, 72 insertions(+), 96 deletions(-) diff --git a/stepmania/src/RageUtil.cpp b/stepmania/src/RageUtil.cpp index 44894ebbf1..0b91cb02f1 100644 --- a/stepmania/src/RageUtil.cpp +++ b/stepmania/src/RageUtil.cpp @@ -252,11 +252,81 @@ RString ssprintf( const char *fmt, ...) return vssprintf(fmt, va); } +#define MAX_FMT_TRIES 5 // #of times we try +#define FMT_BLOCK_SIZE 2048 // # of bytes to increment per try -RString vssprintf( const char *fmt, va_list argList ) +RString vssprintf( const char *szFormat, va_list argList ) { RString sStr; - sStr.FormatV( fmt, argList ); + +#if defined(WIN32) && !defined(__MINGW32__) + char *pBuf = NULL; + int iChars = 1; + int iUsed = 0; + size_t iActual = 0; + int iTry = 0; + + do + { + // Grow more than linearly (e.g. 512, 1536, 3072, etc) + iChars += (iTry+1) * FMT_BLOCK_SIZE; + pBuf = (char*) _alloca( sizeof(char)*iChars ); + iUsed = vsnprintf( pBuf, iChars-1, szFormat, argList ); + + // Ensure proper NULL termination. + iActual = iUsed == -1 ? iChars-1 : min(iUsed, iChars-1); + pBuf[iActual+1]= '\0'; + } while ( iUsed < 0 && iTry++ < MAX_FMT_TRIES ); + + // assign whatever we managed to format + sStr.assign( pBuf, iActual ); +#else + static bool bExactSizeSupported; + static bool bInitialized = false; + if( !bInitialized ) + { + /* Some systems return the actual size required when snprintf + * doesn't have enough space. This lets us avoid wasting time + * iterating, and wasting memory. */ + bInitialized = true; + char ignore; + bExactSizeSupported = ( snprintf( &ignore, 0, "Hello World" ) == 11 ); + } + + if( bExactSizeSupported ) + { + va_list tmp; + va_copy( tmp, argList ); + char ignore; + int iNeeded = vsnprintf( &ignore, 0, szFormat, tmp ); + va_end(tmp); + + char *buf = GetBuffer( iNeeded+1 ); + vsnprintf( buf, iNeeded+1, szFormat, argList ); + ReleaseBuffer( iNeeded ); + return; + } + + int iChars = FMT_BLOCK_SIZE; + int iTry = 1; + do + { + // Grow more than linearly (e.g. 512, 1536, 3072, etc) + char *buf = GetBuffer(iChars); + int iUsed = vsnprintf(buf, iChars-1, szFormat, argList); + + if( iUsed == -1 ) + { + iChars += ((iTry+1) * FMT_BLOCK_SIZE); + ReleaseBuffer(); + continue; + } + + /* OK */ + sStr.ReleaseBuffer(iUsed); + break; + } while ( iTry++ < MAX_FMT_TRIES ); +#endif return sStr; } diff --git a/stepmania/src/StdString.h b/stepmania/src/StdString.h index c509d2640a..f16bd83433 100644 --- a/stepmania/src/StdString.h +++ b/stepmania/src/StdString.h @@ -641,100 +641,6 @@ public: this->resize(static_cast(nNewLen > -1 ? nNewLen : sslen(this->c_str()))); } - #define MAX_FMT_TRIES 5 // #of times we try - #define FMT_BLOCK_SIZE 2048 // # of bytes to increment per try - - // ------------------------------------------------------------------------- - // FUNCTION: FormatV - // void FormatV(PCSTR szFormat, va_list, argList); - // - // DESCRIPTION: - // This function formats the string with sprintf style format-specs. - // It makes a general guess at required buffer size and then tries - // successively larger buffers until it finds one big enough or a - // threshold (MAX_FMT_TRIES) is exceeded. - // - // PARAMETERS: - // szFormat - a PCSTR holding the format of the output - // argList - a Microsoft specific va_list for variable argument lists - // - // RETURN VALUE: - // ------------------------------------------------------------------------- - - void FormatV(const CT* szFormat, va_list argList) - { - #if defined(WIN32) && !defined(__MINGW32__) - CT* pBuf = NULL; - int nChars = 1; - int nUsed = 0; - size_type nActual = 0; - int nTry = 0; - - do - { - // Grow more than linearly (e.g. 512, 1536, 3072, etc) - - nChars += ((nTry+1) * FMT_BLOCK_SIZE); - pBuf = reinterpret_cast(_alloca(sizeof(CT)*nChars)); - nUsed = vsnprintf(pBuf, nChars-1, szFormat, argList); - - // Ensure proper NULL termination. - - nActual = nUsed == -1 ? nChars-1 : min(nUsed, nChars-1); - pBuf[nActual+1]= '\0'; - } while ( nUsed < 0 && nTry++ < MAX_FMT_TRIES ); - - // assign whatever we managed to format - - this->assign(pBuf, nActual); - #else - static bool bExactSizeSupported; - static bool bInitialized = false; - if( !bInitialized ) - { - /* Some systems return the actual size required when snprintf - * doesn't have enough space. This lets us avoid wasting time - * iterating, and wasting memory. */ - bInitialized = true; - char ignore; - bExactSizeSupported = ( snprintf( &ignore, 0, "Hello World" ) == 11 ); - } - - if( bExactSizeSupported ) - { - va_list tmp; - va_copy( tmp, argList ); - char ignore; - int iNeeded = vsnprintf( &ignore, 0, szFormat, tmp ); - va_end(tmp); - - char *buf = GetBuffer( iNeeded+1 ); - vsnprintf( buf, iNeeded+1, szFormat, argList ); - ReleaseBuffer( iNeeded ); - return; - } - - int nChars = FMT_BLOCK_SIZE; - int nTry = 1; - do - { - // Grow more than linearly (e.g. 512, 1536, 3072, etc) - char *buf = GetBuffer(nChars); - int nUsed = vsnprintf(buf, nChars-1, szFormat, argList); - - if(nUsed == -1) - { - nChars += ((nTry+1) * FMT_BLOCK_SIZE); - ReleaseBuffer(); - continue; - } - - /* OK */ - ReleaseBuffer(nUsed); - break; - } while ( nTry++ < MAX_FMT_TRIES ); - #endif - } // -------------------------------------------------------------------------