]> git.lizzy.rs Git - dragonfireclient.git/blob - src/util/serialize.h
Add dtime_s to entity activation
[dragonfireclient.git] / src / util / serialize.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010-2012 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.h"
24 #include "../irr_v2d.h"
25 #include "../irr_v3d.h"
26 #include <iostream>
27 #include <string>
28 #include "../exceptions.h"
29 #include "pointer.h"
30
31 inline void writeU64(u8 *data, u64 i)
32 {
33         data[0] = ((i>>56)&0xff);
34         data[1] = ((i>>48)&0xff);
35         data[2] = ((i>>40)&0xff);
36         data[3] = ((i>>32)&0xff);
37         data[4] = ((i>>24)&0xff);
38         data[5] = ((i>>16)&0xff);
39         data[6] = ((i>> 8)&0xff);
40         data[7] = ((i>> 0)&0xff);
41 }
42
43 inline void writeU32(u8 *data, u32 i)
44 {
45         data[0] = ((i>>24)&0xff);
46         data[1] = ((i>>16)&0xff);
47         data[2] = ((i>> 8)&0xff);
48         data[3] = ((i>> 0)&0xff);
49 }
50
51 inline void writeU16(u8 *data, u16 i)
52 {
53         data[0] = ((i>> 8)&0xff);
54         data[1] = ((i>> 0)&0xff);
55 }
56
57 inline void writeU8(u8 *data, u8 i)
58 {
59         data[0] = ((i>> 0)&0xff);
60 }
61
62 inline u64 readU64(u8 *data)
63 {
64         return ((u64)data[0]<<56) | ((u64)data[1]<<48)
65                 | ((u64)data[2]<<40) | ((u64)data[3]<<32)
66                 | ((u64)data[4]<<24) | ((u64)data[5]<<16)
67                 | ((u64)data[6]<<8) | ((u64)data[7]<<0);
68 }
69
70 inline u32 readU32(u8 *data)
71 {
72         return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
73 }
74
75 inline u16 readU16(u8 *data)
76 {
77         return (data[0]<<8) | (data[1]<<0);
78 }
79
80 inline u8 readU8(u8 *data)
81 {
82         return (data[0]<<0);
83 }
84
85 inline void writeS32(u8 *data, s32 i){
86         writeU32(data, (u32)i);
87 }
88 inline s32 readS32(u8 *data){
89         return (s32)readU32(data);
90 }
91
92 inline void writeS16(u8 *data, s16 i){
93         writeU16(data, (u16)i);
94 }
95 inline s16 readS16(u8 *data){
96         return (s16)readU16(data);
97 }
98
99 inline void writeS8(u8 *data, s8 i){
100         writeU8(data, (u8)i);
101 }
102 inline s8 readS8(u8 *data){
103         return (s8)readU8(data);
104 }
105
106 inline void writeF1000(u8 *data, f32 i){
107         writeS32(data, i*1000);
108 }
109 inline f32 readF1000(u8 *data){
110         return (f32)readS32(data)/1000.;
111 }
112
113 inline void writeV3S32(u8 *data, v3s32 p)
114 {
115         writeS32(&data[0], p.X);
116         writeS32(&data[4], p.Y);
117         writeS32(&data[8], p.Z);
118 }
119 inline v3s32 readV3S32(u8 *data)
120 {
121         v3s32 p;
122         p.X = readS32(&data[0]);
123         p.Y = readS32(&data[4]);
124         p.Z = readS32(&data[8]);
125         return p;
126 }
127
128 inline void writeV3F1000(u8 *data, v3f p)
129 {
130         writeF1000(&data[0], p.X);
131         writeF1000(&data[4], p.Y);
132         writeF1000(&data[8], p.Z);
133 }
134 inline v3f readV3F1000(u8 *data)
135 {
136         v3f p;
137         p.X = (float)readF1000(&data[0]);
138         p.Y = (float)readF1000(&data[4]);
139         p.Z = (float)readF1000(&data[8]);
140         return p;
141 }
142
143 inline void writeV2F1000(u8 *data, v2f p)
144 {
145         writeF1000(&data[0], p.X);
146         writeF1000(&data[4], p.Y);
147 }
148 inline v2f readV2F1000(u8 *data)
149 {
150         v2f p;
151         p.X = (float)readF1000(&data[0]);
152         p.Y = (float)readF1000(&data[4]);
153         return p;
154 }
155
156 inline void writeV2S16(u8 *data, v2s16 p)
157 {
158         writeS16(&data[0], p.X);
159         writeS16(&data[2], p.Y);
160 }
161
162 inline v2s16 readV2S16(u8 *data)
163 {
164         v2s16 p;
165         p.X = readS16(&data[0]);
166         p.Y = readS16(&data[2]);
167         return p;
168 }
169
170 inline void writeV2S32(u8 *data, v2s32 p)
171 {
172         writeS32(&data[0], p.X);
173         writeS32(&data[2], p.Y);
174 }
175
176 inline v2s32 readV2S32(u8 *data)
177 {
178         v2s32 p;
179         p.X = readS32(&data[0]);
180         p.Y = readS32(&data[2]);
181         return p;
182 }
183
184 inline void writeV3S16(u8 *data, v3s16 p)
185 {
186         writeS16(&data[0], p.X);
187         writeS16(&data[2], p.Y);
188         writeS16(&data[4], p.Z);
189 }
190
191 inline v3s16 readV3S16(u8 *data)
192 {
193         v3s16 p;
194         p.X = readS16(&data[0]);
195         p.Y = readS16(&data[2]);
196         p.Z = readS16(&data[4]);
197         return p;
198 }
199
200 /*
201         The above stuff directly interfaced to iostream
202 */
203
204 inline void writeU8(std::ostream &os, u8 p)
205 {
206         char buf[1] = {0};
207         writeU8((u8*)buf, p);
208         os.write(buf, 1);
209 }
210 inline u8 readU8(std::istream &is)
211 {
212         char buf[1] = {0};
213         is.read(buf, 1);
214         return readU8((u8*)buf);
215 }
216
217 inline void writeU16(std::ostream &os, u16 p)
218 {
219         char buf[2] = {0};
220         writeU16((u8*)buf, p);
221         os.write(buf, 2);
222 }
223 inline u16 readU16(std::istream &is)
224 {
225         char buf[2] = {0};
226         is.read(buf, 2);
227         return readU16((u8*)buf);
228 }
229
230 inline void writeU32(std::ostream &os, u32 p)
231 {
232         char buf[4] = {0};
233         writeU32((u8*)buf, p);
234         os.write(buf, 4);
235 }
236 inline u32 readU32(std::istream &is)
237 {
238         char buf[4] = {0};
239         is.read(buf, 4);
240         return readU32((u8*)buf);
241 }
242
243 inline void writeS32(std::ostream &os, s32 p)
244 {
245         char buf[4] = {0};
246         writeS32((u8*)buf, p);
247         os.write(buf, 4);
248 }
249 inline s32 readS32(std::istream &is)
250 {
251         char buf[4] = {0};
252         is.read(buf, 4);
253         return readS32((u8*)buf);
254 }
255
256 inline void writeS16(std::ostream &os, s16 p)
257 {
258         char buf[2] = {0};
259         writeS16((u8*)buf, p);
260         os.write(buf, 2);
261 }
262 inline s16 readS16(std::istream &is)
263 {
264         char buf[2] = {0};
265         is.read(buf, 2);
266         return readS16((u8*)buf);
267 }
268
269 inline void writeS8(std::ostream &os, s8 p)
270 {
271         char buf[1] = {0};
272         writeS8((u8*)buf, p);
273         os.write(buf, 1);
274 }
275 inline s8 readS8(std::istream &is)
276 {
277         char buf[1] = {0};
278         is.read(buf, 1);
279         return readS8((u8*)buf);
280 }
281
282 inline void writeF1000(std::ostream &os, f32 p)
283 {
284         char buf[4] = {0};
285         writeF1000((u8*)buf, p);
286         os.write(buf, 4);
287 }
288 inline f32 readF1000(std::istream &is)
289 {
290         char buf[4] = {0};
291         is.read(buf, 4);
292         return readF1000((u8*)buf);
293 }
294
295 inline void writeV3F1000(std::ostream &os, v3f p)
296 {
297         char buf[12];
298         writeV3F1000((u8*)buf, p);
299         os.write(buf, 12);
300 }
301 inline v3f readV3F1000(std::istream &is)
302 {
303         char buf[12];
304         is.read(buf, 12);
305         return readV3F1000((u8*)buf);
306 }
307
308 inline void writeV2F1000(std::ostream &os, v2f p)
309 {
310         char buf[8] = {0};
311         writeV2F1000((u8*)buf, p);
312         os.write(buf, 8);
313 }
314 inline v2f readV2F1000(std::istream &is)
315 {
316         char buf[8] = {0};
317         is.read(buf, 8);
318         return readV2F1000((u8*)buf);
319 }
320
321 inline void writeV2S16(std::ostream &os, v2s16 p)
322 {
323         char buf[4] = {0};
324         writeV2S16((u8*)buf, p);
325         os.write(buf, 4);
326 }
327 inline v2s16 readV2S16(std::istream &is)
328 {
329         char buf[4] = {0};
330         is.read(buf, 4);
331         return readV2S16((u8*)buf);
332 }
333
334 inline void writeV3S16(std::ostream &os, v3s16 p)
335 {
336         char buf[6] = {0};
337         writeV3S16((u8*)buf, p);
338         os.write(buf, 6);
339 }
340 inline v3s16 readV3S16(std::istream &is)
341 {
342         char buf[6] = {0};
343         is.read(buf, 6);
344         return readV3S16((u8*)buf);
345 }
346
347 /*
348         More serialization stuff
349 */
350
351 // Creates a string with the length as the first two bytes
352 inline std::string serializeString(const std::string &plain)
353 {
354         //assert(plain.size() <= 65535);
355         if(plain.size() > 65535)
356                 throw SerializationError("String too long for serializeString");
357         char buf[2];
358         writeU16((u8*)&buf[0], plain.size());
359         std::string s;
360         s.append(buf, 2);
361         s.append(plain);
362         return s;
363 }
364
365 // Creates a string with the length as the first two bytes from wide string
366 inline std::string serializeWideString(const std::wstring &plain)
367 {
368         //assert(plain.size() <= 65535);
369         if(plain.size() > 65535)
370                 throw SerializationError("String too long for serializeString");
371         char buf[2];
372         writeU16((u8*)buf, plain.size());
373         std::string s;
374         s.append(buf, 2);
375         for(u32 i=0; i<plain.size(); i++)
376         {
377                 writeU16((u8*)buf, plain[i]);
378                 s.append(buf, 2);
379         }
380         return s;
381 }
382
383 // Reads a string with the length as the first two bytes
384 inline std::string deSerializeString(std::istream &is)
385 {
386         char buf[2];
387         is.read(buf, 2);
388         if(is.gcount() != 2)
389                 throw SerializationError("deSerializeString: size not read");
390         u16 s_size = readU16((u8*)buf);
391         if(s_size == 0)
392                 return "";
393         Buffer<char> buf2(s_size);
394         is.read(&buf2[0], s_size);
395         std::string s;
396         s.reserve(s_size);
397         s.append(&buf2[0], s_size);
398         return s;
399 }
400
401 // Reads a wide string with the length as the first two bytes
402 inline std::wstring deSerializeWideString(std::istream &is)
403 {
404         char buf[2];
405         is.read(buf, 2);
406         if(is.gcount() != 2)
407                 throw SerializationError("deSerializeString: size not read");
408         u16 s_size = readU16((u8*)buf);
409         if(s_size == 0)
410                 return L"";
411         std::wstring s;
412         s.reserve(s_size);
413         for(u32 i=0; i<s_size; i++)
414         {
415                 is.read(&buf[0], 2);
416                 wchar_t c16 = readU16((u8*)buf);
417                 s.append(&c16, 1);
418         }
419         return s;
420 }
421
422 // Creates a string with the length as the first four bytes
423 inline std::string serializeLongString(const std::string &plain)
424 {
425         char buf[4];
426         writeU32((u8*)&buf[0], plain.size());
427         std::string s;
428         s.append(buf, 4);
429         s.append(plain);
430         return s;
431 }
432
433 // Reads a string with the length as the first four bytes
434 inline std::string deSerializeLongString(std::istream &is)
435 {
436         char buf[4];
437         is.read(buf, 4);
438         if(is.gcount() != 4)
439                 throw SerializationError("deSerializeLongString: size not read");
440         u32 s_size = readU32((u8*)buf);
441         if(s_size == 0)
442                 return "";
443         Buffer<char> buf2(s_size);
444         is.read(&buf2[0], s_size);
445         std::string s;
446         s.reserve(s_size);
447         s.append(&buf2[0], s_size);
448         return s;
449 }
450
451 // Creates a string encoded in JSON format (almost equivalent to a C string literal)
452 std::string serializeJsonString(const std::string &plain);
453
454 // Reads a string encoded in JSON format
455 std::string deSerializeJsonString(std::istream &is);
456
457 #endif
458