Line data Source code
1 : /*
2 : Minetest
3 : Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 :
5 : This program is free software; you can redistribute it and/or modify
6 : it under the terms of the GNU Lesser General Public License as published by
7 : the Free Software Foundation; either version 2.1 of the License, or
8 : (at your option) any later version.
9 :
10 : This program is distributed in the hope that it will be useful,
11 : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : GNU Lesser General Public License for more details.
14 :
15 : You should have received a copy of the GNU Lesser General Public License along
16 : with this program; if not, write to the Free Software Foundation, Inc.,
17 : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #ifndef UTIL_SERIALIZE_HEADER
21 : #define UTIL_SERIALIZE_HEADER
22 :
23 : #include "../irrlichttypes_bloated.h"
24 : #include "config.h"
25 : #if HAVE_ENDIAN_H
26 : #include <endian.h>
27 : #include <string.h> // for memcpy
28 : #endif
29 : #include <iostream>
30 : #include <string>
31 :
32 : #define FIXEDPOINT_FACTOR 1000.0f
33 : #define FIXEDPOINT_INVFACTOR (1.0f/FIXEDPOINT_FACTOR)
34 :
35 : #if HAVE_ENDIAN_H
36 : // use machine native byte swapping routines
37 : // Note: memcpy below is optimized out by modern compilers
38 :
39 0 : inline void writeU64(u8* data, u64 i)
40 : {
41 0 : u64 val = htobe64(i);
42 0 : memcpy(data, &val, 8);
43 0 : }
44 :
45 10213 : inline void writeU32(u8* data, u32 i)
46 : {
47 10213 : u32 val = htobe32(i);
48 10213 : memcpy(data, &val, 4);
49 10213 : }
50 :
51 16151 : inline void writeU16(u8* data, u16 i)
52 : {
53 16151 : u16 val = htobe16(i);
54 16151 : memcpy(data, &val, 2);
55 16151 : }
56 :
57 1 : inline u64 readU64(const u8* data)
58 : {
59 : u64 val;
60 1 : memcpy(&val, data, 8);
61 1 : return be64toh(val);
62 : }
63 :
64 457097 : inline u32 readU32(const u8* data)
65 : {
66 : u32 val;
67 457097 : memcpy(&val, data, 4);
68 457097 : return be32toh(val);
69 : }
70 :
71 3926637 : inline u16 readU16(const u8* data)
72 : {
73 : u16 val;
74 3926637 : memcpy(&val, data, 2);
75 3926637 : return be16toh(val);
76 : }
77 :
78 : #else
79 : // generic byte-swapping implementation
80 :
81 : inline void writeU64(u8 *data, u64 i)
82 : {
83 : data[0] = ((i>>56)&0xff);
84 : data[1] = ((i>>48)&0xff);
85 : data[2] = ((i>>40)&0xff);
86 : data[3] = ((i>>32)&0xff);
87 : data[4] = ((i>>24)&0xff);
88 : data[5] = ((i>>16)&0xff);
89 : data[6] = ((i>> 8)&0xff);
90 : data[7] = ((i>> 0)&0xff);
91 : }
92 :
93 : inline void writeU32(u8 *data, u32 i)
94 : {
95 : data[0] = ((i>>24)&0xff);
96 : data[1] = ((i>>16)&0xff);
97 : data[2] = ((i>> 8)&0xff);
98 : data[3] = ((i>> 0)&0xff);
99 : }
100 :
101 : inline void writeU16(u8 *data, u16 i)
102 : {
103 : data[0] = ((i>> 8)&0xff);
104 : data[1] = ((i>> 0)&0xff);
105 : }
106 :
107 : inline u64 readU64(const u8 *data)
108 : {
109 : return ((u64)data[0]<<56) | ((u64)data[1]<<48)
110 : | ((u64)data[2]<<40) | ((u64)data[3]<<32)
111 : | ((u64)data[4]<<24) | ((u64)data[5]<<16)
112 : | ((u64)data[6]<<8) | ((u64)data[7]<<0);
113 : }
114 :
115 : inline u32 readU32(const u8 *data)
116 : {
117 : return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
118 : }
119 :
120 : inline u16 readU16(const u8 *data)
121 : {
122 : return (data[0]<<8) | (data[1]<<0);
123 : }
124 :
125 : #endif
126 :
127 18153 : inline void writeU8(u8 *data, u8 i)
128 : {
129 18153 : data[0] = ((i>> 0)&0xff);
130 18153 : }
131 :
132 6862896 : inline u8 readU8(const u8 *data)
133 : {
134 6862896 : return (data[0]<<0);
135 : }
136 :
137 0 : inline void writeS32(u8 *data, s32 i){
138 0 : writeU32(data, (u32)i);
139 0 : }
140 255107 : inline s32 readS32(const u8 *data){
141 255107 : return (s32)readU32(data);
142 : }
143 :
144 0 : inline void writeS16(u8 *data, s16 i){
145 0 : writeU16(data, (u16)i);
146 0 : }
147 2998 : inline s16 readS16(const u8 *data){
148 2998 : return (s16)readU16(data);
149 : }
150 :
151 : inline void writeS8(u8 *data, s8 i){
152 : writeU8(data, (u8)i);
153 : }
154 : inline s8 readS8(const u8 *data){
155 : return (s8)readU8(data);
156 : }
157 :
158 0 : inline void writeF1000(u8 *data, f32 i){
159 0 : writeS32(data, i*FIXEDPOINT_FACTOR);
160 0 : }
161 255093 : inline f32 readF1000(const u8 *data){
162 255093 : return (f32)readS32(data)*FIXEDPOINT_INVFACTOR;
163 : }
164 :
165 : inline void writeV3S32(u8 *data, v3s32 p)
166 : {
167 : writeS32(&data[0], p.X);
168 : writeS32(&data[4], p.Y);
169 : writeS32(&data[8], p.Z);
170 : }
171 0 : inline v3s32 readV3S32(const u8 *data)
172 : {
173 0 : v3s32 p;
174 0 : p.X = readS32(&data[0]);
175 0 : p.Y = readS32(&data[4]);
176 0 : p.Z = readS32(&data[8]);
177 0 : return p;
178 : }
179 :
180 0 : inline void writeV3F1000(u8 *data, v3f p)
181 : {
182 0 : writeF1000(&data[0], p.X);
183 0 : writeF1000(&data[4], p.Y);
184 0 : writeF1000(&data[8], p.Z);
185 0 : }
186 51774 : inline v3f readV3F1000(const u8 *data)
187 : {
188 51774 : v3f p;
189 51774 : p.X = (float)readF1000(&data[0]);
190 51774 : p.Y = (float)readF1000(&data[4]);
191 51774 : p.Z = (float)readF1000(&data[8]);
192 51774 : return p;
193 : }
194 :
195 0 : inline void writeV2F1000(u8 *data, v2f p)
196 : {
197 0 : writeF1000(&data[0], p.X);
198 0 : writeF1000(&data[4], p.Y);
199 0 : }
200 322 : inline v2f readV2F1000(const u8 *data)
201 : {
202 322 : v2f p;
203 322 : p.X = (float)readF1000(&data[0]);
204 322 : p.Y = (float)readF1000(&data[4]);
205 322 : return p;
206 : }
207 :
208 0 : inline void writeV2S16(u8 *data, v2s16 p)
209 : {
210 0 : writeS16(&data[0], p.X);
211 0 : writeS16(&data[2], p.Y);
212 0 : }
213 :
214 236 : inline v2s16 readV2S16(const u8 *data)
215 : {
216 236 : v2s16 p;
217 236 : p.X = readS16(&data[0]);
218 236 : p.Y = readS16(&data[2]);
219 236 : return p;
220 : }
221 :
222 : inline void writeV2S32(u8 *data, v2s32 p)
223 : {
224 : writeS32(&data[0], p.X);
225 : writeS32(&data[4], p.Y);
226 : }
227 :
228 6 : inline v2s32 readV2S32(const u8 *data)
229 : {
230 6 : v2s32 p;
231 6 : p.X = readS32(&data[0]);
232 6 : p.Y = readS32(&data[4]);
233 6 : return p;
234 : }
235 :
236 0 : inline void writeV3S16(u8 *data, v3s16 p)
237 : {
238 0 : writeS16(&data[0], p.X);
239 0 : writeS16(&data[2], p.Y);
240 0 : writeS16(&data[4], p.Z);
241 0 : }
242 :
243 842 : inline v3s16 readV3S16(const u8 *data)
244 : {
245 842 : v3s16 p;
246 842 : p.X = readS16(&data[0]);
247 842 : p.Y = readS16(&data[2]);
248 842 : p.Z = readS16(&data[4]);
249 842 : return p;
250 : }
251 :
252 0 : inline void writeARGB8(u8 *data, video::SColor p)
253 : {
254 0 : writeU32(data, p.color);
255 0 : }
256 :
257 118 : inline video::SColor readARGB8(const u8 *data)
258 : {
259 118 : video::SColor p(readU32(data));
260 118 : return p;
261 : }
262 :
263 : /*
264 : The above stuff directly interfaced to iostream
265 : */
266 :
267 0 : inline void writeU8(std::ostream &os, u8 p)
268 : {
269 : char buf[1];
270 0 : writeU8((u8*)buf, p);
271 0 : os.write(buf, 1);
272 0 : }
273 404806 : inline u8 readU8(std::istream &is)
274 : {
275 404806 : char buf[1] = {0};
276 404806 : is.read(buf, 1);
277 404806 : return readU8((u8*)buf);
278 : }
279 :
280 0 : inline void writeU16(std::ostream &os, u16 p)
281 : {
282 : char buf[2];
283 0 : writeU16((u8*)buf, p);
284 0 : os.write(buf, 2);
285 0 : }
286 377391 : inline u16 readU16(std::istream &is)
287 : {
288 377391 : char buf[2] = {0};
289 377391 : is.read(buf, 2);
290 377391 : return readU16((u8*)buf);
291 : }
292 :
293 23 : inline void writeU32(std::ostream &os, u32 p)
294 : {
295 : char buf[4];
296 23 : writeU32((u8*)buf, p);
297 23 : os.write(buf, 4);
298 23 : }
299 192135 : inline u32 readU32(std::istream &is)
300 : {
301 192135 : char buf[4] = {0};
302 192135 : is.read(buf, 4);
303 192135 : return readU32((u8*)buf);
304 : }
305 :
306 0 : inline void writeS32(std::ostream &os, s32 p)
307 : {
308 0 : writeU32(os, (u32) p);
309 0 : }
310 : inline s32 readS32(std::istream &is)
311 : {
312 : return (s32)readU32(is);
313 : }
314 :
315 0 : inline void writeS16(std::ostream &os, s16 p)
316 : {
317 0 : writeU16(os, (u16) p);
318 0 : }
319 40453 : inline s16 readS16(std::istream &is)
320 : {
321 40453 : return (s16)readU16(is);
322 : }
323 :
324 : inline void writeS8(std::ostream &os, s8 p)
325 : {
326 : writeU8(os, (u8) p);
327 : }
328 : inline s8 readS8(std::istream &is)
329 : {
330 : return (s8)readU8(is);
331 : }
332 :
333 0 : inline void writeF1000(std::ostream &os, f32 p)
334 : {
335 : char buf[4];
336 0 : writeF1000((u8*)buf, p);
337 0 : os.write(buf, 4);
338 0 : }
339 99054 : inline f32 readF1000(std::istream &is)
340 : {
341 99054 : char buf[4] = {0};
342 99054 : is.read(buf, 4);
343 99054 : return readF1000((u8*)buf);
344 : }
345 :
346 0 : inline void writeV3F1000(std::ostream &os, v3f p)
347 : {
348 : char buf[12];
349 0 : writeV3F1000((u8*)buf, p);
350 0 : os.write(buf, 12);
351 0 : }
352 51715 : inline v3f readV3F1000(std::istream &is)
353 : {
354 : char buf[12];
355 51715 : is.read(buf, 12);
356 51715 : return readV3F1000((u8*)buf);
357 : }
358 :
359 0 : inline void writeV2F1000(std::ostream &os, v2f p)
360 : {
361 : char buf[8];
362 0 : writeV2F1000((u8*)buf, p);
363 0 : os.write(buf, 8);
364 0 : }
365 314 : inline v2f readV2F1000(std::istream &is)
366 : {
367 314 : char buf[8] = {0};
368 314 : is.read(buf, 8);
369 314 : return readV2F1000((u8*)buf);
370 : }
371 :
372 0 : inline void writeV2S16(std::ostream &os, v2s16 p)
373 : {
374 : char buf[4];
375 0 : writeV2S16((u8*)buf, p);
376 0 : os.write(buf, 4);
377 0 : }
378 236 : inline v2s16 readV2S16(std::istream &is)
379 : {
380 236 : char buf[4] = {0};
381 236 : is.read(buf, 4);
382 236 : return readV2S16((u8*)buf);
383 : }
384 :
385 : inline void writeV2S32(std::ostream &os, v2s32 p)
386 : {
387 : char buf[8];
388 : writeV2S32((u8*)buf, p);
389 : os.write(buf, 8);
390 : }
391 : inline v2s32 readV2S32(std::istream &is)
392 : {
393 : char buf[8] = {0};
394 : is.read(buf, 8);
395 : return readV2S32((u8*)buf);
396 : }
397 :
398 0 : inline void writeV3S16(std::ostream &os, v3s16 p)
399 : {
400 : char buf[6];
401 0 : writeV3S16((u8*)buf, p);
402 0 : os.write(buf, 6);
403 0 : }
404 0 : inline v3s16 readV3S16(std::istream &is)
405 : {
406 0 : char buf[6] = {0};
407 0 : is.read(buf, 6);
408 0 : return readV3S16((u8*)buf);
409 : }
410 :
411 0 : inline void writeARGB8(std::ostream &os, video::SColor p)
412 : {
413 : char buf[4];
414 0 : writeARGB8((u8*)buf, p);
415 0 : os.write(buf, 4);
416 0 : }
417 :
418 118 : inline video::SColor readARGB8(std::istream &is)
419 : {
420 118 : char buf[4] = {0};
421 118 : is.read(buf, 4);
422 118 : return readARGB8((u8*)buf);
423 : }
424 :
425 : /*
426 : More serialization stuff
427 : */
428 :
429 : // Creates a string with the length as the first two bytes
430 : std::string serializeString(const std::string &plain);
431 :
432 : // Creates a string with the length as the first two bytes from wide string
433 : std::string serializeWideString(const std::wstring &plain);
434 :
435 : // Reads a string with the length as the first two bytes
436 : std::string deSerializeString(std::istream &is);
437 :
438 : // Reads a wide string with the length as the first two bytes
439 : std::wstring deSerializeWideString(std::istream &is);
440 :
441 : // Creates a string with the length as the first four bytes
442 : std::string serializeLongString(const std::string &plain);
443 :
444 : // Reads a string with the length as the first four bytes
445 : std::string deSerializeLongString(std::istream &is);
446 :
447 : // Creates a string encoded in JSON format (almost equivalent to a C string literal)
448 : std::string serializeJsonString(const std::string &plain);
449 :
450 : // Reads a string encoded in JSON format
451 : std::string deSerializeJsonString(std::istream &is);
452 :
453 : // Creates a string containing comma delimited values of a struct whose layout is
454 : // described by the parameter format
455 : bool serializeStructToString(std::string *out,
456 : std::string format, void *value);
457 :
458 : // Reads a comma delimited string of values into a struct whose layout is
459 : // decribed by the parameter format
460 : bool deSerializeStringToStruct(std::string valstr,
461 : std::string format, void *out, size_t olen);
462 :
463 : #endif
464 :
|