Crossfire Server, Trunk
stringbuffer.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
14 #include <stdarg.h>
15 #include <stdlib.h>
16 #include <string.h>
17 
18 #include "global.h"
19 #include "libproto.h"
20 #include "stringbuffer.h"
21 
25 struct StringBuffer {
30  char *buf;
31 
37  size_t pos;
38 
42  size_t size;
43 };
44 
45 
54 static void stringbuffer_ensure(StringBuffer *sb, size_t len);
55 
56 
58  StringBuffer *sb;
59 
60  sb = static_cast<StringBuffer *>(malloc(sizeof(*sb)));
61  if (sb == NULL) {
63  }
64 
65  sb->size = 512;
66  sb->buf = static_cast<char *>(malloc(sb->size));
67  sb->pos = 0;
68  return sb;
69 }
70 
72  free(sb->buf);
73  free(sb);
74 }
75 
77  char *result;
78 
79  sb->buf[sb->pos] = '\0';
80  result = sb->buf;
81  free(sb);
82  return result;
83 }
84 
86  char *str;
88 
91  free(str);
92  return result;
93 }
94 
96  size_t len;
97 
98  len = strlen(str);
99  stringbuffer_ensure(sb, len+1);
100  memcpy(sb->buf+sb->pos, str, len);
101  sb->pos += len;
102 }
103 
104 void stringbuffer_append_char(StringBuffer *sb, const char c) {
105  stringbuffer_ensure(sb, 2); // character and NUL
106  sb->buf[sb->pos] = c;
107  sb->buf[sb->pos + 1] = '\0';
108  sb->pos += 1;
109 }
110 
112  if (x < 0) {
113  stringbuffer_append_char(sb, '-');
114  if (x == INT64_MIN) {
115  x = INT64_MAX;
116  } else {
117  x = -x;
118  }
119  }
120 
121  const int MAX_DIGITS = 20; // handle at most 20 digits, since an int64_t has at most 19 digits
122  char buf[MAX_DIGITS];
123  int i;
124  for (i = 0; i < MAX_DIGITS; i++) {
125  buf[i] = x % 10 + '0';
126  if ((x /= 10) == 0) {
127  i++;
128  break;
129  }
130  }
131 
132  // copy into sb in reverse
133  for (int j = i - 1; j >= 0; j--) {
135  }
136 }
137 
138 void stringbuffer_append_printf(StringBuffer *sb, const char *format, ...) {
139  size_t size;
140 
141  size = 100; /* arbitrary guess */
142  for (;;) {
143  int n;
144  va_list arg;
145 
146  stringbuffer_ensure(sb, size);
147 
148  va_start(arg, format);
149  n = vsnprintf(sb->buf+sb->pos, size, format, arg);
150  va_end(arg);
151 
152  if (n > -1 && (size_t)n < size) {
153  sb->pos += (size_t)n;
154  break;
155  }
156 
157  if (n > -1) {
158  size = n+1; /* precisely what is needed */
159  } else {
160  size *= 2; /* twice the old size */
161  }
162  }
163 }
164 
166  stringbuffer_ensure(sb, sb2->pos+1);
167  memcpy(sb->buf+sb->pos, sb2->buf, sb2->pos);
168  sb->pos += sb2->pos;
169 }
170 
174 static void stringbuffer_ensure(StringBuffer *sb, size_t len) {
175  char *tmp;
176  const size_t newlen = sb->pos+len;
177  if (newlen <= sb->size) {
178  return;
179  }
180 
181 #if 0
182  putchar('.');
183  fflush(stdout);
184 #endif
185 
186  do {
187  sb->size *= 1.5;
188  } while (newlen > sb->size);
189  tmp = static_cast<char *>(realloc(sb->buf, sb->size));
190  if (tmp == NULL) {
192  }
193  sb->buf = tmp;
194 }
195 
196 void stringbuffer_append_multiline_block(StringBuffer *sb, const char *start, const char *content, const char *end) {
197  char buf[100];
198  if (!content || *content == '\0') {
199  return;
200  }
201  if (end == NULL) {
202  snprintf(buf, sizeof(buf), "end_%s", start);
203  end = buf;
204  }
205  size_t ls = strlen(start), lc = strlen(content), le = strlen(end);
206  size_t added = ls + lc + le + 3; // At most 3 newlines to add.
207  stringbuffer_ensure(sb, added);
208  snprintf(sb->buf + sb->pos, sb->size - sb->pos, "%s\n%s", start, content);
209  sb->pos += ls + lc + 1;
210  if ((lc > 0) && (content[lc - 1] != '\n')) {
211  sb->buf[sb->pos] = '\n';
212  sb->pos++;
213  }
214  snprintf(sb->buf + sb->pos, sb->size - sb->pos, "%s\n", end);
215  sb->pos += le + 1;
216 }
217 
219  return sb->pos;
220 }
221 
223  while (sb->pos > 0 && isspace(sb->buf[sb->pos-1])) {
224  sb->pos--;
225  }
226 }
StringBuffer::size
size_t size
Definition: stringbuffer.cpp:42
global.h
stringbuffer_length
size_t stringbuffer_length(StringBuffer *sb)
Definition: stringbuffer.cpp:218
diamondslots.x
x
Definition: diamondslots.py:15
stringbuffer_append_printf
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.cpp:138
c
static event_registration c
Definition: citylife.cpp:425
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.cpp:57
StringBuffer::pos
size_t pos
Definition: stringbuffer.cpp:37
Ice.tmp
int tmp
Definition: Ice.py:207
stringbuffer_append_char
void stringbuffer_append_char(StringBuffer *sb, const char c)
Definition: stringbuffer.cpp:104
buf
StringBuffer * buf
Definition: readable.cpp:1611
stringbuffer_append_int64
void stringbuffer_append_int64(StringBuffer *sb, int64_t x)
Definition: stringbuffer.cpp:111
stringbuffer.h
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.cpp:76
rotate-tower.result
bool result
Definition: rotate-tower.py:13
stringbuffer_finish_shared
sstring stringbuffer_finish_shared(StringBuffer *sb)
Definition: stringbuffer.cpp:85
add_string
sstring add_string(const char *str)
Definition: shstr.cpp:124
StringBuffer::buf
char * buf
Definition: stringbuffer.cpp:30
make_face_from_files.str
str
Definition: make_face_from_files.py:24
sstring
const typedef char * sstring
Definition: global.h:43
stringbuffer_ensure
static void stringbuffer_ensure(StringBuffer *sb, size_t len)
Definition: stringbuffer.cpp:174
stringbuffer_append_string
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Definition: stringbuffer.cpp:95
fatal
void fatal(enum fatal_error err)
Definition: utils.cpp:580
StringBuffer
Definition: stringbuffer.cpp:25
stringbuffer_append_multiline_block
void stringbuffer_append_multiline_block(StringBuffer *sb, const char *start, const char *content, const char *end)
Definition: stringbuffer.cpp:196
stringbuffer_trim_whitespace
void stringbuffer_trim_whitespace(StringBuffer *sb)
Definition: stringbuffer.cpp:222
stringbuffer_delete
void stringbuffer_delete(StringBuffer *sb)
Definition: stringbuffer.cpp:71
stringbuffer_append_stringbuffer
void stringbuffer_append_stringbuffer(StringBuffer *sb, const StringBuffer *sb2)
Definition: stringbuffer.cpp:165
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
libproto.h