move code into RageUtil
This commit is contained in:
@@ -252,11 +252,81 @@ RString ssprintf( const char *fmt, ...)
|
|||||||
return vssprintf(fmt, va);
|
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;
|
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;
|
return sStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -641,100 +641,6 @@ public:
|
|||||||
this->resize(static_cast<MYSIZE>(nNewLen > -1 ? nNewLen : sslen(this->c_str())));
|
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