46
* Appends text. If buffer is full, exceeding text will not
48
* @author Hj. Malthaner
50
33
void cbuffer_t::append(const char * text)
53
if( size>=capacity-1 ) {
54
// Knightly : double the capacity if full
57
buf[size++] = *text++;
64
* Appends a number. If buffer is full, exceeding digits will not
66
* @author Hj. Malthaner
68
void cbuffer_t::append(long n)
81
*--p = '0' + (n % 10);
93
* Appends a number. If buffer is full, exceeding digits will not
95
* @author Hj. Malthaner
35
size_t const n = strlen(text);
37
memcpy(buf + size, text, n + 1);
97
42
void cbuffer_t::append(double n,int decimals)
50
/* this is a vsnprintf which can always process positional parameters
52
* WARNING: posix specification as well as this function always assumes that
53
* ALL parameter are either positional or not!!!
55
* When numbered argument specifications are used, specifying the Nth argument requires that all the
56
* leading arguments, from the first to the (N-1)th, are specified in the format string.
58
* ATTENTION: no support for positional precision (which are not used in simutrans anyway!
60
static int my_vsnprintf(char *buf, size_t n, const char* fmt, va_list ap )
62
#if defined _MSC_FULL_VER && _MSC_FULL_VER >= 140050727 && !defined __WXWINCE__
63
// this MSC function can handle positional parameters since 2008
64
return _vsprintf_p(buf, n, fmt, ap);
66
#if !defined(HAVE_UNIX98_PRINTF)
67
// this function cannot handle positional parameters
68
if( const char *c=strstr( fmt, "%1$" ) ) {
69
// but they are requested here ...
70
// our routine can only handle max. 9 parameters
72
static char format_string[256];
73
char *cfmt = format_string;
74
static char buffer[16000]; // the longest possible buffer ...
76
for( ; c && count<9; count++ ) {
77
sprintf( pos, "%%%i$", count+1 );
78
c = strstr( fmt, pos );
80
// extend format string, using 1 as marke between strings
87
int len = strspn( c, "+-0123456789 #.hlI" )+1;
94
// now printf into buffer
95
int result = vsnprintf( buffer, 16000, format_string, ap );
96
if( result<0 || result>=16000 ) {
101
result += strlen(fmt);
102
if( (size_t)result > n ) {
103
// increase the size please ...
106
// we have enough size: copy everything together
109
cfmt = const_cast<char *>(fmt); // cast is save, as the string is not modified
111
while( *cfmt!='%' && *cfmt ) {
117
// get the nth argument
119
int current = cfmt[1]-'1';
120
for( int j=0; j<current; j++ ) {
121
while( *carg && *carg!='\01' ) {
127
while( *carg && *carg!='\01' ) {
132
cfmt += strspn( cfmt, "+-0123456789 #.hlI" )+1;
137
// no positional parameters: use standard vsnprintf
139
// normal posix system can handle positional parameters
140
return vsnprintf(buf, n, fmt, ap);
105
145
void cbuffer_t::printf(const char* fmt, ...)
109
int count = vsnprintf( buf+size, capacity-size, fmt, ap);
112
// we do not increase it beyond 1MB, as this is usually only needed when %s of a random memory location
113
while(0 <= count && capacity-size <= (uint)count && capacity < 1048576) {
148
size_t const n = capacity - size;
117
152
va_start(ap, fmt);
118
count = vsnprintf( buf+size, capacity-size, fmt, ap);
153
int const count = my_vsnprintf(buf + size, n, fmt, ap );
120
// .. until everything fit into buffer
163
} else if ((size_t)count < n) {
167
// Make room for the string.
133
void cbuffer_t::extend(const unsigned int by_amount)
175
void cbuffer_t::extend(unsigned int min_free_space)
135
if( size+by_amount>=capacity ) {
177
if (min_free_space >= capacity - size) {
178
unsigned int by_amount = min_free_space + 1 - (capacity - size);
179
if (by_amount < capacity) {
180
// At least double the size of the buffer.
181
by_amount = capacity;
136
183
unsigned int new_capacity = capacity + by_amount;
137
184
char *new_buf = new char [new_capacity];
138
185
memcpy( new_buf, buf, capacity );