Crossfire Server, Trunk
stringbuffer.c
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 = malloc(sizeof(*sb));
61  if (sb == NULL) {
63  }
64 
65  sb->size = 512;
66  sb->buf = 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;
87  sstring result;
88 
90  result = add_string(str);
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_printf(StringBuffer *sb, const char *format, ...) {
105  size_t size;
106 
107  size = 100; /* arbitrary guess */
108  for (;;) {
109  int n;
110  va_list arg;
111 
112  stringbuffer_ensure(sb, size);
113 
114  va_start(arg, format);
115  n = vsnprintf(sb->buf+sb->pos, size, format, arg);
116  va_end(arg);
117 
118  if (n > -1 && (size_t)n < size) {
119  sb->pos += (size_t)n;
120  break;
121  }
122 
123  if (n > -1) {
124  size = n+1; /* precisely what is needed */
125  } else {
126  size *= 2; /* twice the old size */
127  }
128  }
129 }
130 
132  stringbuffer_ensure(sb, sb2->pos+1);
133  memcpy(sb->buf+sb->pos, sb2->buf, sb2->pos);
134  sb->pos += sb2->pos;
135 }
136 
140 static void stringbuffer_ensure(StringBuffer *sb, size_t len) {
141  char *tmp;
142  const size_t newlen = sb->pos+len;
143  if (newlen <= sb->size) {
144  return;
145  }
146 
147 #if 0
148  putchar('.');
149  fflush(stdout);
150 #endif
151 
152  do {
153  sb->size *= 1.5;
154  } while (newlen > sb->size);
155  tmp = realloc(sb->buf, sb->size);
156  if (tmp == NULL) {
158  }
159  sb->buf = tmp;
160 }
161 
162 void stringbuffer_append_multiline_block(StringBuffer *sb, const char *start, const char *content, const char *end) {
163  char buf[100];
164  if (!content || *content == '\0') {
165  return;
166  }
167  if (end == NULL) {
168  snprintf(buf, sizeof(buf), "end_%s", start);
169  end = buf;
170  }
171  size_t ls = strlen(start), lc = strlen(content), le = strlen(end);
172  size_t added = ls + lc + le + 3; // At most 3 newlines to add.
173  stringbuffer_ensure(sb, added);
174  snprintf(sb->buf + sb->pos, sb->size - sb->pos, "%s\n%s", start, content);
175  sb->pos += ls + lc + 1;
176  if ((lc > 0) && (content[lc - 1] != '\n')) {
177  sb->buf[sb->pos] = '\n';
178  sb->pos++;
179  }
180  snprintf(sb->buf + sb->pos, sb->size - sb->pos, "%s\n", end);
181  sb->pos += le + 1;
182 }
183 
185  return sb->pos;
186 }
187 
189  while (sb->pos > 0 && isspace(sb->buf[sb->pos-1])) {
190  sb->pos--;
191  }
192 }
StringBuffer::size
size_t size
Definition: stringbuffer.c:42
global.h
add_string
sstring add_string(const char *str)
Definition: shstr.c:124
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
StringBuffer::pos
size_t pos
Definition: stringbuffer.c:37
Ice.tmp
int tmp
Definition: Ice.py:207
stringbuffer.h
stringbuffer_trim_whitespace
void stringbuffer_trim_whitespace(StringBuffer *sb)
Definition: stringbuffer.c:188
stringbuffer_finish_shared
sstring stringbuffer_finish_shared(StringBuffer *sb)
Definition: stringbuffer.c:85
fatal
void fatal(enum fatal_error err)
Definition: utils.c:597
stringbuffer_append_string
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Definition: stringbuffer.c:95
StringBuffer::buf
char * buf
Definition: stringbuffer.c:30
make_face_from_files.str
str
Definition: make_face_from_files.py:24
stringbuffer_ensure
static void stringbuffer_ensure(StringBuffer *sb, size_t len)
Definition: stringbuffer.c:140
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76
sstring
const typedef char * sstring
Definition: global.h:40
StringBuffer
Definition: stringbuffer.c:25
stringbuffer_append_multiline_block
void stringbuffer_append_multiline_block(StringBuffer *sb, const char *start, const char *content, const char *end)
Definition: stringbuffer.c:162
stringbuffer_length
size_t stringbuffer_length(StringBuffer *sb)
Definition: stringbuffer.c:184
buf
StringBuffer * buf
Definition: readable.c:1606
stringbuffer_append_printf
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.c:104
stringbuffer_append_stringbuffer
void stringbuffer_append_stringbuffer(StringBuffer *sb, const StringBuffer *sb2)
Definition: stringbuffer.c:131
stringbuffer_delete
void stringbuffer_delete(StringBuffer *sb)
Definition: stringbuffer.c:71
OUT_OF_MEMORY
@ OUT_OF_MEMORY
Definition: define.h:48
libproto.h