Line data Source code
1 : // implementation of generic tools
2 :
3 : #include "../libprimis-headers/cube.h"
4 : #include "stream.h"
5 :
6 : ////////////////////////// strings ////////////////////////////////////////
7 :
8 6 : char *tempformatstring(const char *fmt, ...)
9 : {
10 : static string tmpstr[4];
11 : static int tmpidx = 0;
12 6 : tmpidx = (tmpidx+1)%4;
13 :
14 : va_list v;
15 6 : va_start(v, fmt);
16 6 : vformatstring(tmpstr[tmpidx], fmt, v);
17 6 : va_end(v);
18 :
19 6 : return tmpstr[tmpidx];
20 : }
21 :
22 : ////////////////////////// bit packing ////////////////////////////////////
23 :
24 : // these functions are useful for packing ints/chars into smaller chunks, which
25 : // is useful for reducing file save sizes
26 :
27 : // note that the parent put*_ template functions is not defined here but in tools.h
28 :
29 : //* signed integers *//
30 13 : void putint(ucharbuf &p, int n)
31 : {
32 13 : putint_(p, n);
33 13 : }
34 :
35 : //Stores the passed integer into a uchar array, by splitting it into four bytes.
36 2 : void putint(std::vector<uchar> &p, int n)
37 : {
38 2 : p.push_back((n >> 24) & 0xFF);
39 2 : p.push_back((n >> 16) & 0xFF);
40 2 : p.push_back((n >> 8 ) & 0xFF);
41 2 : p.push_back(n & 0xFF);
42 2 : }
43 :
44 : //Removes the last four values from the uchar array, returning its int representation.
45 2 : int getint(std::vector<uchar> &p)
46 : {
47 2 : int a = 0;
48 2 : a += static_cast<int>(p.back());
49 2 : p.pop_back();
50 2 : a += static_cast<int>(p.back()) << 8;
51 2 : p.pop_back();
52 2 : a += static_cast<int>(p.back()) << 16;
53 2 : p.pop_back();
54 2 : a += static_cast<int>(p.back()) << 24;
55 2 : p.pop_back();
56 2 : return a;
57 : }
58 :
59 : //Stores the passed float into a uchar array, by splitting it into four bytes.
60 2 : void putfloat(std::vector<uchar> &p, float n)
61 : {
62 : uchar arr[sizeof(float)];
63 2 : std::memcpy(arr, &n, sizeof(float));
64 10 : for(unsigned long i = 0; i < sizeof(float); ++i)
65 : {
66 8 : p.push_back(arr[sizeof(float)-i-1]);
67 : }
68 2 : }
69 :
70 : //Removes the last four values from the uchar array, returning its float representation.
71 2 : float getfloat(std::vector<uchar> &p)
72 : {
73 : uchar arr[sizeof(float)];
74 10 : for(unsigned long i = 0; i < sizeof(float); ++i)
75 : {
76 8 : arr[i] = p.back();
77 8 : p.pop_back();
78 : }
79 2 : float n = 0.f;
80 2 : std::memcpy(&n, arr, sizeof(float));
81 2 : return n;
82 : }
83 :
84 :
85 13 : int getint(ucharbuf &p)
86 : {
87 13 : int c = static_cast<char>(p.get());
88 13 : if(c == -128)
89 : {
90 1 : int n = p.get();
91 1 : n |= static_cast<char>(p.get()) << 8;
92 1 : return n;
93 : }
94 12 : else if(c == -127)
95 : {
96 1 : int n = p.get();
97 1 : n |= p.get() << 8;
98 1 : n |= p.get() << 16;
99 1 : return n|(p.get()<<24);
100 : }
101 : else
102 : {
103 11 : return c;
104 : }
105 : }
106 :
107 : //* unisigned integers *//
108 : // much smaller encoding for unsigned integers up to 28 bits, but can handle signed
109 :
110 4 : void putuint(ucharbuf &p, int n)
111 : {
112 4 : putuint_(p, n);
113 4 : }
114 :
115 4 : int getuint(ucharbuf &p)
116 : {
117 4 : int n = p.get();
118 4 : if(n & 0x80)
119 : {
120 3 : n += (p.get() << 7) - 0x80;
121 3 : if(n & (1<<14))
122 : {
123 2 : n += (p.get() << 14) - (1<<14);
124 : }
125 3 : if(n & (1<<21))
126 : {
127 1 : n += (p.get() << 21) - (1<<21);
128 : }
129 3 : if(n & (1<<28))
130 : {
131 1 : n |= ~0U<<28;
132 : }
133 : }
134 4 : return n;
135 : }
136 :
137 : //* floats *//
138 2 : void putfloat(ucharbuf &p, float f)
139 : {
140 2 : putfloat_(p, f);
141 2 : }
142 :
143 2 : float getfloat(ucharbuf &p)
144 : {
145 : float f;
146 2 : p.get(reinterpret_cast<uchar *>(&f), sizeof(float));
147 2 : return f;
148 : }
149 :
150 : //* strings *//
151 2 : void sendstring(const char *t, ucharbuf &p)
152 : {
153 2 : sendstring_(t, p);
154 2 : }
155 0 : void sendstring(const char *t, std::vector<uchar> &p)
156 : {
157 0 : sendstring_(t, p);
158 0 : }
159 :
160 2 : void getstring(char *text, ucharbuf &p, size_t len)
161 : {
162 2 : char *t = text;
163 : do
164 : {
165 10 : if(t >= &text[len])
166 : {
167 0 : text[len-1] = 0;
168 0 : return;
169 : }
170 10 : if(!p.remaining())
171 : {
172 0 : *t = 0;
173 0 : return;
174 : }
175 10 : *t = getint(p);
176 10 : } while(*t++);
177 : }
178 :
179 5 : void filtertext(char *dst, const char *src, bool whitespace, bool forcespace, size_t len)
180 : {
181 37 : for(int c = static_cast<uchar>(*src); c; c = static_cast<uchar>(*++src))
182 : {
183 33 : if(c == '\f')
184 : {
185 3 : if(!*++src)
186 : {
187 0 : break;
188 : }
189 3 : continue;
190 : }
191 30 : if(!iscubeprint(c))
192 : {
193 0 : if(!iscubespace(c) || !whitespace)
194 : {
195 0 : continue;
196 : }
197 0 : if(forcespace)
198 : {
199 0 : c = ' ';
200 : }
201 : }
202 30 : *dst++ = c;
203 30 : if(!--len)
204 : {
205 1 : break;
206 : }
207 : }
208 5 : *dst = '\0';
209 5 : }
|