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

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