move code into RageUtil
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -641,100 +641,6 @@ public:
|
||||
this->resize(static_cast<MYSIZE>(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<CT*>(_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
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user