Skip to content

Commit bf991bd

Browse files
committedAug 1, 2015
Clean up util/serialization.{cpp,h} and add unit tests
1 parent 67997af commit bf991bd

File tree

3 files changed

+315
-268
lines changed

3 files changed

+315
-268
lines changed
 

Diff for: ‎src/unittest/test_serialization.cpp

+120
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,14 @@ class TestSerialization : public TestBase {
3838
void testDeSerializeString();
3939
void testDeSerializeWideString();
4040
void testDeSerializeLongString();
41+
void testStreamRead();
42+
void testStreamWrite();
4143

4244
std::string teststring2;
4345
std::wstring teststring2_w;
4446
std::string teststring2_w_encoded;
47+
48+
static const u8 test_serialized_data[12 * 13];
4549
};
4650

4751
static TestSerialization g_test_instance;
@@ -58,6 +62,8 @@ void TestSerialization::runTests(IGameDef *gamedef)
5862
TEST(testDeSerializeLongString);
5963
TEST(testSerializeJsonString);
6064
TEST(testSerializeHex);
65+
TEST(testStreamRead);
66+
TEST(testStreamWrite);
6167
}
6268

6369
////////////////////////////////////////////////////////////////////////////////
@@ -271,3 +277,117 @@ void TestSerialization::testSerializeHex()
271277
UASSERT(serializeHexString(mkstr("\x00\x0a\xb0\x63\x1f\x00\xff"), true) ==
272278
"00 0a b0 63 1f 00 ff");
273279
}
280+
281+
282+
void TestSerialization::testStreamRead()
283+
{
284+
std::string datastr(
285+
(const char *)test_serialized_data,
286+
sizeof(test_serialized_data));
287+
std::istringstream is(datastr, std::ios_base::binary);
288+
289+
UASSERT(readU8(is) == 0x11);
290+
UASSERT(readU16(is) == 0x2233);
291+
UASSERT(readU32(is) == 0x44556677);
292+
UASSERT(readU64(is) == 0x8899AABBCCDDEEFF);
293+
294+
UASSERT(readS8(is) == -128);
295+
UASSERT(readS16(is) == 30000);
296+
UASSERT(readS32(is) == -6);
297+
UASSERT(readS64(is) == -43);
298+
299+
UASSERT(fabs(readF1000(is) - 53.534f) < 0.005);
300+
UASSERT(fabs(readF1000(is) - -300000.32f) < 0.05);
301+
UASSERT(fabs(readF1000(is) - -2147483.f) < 0.05);
302+
UASSERT(fabs(readF1000(is) - 2147483.f) < 0.05);
303+
304+
UASSERT(deSerializeString(is) == "foobar!");
305+
306+
UASSERT(readV2S16(is) == v2s16(500, 500));
307+
UASSERT(readV3S16(is) == v3s16(4207, 604, -30));
308+
UASSERT(readV2S32(is) == v2s32(1920, 1080));
309+
UASSERT(readV3S32(is) == v3s32(-400, 6400054, 290549855));
310+
311+
v2f vec2 = readV2F1000(is);
312+
UASSERT(fabs(vec2.X - 500.656f) < 0.005);
313+
UASSERT(fabs(vec2.Y - 350.345f) < 0.005);
314+
315+
UASSERT(deSerializeWideString(is) == L"\x02~woof~\x5455");
316+
317+
v3f vec3 = readV3F1000(is);
318+
UASSERT(fabs(vec3.X - 500.f) < 0.005);
319+
UASSERT(fabs(vec3.Y - 10024.2f) < 0.005);
320+
UASSERT(fabs(vec3.Z - -192.54f) < 0.005);
321+
322+
UASSERT(readARGB8(is) == video::SColor(255, 128, 50, 128));
323+
324+
UASSERT(deSerializeLongString(is) == "some longer string here");
325+
326+
UASSERT(is.rdbuf()->in_avail() == 2);
327+
UASSERT(readU16(is) == 0xF00D);
328+
UASSERT(is.rdbuf()->in_avail() == 0);
329+
}
330+
331+
332+
void TestSerialization::testStreamWrite()
333+
{
334+
std::ostringstream os(std::ios_base::binary);
335+
std::string data;
336+
337+
writeU8(os, 0x11);
338+
writeU16(os, 0x2233);
339+
writeU32(os, 0x44556677);
340+
writeU64(os, 0x8899AABBCCDDEEFF);
341+
342+
writeS8(os, -128);
343+
writeS16(os, 30000);
344+
writeS32(os, -6);
345+
writeS64(os, -43);
346+
347+
writeF1000(os, 53.53467f);
348+
writeF1000(os, -300000.32f);
349+
writeF1000(os, -2147483.f);
350+
writeF1000(os, 2147483.f);
351+
352+
os << serializeString("foobar!");
353+
354+
data = os.str();
355+
UASSERT(data.size() < sizeof(test_serialized_data));
356+
UASSERT(!memcmp(&data[0], test_serialized_data, data.size()));
357+
358+
writeV2S16(os, v2s16(500, 500));
359+
writeV3S16(os, v3s16(4207, 604, -30));
360+
writeV2S32(os, v2s32(1920, 1080));
361+
writeV3S32(os, v3s32(-400, 6400054, 290549855));
362+
writeV2F1000(os, v2f(500.65661f, 350.34567f));
363+
364+
os << serializeWideString(L"\x02~woof~\x5455");
365+
366+
writeV3F1000(os, v3f(500, 10024.2f, -192.54f));
367+
writeARGB8(os, video::SColor(255, 128, 50, 128));
368+
369+
os << serializeLongString("some longer string here");
370+
371+
writeU16(os, 0xF00D);
372+
373+
data = os.str();
374+
UASSERT(data.size() == sizeof(test_serialized_data));
375+
UASSERT(!memcmp(&data[0], test_serialized_data, sizeof(test_serialized_data)));
376+
}
377+
378+
379+
const u8 TestSerialization::test_serialized_data[12 * 13] = {
380+
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
381+
0xdd, 0xee, 0xff, 0x80, 0x75, 0x30, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff,
382+
0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x00, 0x00, 0xd1, 0x1e, 0xee, 0x1e,
383+
0x5b, 0xc0, 0x80, 0x00, 0x02, 0x80, 0x7F, 0xFF, 0xFD, 0x80, 0x00, 0x07,
384+
0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x21, 0x01, 0xf4, 0x01, 0xf4, 0x10,
385+
0x6f, 0x02, 0x5c, 0xff, 0xe2, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x04,
386+
0x38, 0xff, 0xff, 0xfe, 0x70, 0x00, 0x61, 0xa8, 0x36, 0x11, 0x51, 0x70,
387+
0x5f, 0x00, 0x07, 0xa3, 0xb0, 0x00, 0x05, 0x58, 0x89, 0x00, 0x08, 0x00,
388+
0x02, 0x00, 0x7e, 0x00, 0x77, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x66, 0x00,
389+
0x7e, 0x54, 0x55, 0x00, 0x07, 0xa1, 0x20, 0x00, 0x98, 0xf5, 0x08, 0xff,
390+
0xfd, 0x0f, 0xe4, 0xff, 0x80, 0x32, 0x80, 0x00, 0x00, 0x00, 0x17, 0x73,
391+
0x6f, 0x6d, 0x65, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x73,
392+
0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x65, 0x72, 0x65, 0xF0, 0x0D,
393+
};

Diff for: ‎src/util/serialize.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ std::string serializeString(const std::string &plain)
3737
std::string s;
3838
char buf[2];
3939

40-
if (plain.size() > 65535)
40+
if (plain.size() > STRING_MAX_LEN)
4141
throw SerializationError("String too long for serializeString");
4242

4343
writeU16((u8 *)&buf[0], plain.size());
@@ -79,8 +79,8 @@ std::string serializeWideString(const std::wstring &plain)
7979
std::string s;
8080
char buf[2];
8181

82-
if (plain.size() > 65535)
83-
throw SerializationError("String too long for serializeString");
82+
if (plain.size() > WIDE_STRING_MAX_LEN)
83+
throw SerializationError("String too long for serializeWideString");
8484

8585
writeU16((u8 *)buf, plain.size());
8686
s.append(buf, 2);
@@ -99,7 +99,7 @@ std::wstring deSerializeWideString(std::istream &is)
9999

100100
is.read(buf, 2);
101101
if (is.gcount() != 2)
102-
throw SerializationError("deSerializeString: size not read");
102+
throw SerializationError("deSerializeWideString: size not read");
103103

104104
u16 s_size = readU16((u8 *)buf);
105105
if (s_size == 0)
@@ -127,7 +127,7 @@ std::string serializeLongString(const std::string &plain)
127127
{
128128
char buf[4];
129129

130-
if (plain.size() > LONG_STRING_MAX)
130+
if (plain.size() > LONG_STRING_MAX_LEN)
131131
throw SerializationError("String too long for serializeLongString");
132132

133133
writeU32((u8*)&buf[0], plain.size());
@@ -151,15 +151,15 @@ std::string deSerializeLongString(std::istream &is)
151151
return s;
152152

153153
// We don't really want a remote attacker to force us to allocate 4GB...
154-
if (s_size > LONG_STRING_MAX) {
154+
if (s_size > LONG_STRING_MAX_LEN) {
155155
throw SerializationError("deSerializeLongString: "
156156
"string too long: " + itos(s_size) + " bytes");
157157
}
158158

159159
Buffer<char> buf2(s_size);
160160
is.read(&buf2[0], s_size);
161161
if (is.gcount() != s_size)
162-
throw SerializationError("deSerializeString: couldn't read all chars");
162+
throw SerializationError("deSerializeLongString: couldn't read all chars");
163163

164164
s.reserve(s_size);
165165
s.append(&buf2[0], s_size);

Diff for: ‎src/util/serialize.h

+188-261
Original file line numberDiff line numberDiff line change
@@ -32,183 +32,144 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3232
#define FIXEDPOINT_FACTOR 1000.0f
3333
#define FIXEDPOINT_INVFACTOR (1.0f/FIXEDPOINT_FACTOR)
3434

35+
#define STRING_MAX_LEN 0xFFFF
36+
#define WIDE_STRING_MAX_LEN 0xFFFF
37+
// 64 MB ought to be enough for anybody - Billy G.
38+
#define LONG_STRING_MAX_LEN (64 * 1024 * 1024)
39+
40+
3541
#if HAVE_ENDIAN_H
3642
// use machine native byte swapping routines
3743
// Note: memcpy below is optimized out by modern compilers
3844

39-
inline void writeU64(u8* data, u64 i)
40-
{
41-
u64 val = htobe64(i);
42-
memcpy(data, &val, 8);
43-
}
44-
45-
inline void writeU32(u8* data, u32 i)
45+
inline u16 readU16(const u8 *data)
4646
{
47-
u32 val = htobe32(i);
48-
memcpy(data, &val, 4);
47+
u16 val;
48+
memcpy(&val, data, 2);
49+
return be16toh(val);
4950
}
5051

51-
inline void writeU16(u8* data, u16 i)
52+
inline u32 readU32(const u8 *data)
5253
{
53-
u16 val = htobe16(i);
54-
memcpy(data, &val, 2);
54+
u32 val;
55+
memcpy(&val, data, 4);
56+
return be32toh(val);
5557
}
5658

57-
inline u64 readU64(const u8* data)
59+
inline u64 readU64(const u8 *data)
5860
{
5961
u64 val;
6062
memcpy(&val, data, 8);
6163
return be64toh(val);
6264
}
6365

64-
inline u32 readU32(const u8* data)
66+
inline void writeU16(u8 *data, u16 i)
6567
{
66-
u32 val;
67-
memcpy(&val, data, 4);
68-
return be32toh(val);
68+
u16 val = htobe16(i);
69+
memcpy(data, &val, 2);
6970
}
7071

71-
inline u16 readU16(const u8* data)
72+
inline void writeU32(u8 *data, u32 i)
7273
{
73-
u16 val;
74-
memcpy(&val, data, 2);
75-
return be16toh(val);
74+
u32 val = htobe32(i);
75+
memcpy(data, &val, 4);
7676
}
7777

78-
#else
79-
// generic byte-swapping implementation
80-
8178
inline void writeU64(u8 *data, u64 i)
8279
{
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);
80+
u64 val = htobe64(i);
81+
memcpy(data, &val, 8);
9182
}
9283

93-
inline void writeU32(u8 *data, u32 i)
84+
#else
85+
// generic byte-swapping implementation
86+
87+
inline u16 readU16(const u8 *data)
9488
{
95-
data[0] = ((i>>24)&0xff);
96-
data[1] = ((i>>16)&0xff);
97-
data[2] = ((i>> 8)&0xff);
98-
data[3] = ((i>> 0)&0xff);
89+
return
90+
((u16)data[0] << 8) | ((u16)data[1] << 0);
9991
}
10092

101-
inline void writeU16(u8 *data, u16 i)
93+
inline u32 readU32(const u8 *data)
10294
{
103-
data[0] = ((i>> 8)&0xff);
104-
data[1] = ((i>> 0)&0xff);
95+
return
96+
((u32)data[0] << 24) | ((u32)data[1] << 16) |
97+
((u32)data[2] << 8) | ((u32)data[3] << 0);
10598
}
10699

107100
inline u64 readU64(const u8 *data)
108101
{
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);
102+
return
103+
((u64)data[0] << 56) | ((u64)data[1] << 48) |
104+
((u64)data[2] << 40) | ((u64)data[3] << 32) |
105+
((u64)data[4] << 24) | ((u64)data[5] << 16) |
106+
((u64)data[6] << 8) | ((u64)data[7] << 0);
113107
}
114108

115-
inline u32 readU32(const u8 *data)
109+
inline void writeU16(u8 *data, u16 i)
116110
{
117-
return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
111+
data[0] = (i >> 8) & 0xFF;
112+
data[1] = (i >> 0) & 0xFF;
118113
}
119114

120-
inline u16 readU16(const u8 *data)
115+
inline void writeU32(u8 *data, u32 i)
121116
{
122-
return (data[0]<<8) | (data[1]<<0);
117+
data[0] = (i >> 24) & 0xFF;
118+
data[1] = (i >> 16) & 0xFF;
119+
data[2] = (i >> 8) & 0xFF;
120+
data[3] = (i >> 0) & 0xFF;
123121
}
124122

125-
#endif
126-
127-
inline void writeU8(u8 *data, u8 i)
123+
inline void writeU64(u8 *data, u64 i)
128124
{
129-
data[0] = ((i>> 0)&0xff);
125+
data[0] = (i >> 56) & 0xFF;
126+
data[1] = (i >> 48) & 0xFF;
127+
data[2] = (i >> 40) & 0xFF;
128+
data[3] = (i >> 32) & 0xFF;
129+
data[4] = (i >> 24) & 0xFF;
130+
data[5] = (i >> 16) & 0xFF;
131+
data[6] = (i >> 8) & 0xFF;
132+
data[7] = (i >> 0) & 0xFF;
130133
}
131134

132-
inline u8 readU8(const u8 *data)
133-
{
134-
return (data[0]<<0);
135-
}
135+
#endif // HAVE_ENDIAN_H
136136

137-
inline void writeS32(u8 *data, s32 i){
138-
writeU32(data, (u32)i);
139-
}
140-
inline s32 readS32(const u8 *data){
141-
return (s32)readU32(data);
142-
}
137+
//////////////// read routines ////////////////
143138

144-
inline void writeS16(u8 *data, s16 i){
145-
writeU16(data, (u16)i);
146-
}
147-
inline s16 readS16(const u8 *data){
148-
return (s16)readU16(data);
139+
inline u8 readU8(const u8 *data)
140+
{
141+
return ((u8)data[0] << 0);
149142
}
150143

151-
inline void writeS8(u8 *data, s8 i){
152-
writeU8(data, (u8)i);
153-
}
154-
inline s8 readS8(const u8 *data){
144+
inline s8 readS8(const u8 *data)
145+
{
155146
return (s8)readU8(data);
156147
}
157148

158-
inline void writeF1000(u8 *data, f32 i){
159-
writeS32(data, i*FIXEDPOINT_FACTOR);
160-
}
161-
inline f32 readF1000(const u8 *data){
162-
return (f32)readS32(data)*FIXEDPOINT_INVFACTOR;
163-
}
164-
165-
inline void writeV3S32(u8 *data, v3s32 p)
149+
inline s16 readS16(const u8 *data)
166150
{
167-
writeS32(&data[0], p.X);
168-
writeS32(&data[4], p.Y);
169-
writeS32(&data[8], p.Z);
170-
}
171-
inline v3s32 readV3S32(const u8 *data)
172-
{
173-
v3s32 p;
174-
p.X = readS32(&data[0]);
175-
p.Y = readS32(&data[4]);
176-
p.Z = readS32(&data[8]);
177-
return p;
151+
return (s16)readU16(data);
178152
}
179153

180-
inline void writeV3F1000(u8 *data, v3f p)
154+
inline s32 readS32(const u8 *data)
181155
{
182-
writeF1000(&data[0], p.X);
183-
writeF1000(&data[4], p.Y);
184-
writeF1000(&data[8], p.Z);
185-
}
186-
inline v3f readV3F1000(const u8 *data)
187-
{
188-
v3f p;
189-
p.X = (float)readF1000(&data[0]);
190-
p.Y = (float)readF1000(&data[4]);
191-
p.Z = (float)readF1000(&data[8]);
192-
return p;
156+
return (s32)readU32(data);
193157
}
194158

195-
inline void writeV2F1000(u8 *data, v2f p)
159+
inline s64 readS64(const u8 *data)
196160
{
197-
writeF1000(&data[0], p.X);
198-
writeF1000(&data[4], p.Y);
161+
return (s64)readU64(data);
199162
}
200-
inline v2f readV2F1000(const u8 *data)
163+
164+
inline f32 readF1000(const u8 *data)
201165
{
202-
v2f p;
203-
p.X = (float)readF1000(&data[0]);
204-
p.Y = (float)readF1000(&data[4]);
205-
return p;
166+
return (f32)readS32(data) * FIXEDPOINT_INVFACTOR;
206167
}
207168

208-
inline void writeV2S16(u8 *data, v2s16 p)
169+
inline video::SColor readARGB8(const u8 *data)
209170
{
210-
writeS16(&data[0], p.X);
211-
writeS16(&data[2], p.Y);
171+
video::SColor p(readU32(data));
172+
return p;
212173
}
213174

214175
inline v2s16 readV2S16(const u8 *data)
@@ -219,10 +180,13 @@ inline v2s16 readV2S16(const u8 *data)
219180
return p;
220181
}
221182

222-
inline void writeV2S32(u8 *data, v2s32 p)
183+
inline v3s16 readV3S16(const u8 *data)
223184
{
224-
writeS32(&data[0], p.X);
225-
writeS32(&data[4], p.Y);
185+
v3s16 p;
186+
p.X = readS16(&data[0]);
187+
p.Y = readS16(&data[2]);
188+
p.Z = readS16(&data[4]);
189+
return p;
226190
}
227191

228192
inline v2s32 readV2S32(const u8 *data)
@@ -233,201 +197,165 @@ inline v2s32 readV2S32(const u8 *data)
233197
return p;
234198
}
235199

236-
inline void writeV3S16(u8 *data, v3s16 p)
237-
{
238-
writeS16(&data[0], p.X);
239-
writeS16(&data[2], p.Y);
240-
writeS16(&data[4], p.Z);
241-
}
242-
243-
inline v3s16 readV3S16(const u8 *data)
200+
inline v3s32 readV3S32(const u8 *data)
244201
{
245-
v3s16 p;
246-
p.X = readS16(&data[0]);
247-
p.Y = readS16(&data[2]);
248-
p.Z = readS16(&data[4]);
202+
v3s32 p;
203+
p.X = readS32(&data[0]);
204+
p.Y = readS32(&data[4]);
205+
p.Z = readS32(&data[8]);
249206
return p;
250207
}
251208

252-
inline void writeARGB8(u8 *data, video::SColor p)
209+
inline v2f readV2F1000(const u8 *data)
253210
{
254-
writeU32(data, p.color);
211+
v2f p;
212+
p.X = (float)readF1000(&data[0]);
213+
p.Y = (float)readF1000(&data[4]);
214+
return p;
255215
}
256216

257-
inline video::SColor readARGB8(const u8 *data)
217+
inline v3f readV3F1000(const u8 *data)
258218
{
259-
video::SColor p(readU32(data));
219+
v3f p;
220+
p.X = (float)readF1000(&data[0]);
221+
p.Y = (float)readF1000(&data[4]);
222+
p.Z = (float)readF1000(&data[8]);
260223
return p;
261224
}
262225

263-
/*
264-
The above stuff directly interfaced to iostream
265-
*/
226+
/////////////// write routines ////////////////
266227

267-
inline void writeU8(std::ostream &os, u8 p)
268-
{
269-
char buf[1];
270-
writeU8((u8*)buf, p);
271-
os.write(buf, 1);
272-
}
273-
inline u8 readU8(std::istream &is)
274-
{
275-
char buf[1] = {0};
276-
is.read(buf, 1);
277-
return readU8((u8*)buf);
278-
}
279-
280-
inline void writeU16(std::ostream &os, u16 p)
281-
{
282-
char buf[2];
283-
writeU16((u8*)buf, p);
284-
os.write(buf, 2);
285-
}
286-
inline u16 readU16(std::istream &is)
228+
inline void writeU8(u8 *data, u8 i)
287229
{
288-
char buf[2] = {0};
289-
is.read(buf, 2);
290-
return readU16((u8*)buf);
230+
data[0] = (i >> 0) & 0xFF;
291231
}
292232

293-
inline void writeU32(std::ostream &os, u32 p)
294-
{
295-
char buf[4];
296-
writeU32((u8*)buf, p);
297-
os.write(buf, 4);
298-
}
299-
inline u32 readU32(std::istream &is)
233+
inline void writeS8(u8 *data, s8 i)
300234
{
301-
char buf[4] = {0};
302-
is.read(buf, 4);
303-
return readU32((u8*)buf);
235+
writeU8(data, (u8)i);
304236
}
305237

306-
inline void writeS32(std::ostream &os, s32 p)
307-
{
308-
writeU32(os, (u32) p);
309-
}
310-
inline s32 readS32(std::istream &is)
238+
inline void writeS16(u8 *data, s16 i)
311239
{
312-
return (s32)readU32(is);
240+
writeU16(data, (u16)i);
313241
}
314242

315-
inline void writeS16(std::ostream &os, s16 p)
316-
{
317-
writeU16(os, (u16) p);
318-
}
319-
inline s16 readS16(std::istream &is)
243+
inline void writeS32(u8 *data, s32 i)
320244
{
321-
return (s16)readU16(is);
245+
writeU32(data, (u32)i);
322246
}
323247

324-
inline void writeS8(std::ostream &os, s8 p)
248+
inline void writeS64(u8 *data, s64 i)
325249
{
326-
writeU8(os, (u8) p);
327-
}
328-
inline s8 readS8(std::istream &is)
329-
{
330-
return (s8)readU8(is);
250+
writeU64(data, (u64)i);
331251
}
332252

333-
inline void writeF1000(std::ostream &os, f32 p)
253+
inline void writeF1000(u8 *data, f32 i)
334254
{
335-
char buf[4];
336-
writeF1000((u8*)buf, p);
337-
os.write(buf, 4);
338-
}
339-
inline f32 readF1000(std::istream &is)
340-
{
341-
char buf[4] = {0};
342-
is.read(buf, 4);
343-
return readF1000((u8*)buf);
255+
writeS32(data, i * FIXEDPOINT_FACTOR);
344256
}
345257

346-
inline void writeV3F1000(std::ostream &os, v3f p)
347-
{
348-
char buf[12];
349-
writeV3F1000((u8*)buf, p);
350-
os.write(buf, 12);
351-
}
352-
inline v3f readV3F1000(std::istream &is)
258+
inline void writeARGB8(u8 *data, video::SColor p)
353259
{
354-
char buf[12];
355-
is.read(buf, 12);
356-
return readV3F1000((u8*)buf);
260+
writeU32(data, p.color);
357261
}
358262

359-
inline void writeV2F1000(std::ostream &os, v2f p)
360-
{
361-
char buf[8];
362-
writeV2F1000((u8*)buf, p);
363-
os.write(buf, 8);
364-
}
365-
inline v2f readV2F1000(std::istream &is)
263+
inline void writeV2S16(u8 *data, v2s16 p)
366264
{
367-
char buf[8] = {0};
368-
is.read(buf, 8);
369-
return readV2F1000((u8*)buf);
265+
writeS16(&data[0], p.X);
266+
writeS16(&data[2], p.Y);
370267
}
371268

372-
inline void writeV2S16(std::ostream &os, v2s16 p)
373-
{
374-
char buf[4];
375-
writeV2S16((u8*)buf, p);
376-
os.write(buf, 4);
377-
}
378-
inline v2s16 readV2S16(std::istream &is)
269+
inline void writeV3S16(u8 *data, v3s16 p)
379270
{
380-
char buf[4] = {0};
381-
is.read(buf, 4);
382-
return readV2S16((u8*)buf);
271+
writeS16(&data[0], p.X);
272+
writeS16(&data[2], p.Y);
273+
writeS16(&data[4], p.Z);
383274
}
384275

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)
276+
inline void writeV2S32(u8 *data, v2s32 p)
392277
{
393-
char buf[8] = {0};
394-
is.read(buf, 8);
395-
return readV2S32((u8*)buf);
278+
writeS32(&data[0], p.X);
279+
writeS32(&data[4], p.Y);
396280
}
397281

398-
inline void writeV3S16(std::ostream &os, v3s16 p)
399-
{
400-
char buf[6];
401-
writeV3S16((u8*)buf, p);
402-
os.write(buf, 6);
403-
}
404-
inline v3s16 readV3S16(std::istream &is)
282+
inline void writeV3S32(u8 *data, v3s32 p)
405283
{
406-
char buf[6] = {0};
407-
is.read(buf, 6);
408-
return readV3S16((u8*)buf);
284+
writeS32(&data[0], p.X);
285+
writeS32(&data[4], p.Y);
286+
writeS32(&data[8], p.Z);
409287
}
410288

411-
inline void writeARGB8(std::ostream &os, video::SColor p)
289+
inline void writeV2F1000(u8 *data, v2f p)
412290
{
413-
char buf[4];
414-
writeARGB8((u8*)buf, p);
415-
os.write(buf, 4);
291+
writeF1000(&data[0], p.X);
292+
writeF1000(&data[4], p.Y);
416293
}
417294

418-
inline video::SColor readARGB8(std::istream &is)
295+
inline void writeV3F1000(u8 *data, v3f p)
419296
{
420-
char buf[4] = {0};
421-
is.read(buf, 4);
422-
return readARGB8((u8*)buf);
297+
writeF1000(&data[0], p.X);
298+
writeF1000(&data[4], p.Y);
299+
writeF1000(&data[8], p.Z);
423300
}
424301

425-
/*
426-
More serialization stuff
427-
*/
428-
429-
// 64 MB ought to be enough for anybody - Billy G.
430-
#define LONG_STRING_MAX (64 * 1024 * 1024)
302+
////
303+
//// Iostream wrapper for data read/write
304+
////
305+
306+
#define MAKE_STREAM_READ_FXN(T, N, S) \
307+
inline T read ## N(std::istream &is) \
308+
{ \
309+
char buf[S] = {0}; \
310+
is.read(buf, sizeof(buf)); \
311+
return read ## N((u8 *)buf); \
312+
}
313+
314+
#define MAKE_STREAM_WRITE_FXN(T, N, S) \
315+
inline void write ## N(std::ostream &os, T val) \
316+
{ \
317+
char buf[S]; \
318+
write ## N((u8 *)buf, val); \
319+
os.write(buf, sizeof(buf)); \
320+
}
321+
322+
MAKE_STREAM_READ_FXN(u8, U8, 1);
323+
MAKE_STREAM_READ_FXN(u16, U16, 2);
324+
MAKE_STREAM_READ_FXN(u32, U32, 4);
325+
MAKE_STREAM_READ_FXN(u64, U64, 8);
326+
MAKE_STREAM_READ_FXN(s8, S8, 1);
327+
MAKE_STREAM_READ_FXN(s16, S16, 2);
328+
MAKE_STREAM_READ_FXN(s32, S32, 4);
329+
MAKE_STREAM_READ_FXN(s64, S64, 8);
330+
MAKE_STREAM_READ_FXN(f32, F1000, 4);
331+
MAKE_STREAM_READ_FXN(v2s16, V2S16, 4);
332+
MAKE_STREAM_READ_FXN(v3s16, V3S16, 6);
333+
MAKE_STREAM_READ_FXN(v2s32, V2S32, 8);
334+
MAKE_STREAM_READ_FXN(v3s32, V3S32, 12);
335+
MAKE_STREAM_READ_FXN(v2f, V2F1000, 8);
336+
MAKE_STREAM_READ_FXN(v3f, V3F1000, 12);
337+
MAKE_STREAM_READ_FXN(video::SColor, ARGB8, 4);
338+
339+
MAKE_STREAM_WRITE_FXN(u8, U8, 1);
340+
MAKE_STREAM_WRITE_FXN(u16, U16, 2);
341+
MAKE_STREAM_WRITE_FXN(u32, U32, 4);
342+
MAKE_STREAM_WRITE_FXN(u64, U64, 8);
343+
MAKE_STREAM_WRITE_FXN(s8, S8, 1);
344+
MAKE_STREAM_WRITE_FXN(s16, S16, 2);
345+
MAKE_STREAM_WRITE_FXN(s32, S32, 4);
346+
MAKE_STREAM_WRITE_FXN(s64, S64, 8);
347+
MAKE_STREAM_WRITE_FXN(f32, F1000, 4);
348+
MAKE_STREAM_WRITE_FXN(v2s16, V2S16, 4);
349+
MAKE_STREAM_WRITE_FXN(v3s16, V3S16, 6);
350+
MAKE_STREAM_WRITE_FXN(v2s32, V2S32, 8);
351+
MAKE_STREAM_WRITE_FXN(v3s32, V3S32, 12);
352+
MAKE_STREAM_WRITE_FXN(v2f, V2F1000, 8);
353+
MAKE_STREAM_WRITE_FXN(v3f, V3F1000, 12);
354+
MAKE_STREAM_WRITE_FXN(video::SColor, ARGB8, 4);
355+
356+
////
357+
//// More serialization stuff
358+
////
431359

432360
// Creates a string with the length as the first two bytes
433361
std::string serializeString(const std::string &plain);
@@ -467,4 +395,3 @@ bool deSerializeStringToStruct(std::string valstr,
467395
std::string format, void *out, size_t olen);
468396

469397
#endif
470-

0 commit comments

Comments
 (0)
Please sign in to comment.