ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/dynbuf.C
Revision: 1.7
Committed: Mon Apr 23 18:09:57 2007 UTC (17 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.6: +40 -2 lines
Log Message:
- add format utility function.
- split dynbuf into dynbuf and dynbuf_text.
- use dynbuf_text for examine strings instead of
  outputting each line seperately. tried to use stringstreams
  but they add insane overheads (as does std::string, but less so).

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