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