Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine buffer size for vswprintf under Linux gcc

Tags:

c++

gcc

unicode

I need to allocate a sufficient buffer for format function vswprintf(). When doing the same thing with ANSI string, I'm using:

vsnprintf( NULL, NULL, pszFormat, args );

which returns me required size of a buffer. But it seems that unicode version of this function doesn't have this functionality. When I execute:

vswprintf( NULL, NULL, pszFormat, args );

result value is always -1.

Only solution which I found is using a large static buffer for calculation required size. But I don't like this solution:

static const int nBuffSize = 1024;
static XCHAR evalBuff[nBuffSize];
int nSize = vswprintf( evalBuff, nBuffSize, pszFormat, args );
if ( nSize != -1 )
{
 return nSize;
}
else
{
 throw XXX;
}

Is there any way how to measure required buffer size for unicode strings?

Regards Ludek

like image 656
Ludek Vodicka Avatar asked Nov 05 '10 16:11

Ludek Vodicka


2 Answers

Opening a dummy file to /dev/null (or NUL under windows) and printing to that file to retrieve the size works very well (it is faster than printing to a string):

#if !defined(_MSC_VER)
   printf_dummy_file = fopen("/dev/null", "wb");
#else
   printf_dummy_file = fopen("NUL", "wb");
#endif

...

n = vfprintf(printf_dummy_file, format, args);

The "fopen" part should be done once (you can use a static variable, or the constructor of a global variable if you are using C++).

like image 61
John Rusta Avatar answered Nov 15 '22 00:11

John Rusta


A bit heavyweight, but if nobody comes up with anything better you could exponentially grow a buffer until it's big enough:

std::vector<wchar_t> vec(512);
int nSize;
do {
    vec.resize(vec.size()*2);
    va_list args2;
    va_copy args2, args;
    nSize = vswprintf(&vec[0], vec.size(), format, args2);
    va_end args2
} while(nSize < 0);
// now I have the length, and the formatted string to copy if required.

Since you're on POSIX, you'd think that an errno would be defined for insufficient buffer space, and that this errno should be checked in the while condition, so that other errors don't cause a resource-hungry loop. But there's no such errno defined at http://opengroup.org/onlinepubs/007908775/xsh/fwprintf.html, so I guess you'll have to test what errno you actually get on your implementation (if any).

Another option is to get rid of the format strings, and instead write to a wostringstream. But that's not much use if your format string needs to be configured after compile-time.

like image 38
Steve Jessop Avatar answered Nov 15 '22 00:11

Steve Jessop