Crossfire Server, Branches 1.12  R18729
stringbuffer.c
Go to the documentation of this file.
1 /*
2  CrossFire, A Multiplayer game for X-windows
3 
4  Copyright (C) 2008 Crossfire Development Team
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 
20  The authors can be reached via e-mail at crossfire-devel@real-time.com
21 */
22 
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "global.h"
28 #include "libproto.h"
29 #include "stringbuffer.h"
30 
31 
32 struct StringBuffer {
37  char *buf;
38 
44  size_t pos;
45 
49  size_t size;
50 };
51 
52 
61 static void stringbuffer_ensure(StringBuffer *sb, size_t len);
62 
63 
65  StringBuffer *sb;
66 
67  sb = malloc(sizeof(*sb));
68  if (sb == NULL) {
70  }
71 
72  sb->size = 256;
73  sb->buf = malloc(sb->size);
74  sb->pos = 0;
75  return sb;
76 }
77 
79  char *result;
80 
81  sb->buf[sb->pos] = '\0';
82  result = sb->buf;
83  free(sb);
84  return result;
85 }
86 
88  char *str;
89  sstring result;
90 
91  str = stringbuffer_finish(sb);
92  result = add_string(str);
93  free(str);
94  return result;
95 }
96 
97 void stringbuffer_append_string(StringBuffer *sb, const char *str) {
98  size_t len;
99 
100  len = strlen(str);
101  stringbuffer_ensure(sb, len+1);
102  memcpy(sb->buf+sb->pos, str, len);
103  sb->pos += len;
104 }
105 
106 void stringbuffer_append_printf(StringBuffer *sb, const char *format, ...) {
107  size_t size;
108 
109  size = 100; /* arbitrary guess */
110  for (;;) {
111  int n;
112  va_list arg;
113 
114  stringbuffer_ensure(sb, size);
115 
116  va_start(arg, format);
117  n = vsnprintf(sb->buf+sb->pos, size, format, arg);
118  va_end(arg);
119 
120  if (n > -1 && (size_t)n < size) {
121  sb->pos += (size_t)n;
122  break;
123  }
124 
125  if (n > -1) {
126  size = n+1; /* precisely what is needed */
127  } else {
128  size *= 2; /* twice the old size */
129  }
130  }
131 }
132 
134  stringbuffer_ensure(sb, sb2->pos+1);
135  memcpy(sb->buf+sb->pos, sb2->buf, sb2->pos);
136  sb->pos += sb2->pos;
137 }
138 
139 static void stringbuffer_ensure(StringBuffer *sb, size_t len) {
140  char *tmp;
141  size_t new_size;
142 
143  if (sb->pos+len <= sb->size) {
144  return;
145  }
146 
147  new_size = sb->pos+len+256;
148  tmp = realloc(sb->buf, new_size);
149  if (tmp == NULL) {
151  }
152  sb->buf = tmp;
153  sb->size = new_size;
154 }
#define OUT_OF_MEMORY
Definition: define.h:94
void stringbuffer_append_stringbuffer(StringBuffer *sb, const StringBuffer *sb2)
Definition: stringbuffer.c:133
sstring stringbuffer_finish_shared(StringBuffer *sb)
Definition: stringbuffer.c:87
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:64
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Definition: stringbuffer.c:97
void fatal(int err)
Definition: glue.c:60
static void stringbuffer_ensure(StringBuffer *sb, size_t len)
Definition: stringbuffer.c:139
const char * sstring
Definition: global.h:84
#define vsnprintf
Definition: win32.h:72
sstring add_string(const char *str)
Definition: shstr.c:116
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.c:106
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:78