ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/dynbuf.C
Revision: 1.8
Committed: Mon Apr 23 18:21:54 2007 UTC (17 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.7: +10 -7 lines
Log Message:
use g_slice for dynbufs

File Contents

# Content
1 #include "global.h"
2
3 #include <cstdio>
4
5 dynbuf::dynbuf (int initial, int extend)
6 {
7 _size = 0;
8 ext = extend;
9
10 first = last = (chunk *)salloc<char> (sizeof (chunk) + initial);
11 first->alloc = sizeof (chunk) + initial;
12 first->next = 0;
13
14 room = initial;
15 ptr = first->data;
16 }
17
18 dynbuf::~dynbuf ()
19 {
20 clear ();
21 }
22
23 void
24 dynbuf::clear ()
25 {
26 while (first)
27 {
28 chunk *next = first->next;
29
30 sfree<char> ((char *)first, first->alloc);
31 first = next;
32 }
33 }
34
35 void
36 dynbuf::finish ()
37 {
38 // finalise current chunk
39 _size += last->size = ptr - last->data;
40 }
41
42 void
43 dynbuf::_reserve (int size)
44 {
45 finish ();
46
47 do
48 {
49 ext += ext >> 1;
50 ext = (ext + 15) & ~15;
51 }
52 while (ext < size);
53
54 chunk *add = (chunk *) salloc<char> (sizeof (chunk) + ext);
55 add->alloc = sizeof (chunk) + ext;
56 add->next = 0;
57
58 last->next = add;
59 last = add;
60
61 room = ext;
62 ptr = last->data;
63 }
64
65 void
66 dynbuf::linearise (void *data)
67 {
68 char *p = (char *) data;
69
70 last->size = ptr - last->data;
71
72 for (chunk * c = first; c; c = c->next)
73 {
74 memcpy (p, c->data, c->size);
75 p += c->size;
76 }
77 }
78
79 char *
80 dynbuf::linearise ()
81 {
82 if (first->next)
83 {
84 finish ();
85
86 chunk *add = (chunk *) salloc<char> (sizeof (chunk) + _size);
87 add->alloc = sizeof (chunk) + _size;
88 add->next = 0;
89
90 linearise ((void *)add->data);
91 clear ();
92
93 first = last = add;
94 ptr = last->data + _size;
95 _size = 0;
96 room = 0;
97 }
98
99 return first->data;
100 }
101
102 dynbuf::operator std::string ()
103 {
104 // could optimise
105 return std::string (linearise (), size ());
106 }
107
108 void
109 dynbuf_text::printf (const char *format, ...)
110 {
111 int len;
112
113 {
114 force (128);
115
116 va_list ap;
117 va_start (ap, format);
118 len = vsnprintf (ptr, room, format, ap);
119 va_end (ap);
120
121 assert (len >= 0); // shield against broken vsnprintf's
122
123 // was enough room available
124 if (len < room)
125 {
126 alloc (len);
127 return;
128 }
129 }
130
131 // longer, try harder
132 va_list ap;
133 va_start (ap, format);
134 vsnprintf (force (len + 1), len + 1, format, ap);
135 va_end (ap);
136
137 alloc (len);
138 }
139
140 void
141 dynbuf_text::add (sint32 i)
142 {
143 char buf[max_sint32_size];
144 char *p = buf + sizeof (buf);
145 char neg;
146
147 uint32 val;
148
149 if (i < 0)
150 {
151 neg = '-';
152 val = -i;
153 }
154 else
155 {
156 neg = 0;
157 val = i;
158 }
159
160 do
161 {
162 uint32 div = val / 10;
163 *--p = '0' + char (val - div * 10);
164
165 val = div;
166 }
167 while (val);
168
169 if (neg)
170 *--p = neg;
171
172 add ((void *) p, buf + sizeof (buf) - p);
173 }
174
175 void
176 dynbuf_text::add (sint64 i)
177 {
178 if (i > -10000000 && i < 10000000)
179 {
180 add (sint32 (i));
181 return;
182 }
183
184 char buf[max_sint64_size];
185 char *p = buf + sizeof (buf);
186 char neg;
187
188 uint64 val;
189
190 if (i < 0)
191 {
192 neg = '-';
193 val = -i;
194 }
195 else
196 {
197 neg = 0;
198 val = i;
199 }
200
201 do
202 {
203 uint64 div = val / 10;
204 *--p = '0' + char (val - div * 10);
205
206 val = div;
207 }
208 while (val);
209
210 if (neg)
211 *--p = neg;
212
213 add ((void *) p, buf + sizeof (buf) - p);
214 }