Added missing newline chars to logging commands
[platform/core/uifw/dali-core.git] / dali / internal / event / resources / archive.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/resources/archive.h>
20
21 // EXTERNAL INCLUDES
22 #include <fstream>
23 #include <ios>
24
25 // INTERNAL INCLUDES
26 #include <dali/integration-api/debug.h>
27 #include <dali/public-api/common/dali-common.h>
28 #include <dali/public-api/math/vector2.h>
29 #include <dali/public-api/math/vector3.h>
30 #include <dali/public-api/math/vector4.h>
31 #include <dali/public-api/math/matrix.h>
32 #include <dali/public-api/math/quaternion.h>
33
34 namespace Dali
35 {
36
37 namespace Internal
38 {
39
40 /*--------- Archive ---------*/
41
42 Archive::Archive(std::streambuf& buf)
43 : mVersion(0),
44   mStream(&buf),
45   mResult(true)
46 {
47 }
48
49 Archive::~Archive()
50 {
51   if(!mChunkStack.empty())
52   {
53     DALI_LOG_ERROR("mChunkStack should be empty!\n");
54   }
55 }
56
57
58 /*--------- OutputArchive ---------*/
59
60 OutputArchive::OutputArchive(std::streambuf& buf, const unsigned int version)
61 : Archive(buf)
62 {
63   SetVersion(version);
64 }
65
66 OutputArchive::~OutputArchive()
67 {
68 }
69
70 bool OutputArchive::Write(const char* data, const unsigned int length)
71 {
72   if( mResult )
73   {
74     mStream.write(data, length);
75     if( mStream.bad() )
76     {
77       mResult = false;
78     }
79   }
80   return mResult;
81 }
82
83 bool OutputArchive::OpenChunk(const unsigned int fourCC)
84 {
85   const unsigned int zero = 0;
86
87   // Get current position in stream
88   std::streampos currentPos = mStream.tellp();
89
90   // Ensure chunk will start at an even byte
91   // (necessary for nested chunks)
92   if( currentPos & 1 )
93   {
94     const char padding = 0;
95     Write(&padding, sizeof(char));
96   }
97
98   // Write chunk header to stream
99   Write(reinterpret_cast<const char*>(&fourCC), sizeof(unsigned int));
100
101   // Push chunkHeader information to chunk LIFO stack
102   mChunkStack.push(std::make_pair(fourCC, mStream.tellp()));
103
104   // Write zero for chunk length temporarily. This will be overwritten in CloseChunk
105   Write(reinterpret_cast<const char*>(&zero), sizeof(unsigned int));
106
107   return mResult;
108 }
109
110 void OutputArchive::CloseChunk()
111 {
112   // Get current position in stream
113   std::streampos currentPos = mStream.tellp();
114
115   // retrieve chunk header
116   ChunkHeader chunkHeader = mChunkStack.top();
117   mChunkStack.pop();
118
119   // seek to chunk header in stream
120   mStream.seekp(chunkHeader.second);
121
122   // calculate and write chunk size
123   unsigned int chunkLength = static_cast<unsigned int>(currentPos - chunkHeader.second) - sizeof(unsigned int);
124   Write(reinterpret_cast<const char*>(&chunkLength), sizeof(unsigned int));
125
126   // return to current position in stream
127   mStream.seekp(currentPos);
128
129   // Ensure next chunk will start at on even byte
130   if( currentPos & 1 )
131   {
132     const char padding = 0;
133     Write(&padding, 1);
134   }
135 }
136
137
138 /*--------- InputArchive ---------*/
139
140 InputArchive::InputArchive(std::streambuf& buf, const unsigned int version)
141 : Archive(buf),
142   mFileVersion(0)
143 {
144   SetVersion(version);
145 }
146
147 InputArchive::~InputArchive()
148 {
149 }
150
151 bool InputArchive::Read(char* data, const unsigned int length)
152 {
153   if( mResult )
154   {
155     mStream.read(data, length);
156     if( mStream.bad() )
157     {
158       mResult = false;
159     }
160   }
161   return mResult;
162 }
163
164 bool InputArchive::OpenChunk(const unsigned int fourCC)
165 {
166   if( PeekChunk() != fourCC )
167   {
168     // trying to open incorrect chunk, mark archive error
169     mResult = false;
170     return mResult;
171   }
172
173   union
174   {
175     unsigned int fourCC_int;
176     char fourCC_char[4];
177   };
178   fourCC_int = 0;
179
180   if( mStream.tellg() & 1 )
181   {
182     mStream.seekg(1, std::ios_base::cur);
183   }
184
185   Read(fourCC_char, sizeof(unsigned int));
186
187   // Push chunkHeader information to chunk LIFO stack
188   mChunkStack.push(std::make_pair(fourCC_int, mStream.tellg()));
189
190 # if defined(DEBUG_ENABLED)
191
192   unsigned int chunkLength;
193   Read(reinterpret_cast<char*>(&chunkLength), sizeof(unsigned int));
194
195   DALI_LOG_INFO(Debug::Filter::gModel, Debug::Verbose, "Enter: %c%c%c%c(%d)\n",
196                 fourCC_char[0], fourCC_char[1], fourCC_char[2], fourCC_char[3], chunkLength);
197
198 # else  // defined(DEBUG_ENABLED)
199
200   // skip chunk length
201   mStream.seekg(sizeof(unsigned int), std::ios_base::cur);
202
203 # endif // defined(DEBUG_ENABLED)
204
205   return mResult;
206 }
207
208 void InputArchive::SkipChunk(const unsigned int fourCC)
209 {
210   // Ensure the next chunk is the correct one
211   if( PeekChunk() != fourCC )
212   {
213     return;
214   }
215
216   union
217   {
218     unsigned int fourCC_int;
219     char fourCC_char[4];
220   };
221   unsigned int chunkLength;
222
223   if( mStream.tellg() & 1 )
224   {
225     mStream.seekg(1, std::ios_base::cur);
226   }
227
228   Read(fourCC_char, sizeof(unsigned int));
229   Read(reinterpret_cast<char*>(&chunkLength), sizeof(unsigned int));
230
231   DALI_LOG_INFO(Debug::Filter::gModel, Debug::Verbose, "Enter: %c%c%c%c(%d)\n",
232                 fourCC_char[0], fourCC_char[1], fourCC_char[2], fourCC_char[3], chunkLength);
233
234   if( chunkLength & 1 )
235   {
236     ++chunkLength;
237   }
238
239   mStream.seekg(chunkLength, std::ios_base::cur);
240 }
241
242 void InputArchive::CloseChunk()
243 {
244   ChunkHeader chunkHeader = mChunkStack.top();
245   mChunkStack.pop();
246
247   mStream.seekg(chunkHeader.second);
248
249   unsigned int chunkLength;
250   Read(reinterpret_cast<char*>(&chunkLength), sizeof(unsigned int));
251
252   if( chunkLength & 1)
253   {
254     ++chunkLength;
255   }
256   mStream.seekg(chunkLength, std::ios_base::cur);
257 }
258
259 unsigned int InputArchive::PeekChunk()
260 {
261   union
262   {
263     unsigned int fourCC_int;
264     char fourCC_char[4];
265   };
266   fourCC_int = 0;
267
268   // Get current position in stream
269   std::streampos currentPos = mStream.tellg();
270
271   // Ensure next read will be from an even byte
272   if( currentPos & 1 )
273   {
274     mStream.seekg(1, std::ios_base::cur);
275   }
276
277   // Read tag
278   Read(fourCC_char, sizeof(unsigned int));
279
280 # if defined(DEBUG_ENABLED)
281   unsigned int chunkLength;
282   Read(reinterpret_cast<char*>(&chunkLength), sizeof(unsigned int));
283
284   DALI_LOG_INFO(Debug::Filter::gModel, Debug::Verbose, "Peek: %c%c%c%c(%d)\n",
285                 fourCC_char[0], fourCC_char[1], fourCC_char[2], fourCC_char[3], chunkLength);
286 # endif // defined(DEBUG_ENABLED)
287
288   // return to original position in stream
289   mStream.seekg(currentPos);
290
291   return fourCC_int;
292 }
293
294 namespace Serialize
295 {
296 /*------ serialization overrides of operator<< () and operator>> () ------*/
297
298 Archive& operator<< (Archive& ar, const char& t)
299 {
300   ar.Write((char*)&t, sizeof(t));
301
302   return ar;
303 }
304
305 Archive& operator>> (Archive& ar, char& t)
306 {
307   ar.Read((char*)&t, sizeof(t));
308
309   return ar;
310 }
311
312 Archive& operator<< (Archive& ar, const unsigned char& t)
313 {
314   ar.Write((char*)&t, sizeof(t));
315   return ar;
316 }
317
318 Archive& operator>> (Archive& ar, unsigned char& t)
319 {
320   ar.Read((char*)&t, sizeof(t));
321
322   return ar;
323 }
324
325 Archive& operator<< (Archive& ar, const bool& t)
326 {
327   char value = t ? 1 : 0;
328   ar.Write(&value, sizeof(value));
329   return ar;
330 }
331
332 Archive& operator>> (Archive& ar, bool& t)
333 {
334   char value;
335   ar.Read(&value, sizeof(value));
336   t = value != 0;
337
338   return ar;
339 }
340
341 Archive& operator<< (Archive& ar, const short& t)
342 {
343   ar.Write((char*)&t, sizeof(t));
344
345   return ar;
346 }
347
348 Archive& operator>> (Archive& ar, short& t)
349 {
350   ar.Read((char*)&t, sizeof(t));
351
352   return ar;
353 }
354
355 Archive& operator<< (Archive& ar, const unsigned short& t)
356 {
357   ar.Write((char*)&t, sizeof(t));
358
359   return ar;
360 }
361
362 Archive& operator>> (Archive& ar, unsigned short& t)
363 {
364   ar.Read((char*)&t, sizeof(t));
365
366   return ar;
367 }
368
369 Archive& operator<< (Archive& ar, const int& t)
370 {
371   ar.Write((char*)&t, sizeof(t));
372
373   return ar;
374 }
375
376 Archive& operator>> (Archive& ar, int& t)
377 {
378   ar.Read((char*)&t, sizeof(t));
379
380   return ar;
381 }
382
383 Archive& operator<< (Archive& ar, const unsigned int& t)
384 {
385   ar.Write((char*)&t, sizeof(t));
386
387   return ar;
388 }
389
390 Archive& operator>> (Archive& ar, unsigned int& t)
391 {
392   ar.Read((char*)&t, sizeof(t));
393
394   return ar;
395 }
396
397 // float
398 Archive& operator<< (Archive& ar, const float& t)
399 {
400   ar.Write((char*)&t, sizeof(t));
401
402   return ar;
403 }
404
405 Archive& operator>> (Archive& ar, float& t)
406 {
407   ar.Read((char*)&t, sizeof(t));
408
409   return ar;
410 }
411
412 // Vector2
413 Archive& operator<< (Archive& ar, const Vector2& t)
414 {
415   ar << t.x << t.y;
416   return ar;
417 }
418
419 Archive& operator>> (Archive& ar, Vector2& t)
420 {
421   ar >> t.x >> t.y;
422   return ar;
423 }
424
425 // Vector3
426 Archive& operator<< (Archive& ar, const Vector3& t)
427 {
428   ar << t.x << t.y << t.z;
429   return ar;
430 }
431
432 Archive& operator>> (Archive& ar, Vector3& t)
433 {
434   ar >> t.x >> t.y >> t.z;
435   return ar;
436 }
437
438 // Vector4
439 Archive& operator<< (Archive& ar, const Vector4& t)
440 {
441   ar << t.x << t.y << t.z << t.w;
442   return ar;
443 }
444
445 Archive& operator>> (Archive& ar, Vector4& t)
446 {
447   ar >> t.x >> t.y >> t.z >> t.w;
448   return ar;
449 }
450
451 // Quaternion
452 Archive& operator<< (Archive& ar, const Quaternion& t)
453 {
454   ar << t.mVector;
455
456   return ar;
457 }
458
459 Archive& operator>> (Archive& ar, Quaternion& t)
460 {
461   ar >> t.mVector;
462
463   return ar;
464 }
465
466 // Matrix
467 Archive& operator<< (Archive& ar, const Matrix& t)
468 {
469   const float* data = t.AsFloat();
470
471   for( unsigned i = 0; i < sizeof(Matrix) / sizeof(float); ++i)
472   {
473     ar << *data;
474     ++data;
475   }
476
477   return ar;
478 }
479
480 Archive& operator>> (Archive& ar, Matrix& t)
481 {
482   float* data = t.AsFloat();
483
484   for( unsigned i = 0; i < sizeof(Matrix) / sizeof(float); ++i)
485   {
486     ar >> *data;
487     ++data;
488   }
489
490   return ar;
491 }
492
493 /*---- std::string ----*/
494 Archive& operator<< (Archive& ar, const std::string& t)
495 {
496   unsigned int length = t.size();
497   ar << length;
498   ar.Write(t.data(), length);
499
500   return ar;
501 }
502
503 Archive& operator>> (Archive& ar, std::string& t)
504 {
505   unsigned int length = 0;
506   char* data = NULL;
507
508   ar >> length;
509   data = new char[ length ];
510   ar.Read(data, length);
511   t.assign(data, length);
512   delete [] data;
513
514   return ar;
515 }
516
517 } // namespace Serialize
518
519 } // Internal
520
521 } // Dali
522