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 }
global.h
stringbuffer_length
size_t stringbuffer_length(StringBuffer *sb)
Definition: stringbuffer.cpp:218
StringBuffer::pos
size_t pos
Definition: stringbuffer.cpp:37
diamondslots.x
x
Definition: diamondslots.py:15
n
based on the size of the this randomly makes land number of spaces randomly lower or higher The default is Note that this is run also based on the the altitude amount will likely be less So if you do something like l and n
Definition: land.6.txt:25
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::size
size_t size
Definition: stringbuffer.cpp:42
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:1552
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
make_face_from_files.str
str
Definition: make_face_from_files.py:30
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
stringbuffer_append_multiline_block
void stringbuffer_append_multiline_block(StringBuffer *sb, const char *start, const char *content, const char *end)
Definition: stringbuffer.cpp:196
fatal
void fatal(enum fatal_error err)
Definition: utils.cpp:570
stringbuffer_trim_whitespace
void stringbuffer_trim_whitespace(StringBuffer *sb)
Definition: stringbuffer.cpp:222
stringbuffer_delete
void stringbuffer_delete(StringBuffer *sb)
Definition: stringbuffer.cpp:71
sstring
const typedef char * sstring
Definition: sstring.h:2
format
Python Guilds Quick outline Add a guild(mapmakers) this is still a problem *after dropping the token to gain access to the stove a woodfloor now appears which is Toolshed Token(found in Guild_HQ) *Note also have multiple gates in place to protect players and items from the mana explosion drop x for Jewelers room *Jewelers room works just need to determine what x is drop x for Thaumaturgy room *Thaumaturgy room works just need to determine what x is drop gold dropping the Firestar named fearless allows access to but I suspect that the drop location of the chest is not as intended because the player is in the way once you enter the chest the exit back to the basement is things such as the message et al reside on teleporters which then transport items to the map as they are when the map is already purchased items reappear in that area From my this does not cause any problems at the moment But this should be corrected fixed Major it s now possible to buy guilds Ryo Update Uploaded guild package to CVS Changes the cauldrons and the charging room I spent a while agonizing over They were natural guild enhancements but much too much value for any reasonable expense to buy them Then I thought that they should be pay access but at a greatly reduced rate SO when you buy a forge or whatever for your guild it is available on a perplayer daily rate but it will be accessable for testing and to DMs to play with Like I said lots still to do with the especially comingt up with quest items for buying things like the new workshops and stuff One of the things I would like some input on would be proposals for additional fields for either the guildhouses or guild datafiles to play with Currently the Guildhouse but there is no reason we can t have more than one measure of a guild perhaps have dues relate to Dues and use points for some other suspended or inactive or when a guild is founded inactive active Guilds have the format
Definition: README.txt:140
stringbuffer_append_stringbuffer
void stringbuffer_append_stringbuffer(StringBuffer *sb, const StringBuffer *sb2)
Definition: stringbuffer.cpp:165
StringBuffer
Definition: stringbuffer.cpp:25
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
libproto.h
StringBuffer::buf
char * buf
Definition: stringbuffer.cpp:30