1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22
23 #include "../Precompiled.h"
24
25 #include "../IO/Serializer.h"
26
27 #include "../DebugNew.h"
28
29 namespace Urho3D
30 {
31
32 static const float q = 32767.0f;
33
~Serializer()34 Serializer::~Serializer()
35 {
36 }
37
WriteInt64(long long value)38 bool Serializer::WriteInt64(long long value)
39 {
40 return Write(&value, sizeof value) == sizeof value;
41 }
42
WriteInt(int value)43 bool Serializer::WriteInt(int value)
44 {
45 return Write(&value, sizeof value) == sizeof value;
46 }
47
WriteShort(short value)48 bool Serializer::WriteShort(short value)
49 {
50 return Write(&value, sizeof value) == sizeof value;
51 }
52
WriteByte(signed char value)53 bool Serializer::WriteByte(signed char value)
54 {
55 return Write(&value, sizeof value) == sizeof value;
56 }
57
WriteUInt64(unsigned long long value)58 bool Serializer::WriteUInt64(unsigned long long value)
59 {
60 return Write(&value, sizeof value) == sizeof value;
61 }
62
WriteUInt(unsigned value)63 bool Serializer::WriteUInt(unsigned value)
64 {
65 return Write(&value, sizeof value) == sizeof value;
66 }
67
WriteUShort(unsigned short value)68 bool Serializer::WriteUShort(unsigned short value)
69 {
70 return Write(&value, sizeof value) == sizeof value;
71 }
72
WriteUByte(unsigned char value)73 bool Serializer::WriteUByte(unsigned char value)
74 {
75 return Write(&value, sizeof value) == sizeof value;
76 }
77
WriteBool(bool value)78 bool Serializer::WriteBool(bool value)
79 {
80 return WriteUByte((unsigned char)(value ? 1 : 0)) == 1;
81 }
82
WriteFloat(float value)83 bool Serializer::WriteFloat(float value)
84 {
85 return Write(&value, sizeof value) == sizeof value;
86 }
87
WriteDouble(double value)88 bool Serializer::WriteDouble(double value)
89 {
90 return Write(&value, sizeof value) == sizeof value;
91 }
92
WriteIntRect(const IntRect & value)93 bool Serializer::WriteIntRect(const IntRect& value)
94 {
95 return Write(value.Data(), sizeof value) == sizeof value;
96 }
97
WriteIntVector2(const IntVector2 & value)98 bool Serializer::WriteIntVector2(const IntVector2& value)
99 {
100 return Write(value.Data(), sizeof value) == sizeof value;
101 }
102
WriteIntVector3(const IntVector3 & value)103 bool Serializer::WriteIntVector3(const IntVector3& value)
104 {
105 return Write(value.Data(), sizeof value) == sizeof value;
106 }
107
WriteRect(const Rect & value)108 bool Serializer::WriteRect(const Rect& value)
109 {
110 return Write(value.Data(), sizeof value) == sizeof value;
111 }
112
WriteVector2(const Vector2 & value)113 bool Serializer::WriteVector2(const Vector2& value)
114 {
115 return Write(value.Data(), sizeof value) == sizeof value;
116 }
117
WriteVector3(const Vector3 & value)118 bool Serializer::WriteVector3(const Vector3& value)
119 {
120 return Write(value.Data(), sizeof value) == sizeof value;
121 }
122
WritePackedVector3(const Vector3 & value,float maxAbsCoord)123 bool Serializer::WritePackedVector3(const Vector3& value, float maxAbsCoord)
124 {
125 short coords[3];
126 float v = 32767.0f / maxAbsCoord;
127
128 coords[0] = (short)(Clamp(value.x_, -maxAbsCoord, maxAbsCoord) * v + 0.5f);
129 coords[1] = (short)(Clamp(value.y_, -maxAbsCoord, maxAbsCoord) * v + 0.5f);
130 coords[2] = (short)(Clamp(value.z_, -maxAbsCoord, maxAbsCoord) * v + 0.5f);
131 return Write(&coords[0], sizeof coords) == sizeof coords;
132 }
133
WriteVector4(const Vector4 & value)134 bool Serializer::WriteVector4(const Vector4& value)
135 {
136 return Write(value.Data(), sizeof value) == sizeof value;
137 }
138
WriteQuaternion(const Quaternion & value)139 bool Serializer::WriteQuaternion(const Quaternion& value)
140 {
141 return Write(value.Data(), sizeof value) == sizeof value;
142 }
143
WritePackedQuaternion(const Quaternion & value)144 bool Serializer::WritePackedQuaternion(const Quaternion& value)
145 {
146 short coords[4];
147 Quaternion norm = value.Normalized();
148
149 coords[0] = (short)(Clamp(norm.w_, -1.0f, 1.0f) * q + 0.5f);
150 coords[1] = (short)(Clamp(norm.x_, -1.0f, 1.0f) * q + 0.5f);
151 coords[2] = (short)(Clamp(norm.y_, -1.0f, 1.0f) * q + 0.5f);
152 coords[3] = (short)(Clamp(norm.z_, -1.0f, 1.0f) * q + 0.5f);
153 return Write(&coords[0], sizeof coords) == sizeof coords;
154 }
155
WriteMatrix3(const Matrix3 & value)156 bool Serializer::WriteMatrix3(const Matrix3& value)
157 {
158 return Write(value.Data(), sizeof value) == sizeof value;
159 }
160
WriteMatrix3x4(const Matrix3x4 & value)161 bool Serializer::WriteMatrix3x4(const Matrix3x4& value)
162 {
163 return Write(value.Data(), sizeof value) == sizeof value;
164 }
165
WriteMatrix4(const Matrix4 & value)166 bool Serializer::WriteMatrix4(const Matrix4& value)
167 {
168 return Write(value.Data(), sizeof value) == sizeof value;
169 }
170
WriteColor(const Color & value)171 bool Serializer::WriteColor(const Color& value)
172 {
173 return Write(value.Data(), sizeof value) == sizeof value;
174 }
175
WriteBoundingBox(const BoundingBox & value)176 bool Serializer::WriteBoundingBox(const BoundingBox& value)
177 {
178 bool success = true;
179 success &= WriteVector3(value.min_);
180 success &= WriteVector3(value.max_);
181 return success;
182 }
183
WriteString(const String & value)184 bool Serializer::WriteString(const String& value)
185 {
186 const char* chars = value.CString();
187 // Count length to the first zero, because ReadString() does the same
188 unsigned length = String::CStringLength(chars);
189 return Write(chars, length + 1) == length + 1;
190 }
191
WriteFileID(const String & value)192 bool Serializer::WriteFileID(const String& value)
193 {
194 bool success = true;
195 unsigned length = Min(value.Length(), 4U);
196
197 success &= Write(value.CString(), length) == length;
198 for (unsigned i = value.Length(); i < 4; ++i)
199 success &= WriteByte(' ');
200 return success;
201 }
202
WriteStringHash(const StringHash & value)203 bool Serializer::WriteStringHash(const StringHash& value)
204 {
205 return WriteUInt(value.Value());
206 }
207
WriteBuffer(const PODVector<unsigned char> & value)208 bool Serializer::WriteBuffer(const PODVector<unsigned char>& value)
209 {
210 bool success = true;
211 unsigned size = value.Size();
212
213 success &= WriteVLE(size);
214 if (size)
215 success &= Write(&value[0], size) == size;
216 return success;
217 }
218
WriteResourceRef(const ResourceRef & value)219 bool Serializer::WriteResourceRef(const ResourceRef& value)
220 {
221 bool success = true;
222 success &= WriteStringHash(value.type_);
223 success &= WriteString(value.name_);
224 return success;
225 }
226
WriteResourceRefList(const ResourceRefList & value)227 bool Serializer::WriteResourceRefList(const ResourceRefList& value)
228 {
229 bool success = true;
230
231 success &= WriteStringHash(value.type_);
232 success &= WriteVLE(value.names_.Size());
233 for (unsigned i = 0; i < value.names_.Size(); ++i)
234 success &= WriteString(value.names_[i]);
235
236 return success;
237 }
238
WriteVariant(const Variant & value)239 bool Serializer::WriteVariant(const Variant& value)
240 {
241 bool success = true;
242 VariantType type = value.GetType();
243
244 success &= WriteUByte((unsigned char)type);
245 success &= WriteVariantData(value);
246 return success;
247 }
248
WriteVariantData(const Variant & value)249 bool Serializer::WriteVariantData(const Variant& value)
250 {
251 switch (value.GetType())
252 {
253 case VAR_NONE:
254 return true;
255
256 case VAR_INT:
257 return WriteInt(value.GetInt());
258
259 case VAR_INT64:
260 return WriteInt64(value.GetInt64());
261
262 case VAR_BOOL:
263 return WriteBool(value.GetBool());
264
265 case VAR_FLOAT:
266 return WriteFloat(value.GetFloat());
267
268 case VAR_VECTOR2:
269 return WriteVector2(value.GetVector2());
270
271 case VAR_VECTOR3:
272 return WriteVector3(value.GetVector3());
273
274 case VAR_VECTOR4:
275 return WriteVector4(value.GetVector4());
276
277 case VAR_QUATERNION:
278 return WriteQuaternion(value.GetQuaternion());
279
280 case VAR_COLOR:
281 return WriteColor(value.GetColor());
282
283 case VAR_STRING:
284 return WriteString(value.GetString());
285
286 case VAR_BUFFER:
287 return WriteBuffer(value.GetBuffer());
288
289 // Serializing pointers is not supported. Write null
290 case VAR_VOIDPTR:
291 case VAR_PTR:
292 return WriteUInt(0);
293
294 case VAR_RESOURCEREF:
295 return WriteResourceRef(value.GetResourceRef());
296
297 case VAR_RESOURCEREFLIST:
298 return WriteResourceRefList(value.GetResourceRefList());
299
300 case VAR_VARIANTVECTOR:
301 return WriteVariantVector(value.GetVariantVector());
302
303 case VAR_STRINGVECTOR:
304 return WriteStringVector(value.GetStringVector());
305
306 case VAR_VARIANTMAP:
307 return WriteVariantMap(value.GetVariantMap());
308
309 case VAR_INTRECT:
310 return WriteIntRect(value.GetIntRect());
311
312 case VAR_INTVECTOR2:
313 return WriteIntVector2(value.GetIntVector2());
314
315 case VAR_INTVECTOR3:
316 return WriteIntVector3(value.GetIntVector3());
317
318 case VAR_MATRIX3:
319 return WriteMatrix3(value.GetMatrix3());
320
321 case VAR_MATRIX3X4:
322 return WriteMatrix3x4(value.GetMatrix3x4());
323
324 case VAR_MATRIX4:
325 return WriteMatrix4(value.GetMatrix4());
326
327 case VAR_DOUBLE:
328 return WriteDouble(value.GetDouble());
329
330 default:
331 return false;
332 }
333 }
334
WriteVariantVector(const VariantVector & value)335 bool Serializer::WriteVariantVector(const VariantVector& value)
336 {
337 bool success = true;
338 success &= WriteVLE(value.Size());
339 for (VariantVector::ConstIterator i = value.Begin(); i != value.End(); ++i)
340 success &= WriteVariant(*i);
341 return success;
342 }
343
WriteStringVector(const StringVector & value)344 bool Serializer::WriteStringVector(const StringVector& value)
345 {
346 bool success = true;
347 success &= WriteVLE(value.Size());
348 for (StringVector::ConstIterator i = value.Begin(); i != value.End(); ++i)
349 success &= WriteString(*i);
350 return success;
351 }
352
WriteVariantMap(const VariantMap & value)353 bool Serializer::WriteVariantMap(const VariantMap& value)
354 {
355 bool success = true;
356 success &= WriteVLE(value.Size());
357 for (VariantMap::ConstIterator i = value.Begin(); i != value.End(); ++i)
358 {
359 WriteStringHash(i->first_);
360 WriteVariant(i->second_);
361 }
362 return success;
363 }
364
WriteVLE(unsigned value)365 bool Serializer::WriteVLE(unsigned value)
366 {
367 unsigned char data[4];
368
369 if (value < 0x80)
370 return WriteUByte((unsigned char)value);
371 else if (value < 0x4000)
372 {
373 data[0] = (unsigned char)(value | 0x80);
374 data[1] = (unsigned char)(value >> 7);
375 return Write(data, 2) == 2;
376 }
377 else if (value < 0x200000)
378 {
379 data[0] = (unsigned char)(value | 0x80);
380 data[1] = (unsigned char)((value >> 7) | 0x80);
381 data[2] = (unsigned char)(value >> 14);
382 return Write(data, 3) == 3;
383 }
384 else
385 {
386 data[0] = (unsigned char)(value | 0x80);
387 data[1] = (unsigned char)((value >> 7) | 0x80);
388 data[2] = (unsigned char)((value >> 14) | 0x80);
389 data[3] = (unsigned char)(value >> 21);
390 return Write(data, 4) == 4;
391 }
392 }
393
WriteNetID(unsigned value)394 bool Serializer::WriteNetID(unsigned value)
395 {
396 return Write(&value, 3) == 3;
397 }
398
WriteLine(const String & value)399 bool Serializer::WriteLine(const String& value)
400 {
401 bool success = true;
402 success &= Write(value.CString(), value.Length()) == value.Length();
403 success &= WriteUByte(13);
404 success &= WriteUByte(10);
405 return success;
406 }
407
408 }
409