2012-11-29 09:50:40 +00:00
|
|
|
/*
|
|
|
|
* Buffer reusing string formatter
|
|
|
|
*
|
|
|
|
* by WangLu
|
|
|
|
* 2012.11.29
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef STRING_FORMATTER_H__
|
|
|
|
#define STRING_FORMATTER_H__
|
|
|
|
|
2012-11-29 10:16:05 +00:00
|
|
|
namespace pdf2htmlEX {
|
|
|
|
|
2012-11-29 09:50:40 +00:00
|
|
|
class string_formatter
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
class guarded_pointer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
guarded_pointer(string_formatter * sf) : sf(sf) { ++(sf->buf_cnt); }
|
2012-11-29 11:43:19 +00:00
|
|
|
guarded_pointer(const guarded_pointer & gp) : sf(gp.sf) { ++(sf->buf_cnt); }
|
2012-11-29 09:50:40 +00:00
|
|
|
~guarded_pointer(void) { --(sf->buf_cnt); }
|
2012-11-29 11:43:19 +00:00
|
|
|
operator char* () const { return &(sf->buf.front()); }
|
2012-11-29 09:50:40 +00:00
|
|
|
private:
|
|
|
|
string_formatter * sf;
|
|
|
|
};
|
|
|
|
|
|
|
|
string_formatter() : buf_cnt(0) { buf.reserve(L_tmpnam); }
|
|
|
|
/*
|
|
|
|
* Important:
|
|
|
|
* there is only one buffer, so new strings will replace old ones
|
|
|
|
*/
|
|
|
|
guarded_pointer operator () (const char * format, ...) {
|
|
|
|
assert((buf_cnt == 0) && "string_formatter: buffer is reused!");
|
|
|
|
|
|
|
|
va_list vlist;
|
|
|
|
va_start(vlist, format);
|
|
|
|
int l = vsnprintf(&buf.front(), buf.capacity(), format, vlist);
|
|
|
|
va_end(vlist);
|
|
|
|
if(l >= (int)buf.capacity())
|
|
|
|
{
|
|
|
|
buf.reserve(std::max<long>((long)(l+1), (long)buf.capacity() * 2));
|
|
|
|
va_start(vlist, format);
|
|
|
|
l = vsnprintf(&buf.front(), buf.capacity(), format, vlist);
|
|
|
|
va_end(vlist);
|
|
|
|
}
|
|
|
|
assert(l >= 0); // we should fail when vsnprintf fail
|
|
|
|
assert(l < (int)buf.capacity());
|
|
|
|
return guarded_pointer(this);
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
friend class guarded_pointer;
|
|
|
|
std::vector<char> buf;
|
|
|
|
int buf_cnt;
|
|
|
|
};
|
|
|
|
|
2012-11-29 10:16:05 +00:00
|
|
|
} //namespace pdf2htmlEX
|
2012-11-29 09:50:40 +00:00
|
|
|
#endif //STRING_FORMATTER_H__
|