ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/dynbuf.C
(Generate patch)

Comparing deliantra/server/server/dynbuf.C (file contents):
Revision 1.23 by root, Thu Sep 11 21:36:07 2008 UTC vs.
Revision 1.31 by root, Fri Mar 26 01:04:45 2010 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * 5 *
6 * Deliantra is free software: you can redistribute it and/or modify 6 * Deliantra is free software: you can redistribute it and/or modify it under
7 * it under the terms of the GNU General Public License as published by 7 * the terms of the Affero GNU General Public License as published by the
8 * the Free Software Foundation, either version 3 of the License, or 8 * Free Software Foundation, either version 3 of the License, or (at your
9 * (at your option) any later version. 9 * option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the Affero GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * and the GNU General Public License along with this program. If not, see
18 * <http://www.gnu.org/licenses/>.
18 * 19 *
19 * The authors can be reached via e-mail to <support@deliantra.net> 20 * The authors can be reached via e-mail to <support@deliantra.net>
20 */ 21 */
21 22
22#include "global.h" 23#include "global.h"
103 data = (void *)(((char *)data) + c->size); 104 data = (void *)(((char *)data) + c->size);
104 } 105 }
105} 106}
106 107
107char * 108char *
108dynbuf::_linearise () 109dynbuf::_linearise (int extra)
109{ 110{
110 finalise (); 111 finalise ();
111 112
112 chunk *add = (chunk *) salloc<char> (sizeof (chunk) + _size); 113 chunk *add = (chunk *) salloc<char> (sizeof (chunk) + _size + extra);
113 add->alloc = sizeof (chunk) + _size; 114 add->alloc = sizeof (chunk) + _size;
114 add->next = 0; 115 add->next = 0;
115 116
116 linearise ((void *)add->data); 117 linearise ((void *)add->data);
117 free (first); 118 free (first);
118 119
119 first = last = add; 120 first = last = add;
120 ptr = last->data + _size; 121 ptr = last->data + _size;
121 end = ptr; 122 end = ptr + extra;
122 _size = 0; 123 _size = 0;
123 124
124 return first->data; 125 return first->data;
125} 126}
126 127
127dynbuf::operator std::string () 128dynbuf::operator std::string ()
128{ 129{
129 // could optimise 130 // could optimise
130 return std::string (linearise (), size ()); 131 return std::string (linearise (), size ());
132}
133
134void
135dynbuf::splice (int offset, int olen, const char *s, int slen)
136{
137 // how much bytes to extend (negative if shrinking)
138 int adjust = slen - olen;
139
140 // linearise, unless everything fits in the last chunk
141 if (offset < _size || room () < adjust)
142 _linearise (max (adjust, 0));
143
144 offset -= _size; // offset into chunk
145
146 // now move tail to final position
147 char *pos = last->data + offset;
148 char *src = pos + olen;
149 char *dst = pos + slen;
150 memmove (dst, src, ptr - src);
151
152 // now copy new content
153 memcpy (pos, s, slen);
154
155 // finally adjust length
156 ptr += adjust;
131} 157}
132 158
133void 159void
134dynbuf_text::vprintf (const char *format, va_list ap) 160dynbuf_text::vprintf (const char *format, va_list ap)
135{ 161{
167 vprintf (format, ap); 193 vprintf (format, ap);
168 va_end (ap); 194 va_end (ap);
169} 195}
170 196
171// simply return a mask with "bits" bits set 197// simply return a mask with "bits" bits set
172inline uint64 198static inline uint64
173m (int b) 199m (int b)
174{ 200{
175 return (uint64 (1) << b) - 1; 201 return (uint64 (1) << b) - 1;
176} 202}
177 203
178// convert 9 digits to ascii, using only a single multiplication 204// convert 9 digits to ascii, using only a single multiplication
179// (depending on cpu and compiler). 205// (depending on cpu and compiler).
180// will generate a single 0 as output when v=lz=0 206// will generate a single 0 as output when v=lz=0
181inline char * 207static inline char *
182i2a_9 (char *ptr, uint32 v, bool lz) 208i2a_9 (char *ptr, uint32 v, bool lz)
183{ 209{
184 // convert to 4.56 fixed-point representation 210 // convert to 4.56 fixed-point representation
185 // this should be optimal on 64 bit cpus, and rather 211 // this should be optimal on 64 bit cpus, and rather
186 // slow on 32 bit cpus. go figure :) 212 // slow on 32 bit cpus. go figure :)
229 255
230 *ptr = '-'; ptr += i < 0 ? 1 : 0; 256 *ptr = '-'; ptr += i < 0 ? 1 : 0;
231 uint32 u = i < 0 ? -i : i; 257 uint32 u = i < 0 ? -i : i;
232 258
233 if (expect_true (u < 10)) // we have a lot of single-digit numbers, so optimise 259 if (expect_true (u < 10)) // we have a lot of single-digit numbers, so optimise
234 fadd (char (u + '0')); 260 *ptr++ = u + '0';
261 else if (expect_true (u < 100)) // we have a lot of double-digit numbers, too :)
262 {
263 // let the compiler figure out sth. efficient here
264 *ptr++ = u / 10 + '0';
265 *ptr++ = u % 10 + '0';
266 }
235 else if (expect_true (u < 1000000000)) // 9 0's 267 else if (expect_true (u < 1000000000)) // 9 0's
236 ptr = i2a_9 (ptr, u, false); 268 ptr = i2a_9 (ptr, u, false);
237 else 269 else
238 { 270 {
239 sint32 div = u / 1000000000; 271 uint32 div = u / 1000000000;
240 uint32 rem = u % 1000000000; 272 uint32 rem = u % 1000000000;
241 273
242 ptr = i2a_9 (ptr, div, false); 274 ptr = i2a_9 (ptr, div, false);
243 ptr = i2a_9 (ptr, rem, true); 275 ptr = i2a_9 (ptr, rem, true);
244 } 276 }
256 // (#19) and two 9 digit parts (9..18 and 0..8) 288 // (#19) and two 9 digit parts (9..18 and 0..8)
257 289
258 // good compilers will only use multiplications here 290 // good compilers will only use multiplications here
259 291
260 if (u < 10) // we have a lot of single-digit numbers, so optimise 292 if (u < 10) // we have a lot of single-digit numbers, so optimise
261 fadd (char (u + '0')); 293 *ptr++ = u + '0';
262 else if (expect_true (u < 1000000000)) // 9 0's 294 else if (expect_true (u < 1000000000)) // 9 0's
263 ptr = i2a_9 (ptr, u, false); 295 ptr = i2a_9 (ptr, u, false);
264 else if (expect_true (u < UINT64_C (1000000000000000000))) // 18 0's 296 else if (expect_true (u < UINT64_C (1000000000000000000))) // 18 0's
265 { 297 {
266 sint32 div = u / 1000000000; 298 uint32 div = u / 1000000000;
267 uint32 rem = u % 1000000000; 299 uint32 rem = u % 1000000000;
268 300
269 ptr = i2a_9 (ptr, div, false); 301 ptr = i2a_9 (ptr, div, false);
270 ptr = i2a_9 (ptr, rem, true); 302 ptr = i2a_9 (ptr, rem, true);
271 } 303 }
272 else 304 else
273 { 305 {
274 // a biggy 306 // a biggy, split off the topmost digit
275 sint32 div = u / UINT64_C (1000000000000000000); 307 uint32 div = u / UINT64_C (1000000000000000000);
276 uint64 rem = u % UINT64_C (1000000000000000000); 308 uint64 rem = u % UINT64_C (1000000000000000000);
277 309
278 fadd (char (div + '0')); 310 *ptr++ = div + '0';
311
279 u = rem; 312 u = rem;
280 313
281 { 314 {
282 sint32 div = u / 1000000000; 315 uint32 div = u / 1000000000;
283 uint32 rem = u % 1000000000; 316 uint32 rem = u % 1000000000;
284 317
285 ptr = i2a_9 (ptr, div, true); 318 ptr = i2a_9 (ptr, div, true);
286 ptr = i2a_9 (ptr, rem, true); 319 ptr = i2a_9 (ptr, rem, true);
287 } 320 }
288 } 321 }
289} 322}
290 323
291dynbuf_text::operator const char *() 324dynbuf_text::operator char *()
292{ 325{
293 *this << '\0'; 326 *this << '\0';
294 linearise (); 327 linearise ();
295 --ptr; 328 --ptr;
296 return first->data; 329 return first->data;
303 return; 336 return;
304 337
305 *this << '(' << name; 338 *this << '(' << name;
306 339
307 const char *sep = ": "; 340 const char *sep = ": ";
308 for (int i = 0; i < NROFATTACKS; ++i) 341 for_all_bits_sparse_32 (abilities, i)
309 if (abilities & (1 << i))
310 { 342 {
311 *this << sep; sep = ", "; 343 *this << sep; sep = ", ";
312 *this << attacks [i]; 344 *this << attacks [i];
313 } 345 }
314 346
315 *this << ')'; 347 *this << ')';
316} 348}
317 349
318void 350void

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines