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

# User Rev Content
1 root 1.1 #include "global.h"
2    
3     #include <cstdio>
4    
5     dynbuf::dynbuf (int initial, int extend)
6     {
7 root 1.10 ext = extend;
8 root 1.1 _size = 0;
9 root 1.5
10 root 1.8 first = last = (chunk *)salloc<char> (sizeof (chunk) + initial);
11     first->alloc = sizeof (chunk) + initial;
12 root 1.1 first->next = 0;
13 root 1.8
14 root 1.5 ptr = first->data;
15 root 1.9 end = ptr + initial;
16 root 1.1 }
17    
18     dynbuf::~dynbuf ()
19     {
20 root 1.10 _clear ();
21 root 1.1 }
22    
23 root 1.5 void
24 root 1.10 dynbuf::_clear ()
25 root 1.1 {
26     while (first)
27     {
28     chunk *next = first->next;
29 root 1.5
30 root 1.8 sfree<char> ((char *)first, first->alloc);
31 root 1.1 first = next;
32     }
33 root 1.5 }
34 root 1.1
35 root 1.5 void
36 root 1.10 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 root 1.5 dynbuf::finish ()
51 root 1.1 {
52     // finalise current chunk
53     _size += last->size = ptr - last->data;
54     }
55    
56 root 1.5 void
57     dynbuf::_reserve (int size)
58 root 1.1 {
59     finish ();
60    
61     do
62     {
63     ext += ext >> 1;
64     ext = (ext + 15) & ~15;
65     }
66     while (ext < size);
67    
68 root 1.8 chunk *add = (chunk *) salloc<char> (sizeof (chunk) + ext);
69     add->alloc = sizeof (chunk) + ext;
70 root 1.1 add->next = 0;
71    
72     last->next = add;
73     last = add;
74    
75 root 1.5 ptr = last->data;
76 root 1.9 end = ptr + ext;
77 root 1.1 }
78    
79 root 1.5 void
80     dynbuf::linearise (void *data)
81 root 1.1 {
82     last->size = ptr - last->data;
83    
84 root 1.10 for (chunk *c = first; c; c = c->next)
85 root 1.1 {
86 root 1.10 memcpy (data, c->data, c->size);
87     data = (void *)(((char *)data) + c->size);
88 root 1.1 }
89     }
90    
91 root 1.5 char *
92     dynbuf::linearise ()
93 root 1.1 {
94     if (first->next)
95     {
96     finish ();
97    
98 root 1.8 chunk *add = (chunk *) salloc<char> (sizeof (chunk) + _size);
99     add->alloc = sizeof (chunk) + _size;
100     add->next = 0;
101 root 1.1
102 root 1.8 linearise ((void *)add->data);
103 root 1.10 _clear ();
104 root 1.1
105     first = last = add;
106 root 1.5 ptr = last->data + _size;
107 root 1.9 end = ptr;
108 root 1.1 _size = 0;
109     }
110    
111     return first->data;
112     }
113    
114 root 1.7 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 root 1.9 len = vsnprintf (ptr, end - ptr, format, ap);
131 root 1.7 va_end (ap);
132    
133     assert (len >= 0); // shield against broken vsnprintf's
134    
135     // was enough room available
136 root 1.9 if (ptr + len < end)
137 root 1.7 {
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 root 1.5 void
153 root 1.7 dynbuf_text::add (sint32 i)
154 root 1.1 {
155 root 1.5 char buf[max_sint32_size];
156 root 1.1 char *p = buf + sizeof (buf);
157     char neg;
158    
159 root 1.4 uint32 val;
160    
161 root 1.1 if (i < 0)
162     {
163     neg = '-';
164 root 1.4 val = -i;
165 root 1.1 }
166     else
167 root 1.4 {
168     neg = 0;
169     val = i;
170     }
171 root 1.1
172     do
173     {
174     uint32 div = val / 10;
175     *--p = '0' + char (val - div * 10);
176 root 1.5
177 root 1.1 val = div;
178     }
179     while (val);
180    
181     if (neg)
182     *--p = neg;
183    
184 root 1.5 add ((void *) p, buf + sizeof (buf) - p);
185 root 1.1 }
186    
187 root 1.5 void
188 root 1.7 dynbuf_text::add (sint64 i)
189 root 1.1 {
190     if (i > -10000000 && i < 10000000)
191     {
192     add (sint32 (i));
193     return;
194     }
195    
196 root 1.5 char buf[max_sint64_size];
197 root 1.4 char *p = buf + sizeof (buf);
198     char neg;
199    
200 root 1.2 uint64 val;
201    
202 root 1.1 if (i < 0)
203     {
204 root 1.4 neg = '-';
205 root 1.2 val = -i;
206 root 1.1 }
207 root 1.2 else
208 root 1.1 {
209 root 1.4 neg = 0;
210     val = i;
211 root 1.1 }
212    
213 root 1.4 do
214 root 1.1 {
215 root 1.4 uint64 div = val / 10;
216     *--p = '0' + char (val - div * 10);
217 root 1.5
218 root 1.4 val = div;
219 root 1.1 }
220 root 1.4 while (val);
221 root 1.1
222 root 1.4 if (neg)
223     *--p = neg;
224    
225 root 1.5 add ((void *) p, buf + sizeof (buf) - p);
226 root 1.1 }