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

# User Rev Content
1 root 1.1 #include "global.h"
2    
3     #include <cstdio>
4    
5     dynbuf::dynbuf (int initial, int extend)
6     {
7     _size = 0;
8 root 1.5 ext = extend;
9    
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 room = initial;
15     ptr = first->data;
16 root 1.1 }
17    
18     dynbuf::~dynbuf ()
19     {
20     clear ();
21     }
22    
23 root 1.5 void
24     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     dynbuf::finish ()
37 root 1.1 {
38     // finalise current chunk
39     _size += last->size = ptr - last->data;
40     }
41    
42 root 1.5 void
43     dynbuf::_reserve (int size)
44 root 1.1 {
45     finish ();
46    
47     do
48     {
49     ext += ext >> 1;
50     ext = (ext + 15) & ~15;
51     }
52     while (ext < size);
53    
54 root 1.8 chunk *add = (chunk *) salloc<char> (sizeof (chunk) + ext);
55     add->alloc = sizeof (chunk) + ext;
56 root 1.1 add->next = 0;
57    
58     last->next = add;
59     last = add;
60    
61     room = ext;
62 root 1.5 ptr = last->data;
63 root 1.1 }
64    
65 root 1.5 void
66     dynbuf::linearise (void *data)
67 root 1.1 {
68 root 1.5 char *p = (char *) data;
69 root 1.1
70     last->size = ptr - last->data;
71    
72 root 1.5 for (chunk * c = first; c; c = c->next)
73 root 1.1 {
74     memcpy (p, c->data, c->size);
75     p += c->size;
76     }
77     }
78    
79 root 1.5 char *
80     dynbuf::linearise ()
81 root 1.1 {
82     if (first->next)
83     {
84     finish ();
85    
86 root 1.8 chunk *add = (chunk *) salloc<char> (sizeof (chunk) + _size);
87     add->alloc = sizeof (chunk) + _size;
88     add->next = 0;
89 root 1.1
90 root 1.8 linearise ((void *)add->data);
91 root 1.1 clear ();
92    
93     first = last = add;
94 root 1.5 ptr = last->data + _size;
95 root 1.1 _size = 0;
96 root 1.5 room = 0;
97 root 1.1 }
98    
99     return first->data;
100     }
101    
102 root 1.7 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 root 1.5 void
141 root 1.7 dynbuf_text::add (sint32 i)
142 root 1.1 {
143 root 1.5 char buf[max_sint32_size];
144 root 1.1 char *p = buf + sizeof (buf);
145     char neg;
146    
147 root 1.4 uint32 val;
148    
149 root 1.1 if (i < 0)
150     {
151     neg = '-';
152 root 1.4 val = -i;
153 root 1.1 }
154     else
155 root 1.4 {
156     neg = 0;
157     val = i;
158     }
159 root 1.1
160     do
161     {
162     uint32 div = val / 10;
163     *--p = '0' + char (val - div * 10);
164 root 1.5
165 root 1.1 val = div;
166     }
167     while (val);
168    
169     if (neg)
170     *--p = neg;
171    
172 root 1.5 add ((void *) p, buf + sizeof (buf) - p);
173 root 1.1 }
174    
175 root 1.5 void
176 root 1.7 dynbuf_text::add (sint64 i)
177 root 1.1 {
178     if (i > -10000000 && i < 10000000)
179     {
180     add (sint32 (i));
181     return;
182     }
183    
184 root 1.5 char buf[max_sint64_size];
185 root 1.4 char *p = buf + sizeof (buf);
186     char neg;
187    
188 root 1.2 uint64 val;
189    
190 root 1.1 if (i < 0)
191     {
192 root 1.4 neg = '-';
193 root 1.2 val = -i;
194 root 1.1 }
195 root 1.2 else
196 root 1.1 {
197 root 1.4 neg = 0;
198     val = i;
199 root 1.1 }
200    
201 root 1.4 do
202 root 1.1 {
203 root 1.4 uint64 div = val / 10;
204     *--p = '0' + char (val - div * 10);
205 root 1.5
206 root 1.4 val = div;
207 root 1.1 }
208 root 1.4 while (val);
209 root 1.1
210 root 1.4 if (neg)
211     *--p = neg;
212    
213 root 1.5 add ((void *) p, buf + sizeof (buf) - p);
214 root 1.1 }