ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/dynbuf.C
Revision: 1.3
Committed: Fri Sep 1 21:39:59 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.2: +1 -1 lines
Log Message:
fix bad, bad bug

File Contents

# User Rev Content
1 root 1.2 #define __STDC_CONSTANT_MACROS
2     #include <stdint.h>
3    
4     #ifndef UINT64_C
5     # error missing c99 support, define UINT64_C yourself
6     # define UINT64_C(c) c ## LL
7     #endif
8    
9 root 1.1 #include "global.h"
10    
11     #include <cstdio>
12    
13     dynbuf::dynbuf (int initial, int extend)
14     {
15     _size = 0;
16     ext = extend;
17     first = last = (chunk *)new char [sizeof (chunk) + initial];
18     first->next = 0;
19     room = initial;
20     ptr = first->data;
21     }
22    
23     dynbuf::~dynbuf ()
24     {
25     clear ();
26     }
27    
28     void dynbuf::clear ()
29     {
30     while (first)
31     {
32     chunk *next = first->next;
33     delete [] (char *)first;
34     first = next;
35     }
36     }
37    
38     void dynbuf::finish ()
39     {
40     // finalise current chunk
41     _size += last->size = ptr - last->data;
42     }
43    
44     void dynbuf::_reserve (int size)
45     {
46     finish ();
47    
48     do
49     {
50     ext += ext >> 1;
51     ext = (ext + 15) & ~15;
52     }
53     while (ext < size);
54    
55     chunk *add = (chunk *)new char [sizeof (chunk) + ext];
56     add->next = 0;
57    
58     last->next = add;
59     last = add;
60    
61     room = ext;
62     ptr = last->data;
63     }
64    
65     void dynbuf::linearise (void *data)
66     {
67     char *p = (char *)data;
68    
69     last->size = ptr - last->data;
70    
71     for (chunk *c = first; c; c = c->next)
72     {
73     memcpy (p, c->data, c->size);
74     p += c->size;
75     }
76     }
77    
78     char *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     void dynbuf::add (sint32 i)
100     {
101     char buf [max_sint32_size];
102     char *p = buf + sizeof (buf);
103     char neg;
104    
105     if (i < 0)
106     {
107     neg = '-';
108     i = -i;
109     }
110     else
111     neg = 0;
112    
113     uint32 val = i;
114    
115     do
116     {
117     uint32 div = val / 10;
118     *--p = '0' + char (val - div * 10);
119     val = div;
120     }
121     while (val);
122    
123     if (neg)
124     *--p = neg;
125    
126     add ((void *)p, buf + sizeof (buf) - p);
127     }
128    
129     void dynbuf::add (sint64 i)
130     {
131     if (i > -10000000 && i < 10000000)
132     {
133     add (sint32 (i));
134     return;
135     }
136    
137 root 1.2 uint64 val;
138    
139 root 1.1 if (i < 0)
140     {
141     add ('-');
142 root 1.2 val = -i;
143 root 1.1 }
144 root 1.2 else
145     val = i;
146 root 1.1
147 root 1.2 if (val > UINT64_C (1000000000000000))
148 root 1.1 {
149 root 1.2 add (sint32 (val / UINT64_C (1000000000000000)));
150     val %= UINT64_C (1000000000000000);
151 root 1.1 }
152    
153 root 1.2 if (val > 10000000)
154 root 1.1 {
155 root 1.2 add (sint32 (val / 10000000));
156     val %= 10000000;
157 root 1.1 }
158    
159 root 1.3 add (sint32 (val));
160 root 1.1 }
161