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