Crossfire Server, Trunk  R213250
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 
89  str = stringbuffer_finish(sb);
90  result = add_string(str);
91  free(str);
92  return result;
93 }
94 
95 void stringbuffer_append_string(StringBuffer *sb, const char *str) {
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 
163  return sb->pos;
164 }
void stringbuffer_append_stringbuffer(StringBuffer *sb, const StringBuffer *sb2)
Definition: stringbuffer.c:131
sstring stringbuffer_finish_shared(StringBuffer *sb)
Definition: stringbuffer.c:85
void fatal(enum fatal_error err)
Definition: utils.c:597
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Definition: stringbuffer.c:95
size_t stringbuffer_length(StringBuffer *sb)
Definition: stringbuffer.c:162
static void stringbuffer_ensure(StringBuffer *sb, size_t len)
Definition: stringbuffer.c:140
const char * sstring
Definition: global.h:40
#define vsnprintf
Definition: win32.h:61
void stringbuffer_delete(StringBuffer *sb)
Definition: stringbuffer.c:71
sstring add_string(const char *str)
Definition: shstr.c:124
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.c:104
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76