ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/dynbuf.C
Revision: 1.10
Committed: Thu May 3 09:26:45 2007 UTC (17 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.9: +21 -9 lines
Log Message:
only allow one range weapon to be applied at any one time, some dynbuf fixes

File Contents

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