Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreSerializer.cpp @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

File size: 12.8 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreStableHeaders.h"
30
31#include "OgreSerializer.h"
32#include "OgreLogManager.h"
33#include "OgreDataStream.h"
34#include "OgreException.h"
35#include "OgreVector3.h"
36#include "OgreQuaternion.h"
37
38
39namespace Ogre {
40
41    /// stream overhead = ID + size
42    const size_t STREAM_OVERHEAD_SIZE = sizeof(uint16) + sizeof(uint32);
43    const uint16 HEADER_STREAM_ID = 0x1000;
44    const uint16 OTHER_ENDIAN_HEADER_STREAM_ID = 0x0010;
45    //---------------------------------------------------------------------
46    Serializer::Serializer()
47    {
48        // Version number
49        mVersion = "[Serializer_v1.00]";
50                mFlipEndian = false;
51    }
52    //---------------------------------------------------------------------
53    Serializer::~Serializer()
54    {
55    }
56    //---------------------------------------------------------------------
57        void Serializer::determineEndianness(DataStreamPtr& stream)
58        {
59                if (stream->tell() != 0)
60                {
61                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
62                                "Can only determine the endianness of the input stream if it "
63                                "is at the start", "Serializer::determineEndianness");
64                }
65                               
66                uint16 dest;
67                // read header id manually (no conversion)
68        stream->read(&dest, sizeof(uint16));
69                // skip back
70                stream->skip(0 - sizeof(uint16));
71                if (dest == HEADER_STREAM_ID)
72                {
73                        mFlipEndian = false;
74                }
75                else if (dest == OTHER_ENDIAN_HEADER_STREAM_ID)
76                {
77                        mFlipEndian = true;
78                }
79                else
80                {
81                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
82                                "Can't find a header chunk to determine endianness",
83                                "Serializer::determineEndianness");
84                }
85        }
86    //---------------------------------------------------------------------
87        void Serializer::determineEndianness(Endian requestedEndian)
88        {
89                switch(requestedEndian)
90                {
91                case ENDIAN_NATIVE:
92                        mFlipEndian = false;
93                        break;
94                case ENDIAN_BIG:
95#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
96                        mFlipEndian = false;
97#else
98                        mFlipEndian = true;
99#endif
100                        break;
101                case ENDIAN_LITTLE:
102#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
103                        mFlipEndian = true;
104#else
105                        mFlipEndian = false;
106#endif
107                        break;
108                }
109        }
110    //---------------------------------------------------------------------
111    void Serializer::writeFileHeader(void)
112    {
113       
114        uint16 val = HEADER_STREAM_ID;
115        writeShorts(&val, 1);
116
117        writeString(mVersion);
118
119    }
120    //---------------------------------------------------------------------
121    void Serializer::writeChunkHeader(uint16 id, size_t size)
122    {
123        writeShorts(&id, 1);
124                uint32 uint32size = static_cast<uint32>(size);
125        writeInts(&uint32size, 1);
126    }
127    //---------------------------------------------------------------------
128    void Serializer::writeFloats(const float* const pFloat, size_t count)
129    {
130                if (mFlipEndian)
131                {
132            float * pFloatToWrite = (float *)malloc(sizeof(float) * count);
133            memcpy(pFloatToWrite, pFloat, sizeof(float) * count);
134           
135            flipToLittleEndian(pFloatToWrite, sizeof(float), count);
136            writeData(pFloatToWrite, sizeof(float), count);
137           
138            free(pFloatToWrite);
139                }
140                else
141                {
142            writeData(pFloat, sizeof(float), count);
143                }
144    }
145    //---------------------------------------------------------------------
146    void Serializer::writeFloats(const double* const pDouble, size_t count)
147    {
148                // Convert to float, then write
149                float* tmp = new float[count];
150                for (unsigned int i = 0; i < count; ++i)
151                {
152                        tmp[i] = static_cast<float>(pDouble[i]);
153                }
154                if(mFlipEndian)
155                {
156            flipToLittleEndian(tmp, sizeof(float), count);
157            writeData(tmp, sizeof(float), count);
158                }
159                else
160                {
161            writeData(tmp, sizeof(float), count);
162                }
163                delete [] tmp;
164    }
165    //---------------------------------------------------------------------
166    void Serializer::writeShorts(const uint16* const pShort, size_t count = 1)
167    {
168                if(mFlipEndian)
169                {
170            unsigned short * pShortToWrite = (unsigned short *)malloc(sizeof(unsigned short) * count);
171            memcpy(pShortToWrite, pShort, sizeof(unsigned short) * count);
172           
173            flipToLittleEndian(pShortToWrite, sizeof(unsigned short), count);
174            writeData(pShortToWrite, sizeof(unsigned short), count);
175           
176            free(pShortToWrite);
177                }
178                else
179                {
180            writeData(pShort, sizeof(unsigned short), count);
181                }
182    }
183    //---------------------------------------------------------------------
184    void Serializer::writeInts(const uint32* const pInt, size_t count = 1)
185    {
186                if(mFlipEndian)
187                {
188            unsigned int * pIntToWrite = (unsigned int *)malloc(sizeof(unsigned int) * count);
189            memcpy(pIntToWrite, pInt, sizeof(unsigned int) * count);
190           
191            flipToLittleEndian(pIntToWrite, sizeof(unsigned int), count);
192            writeData(pIntToWrite, sizeof(unsigned int), count);
193           
194            free(pIntToWrite);
195                }
196                else
197                {
198            writeData(pInt, sizeof(unsigned int), count);
199                }
200    }
201    //---------------------------------------------------------------------
202    //---------------------------------------------------------------------
203    void Serializer::writeBools(const bool* const pBool, size_t count = 1)
204    {
205    //no endian flipping for 1-byte bools
206    //XXX Nasty Hack to convert to 1-byte bools
207#       if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
208        char * pCharToWrite = (char *)malloc(sizeof(char) * count);
209        for(int i = 0; i < count; i++)
210        {
211            *(char *)(pCharToWrite + i) = *(bool *)(pBool + i);
212        }
213       
214        writeData(pCharToWrite, sizeof(char), count);
215       
216        free(pCharToWrite);
217#       else
218        writeData(pBool, sizeof(bool), count);
219#       endif
220
221    }
222   
223    //---------------------------------------------------------------------
224    void Serializer::writeData(const void* const buf, size_t size, size_t count)
225    {
226        fwrite((void* const)buf, size, count, mpfFile);
227    }
228    //---------------------------------------------------------------------
229    void Serializer::writeString(const String& string)
230    {
231        fputs(string.c_str(), mpfFile);
232        // Write terminating newline char
233        fputc('\n', mpfFile);
234    }
235    //---------------------------------------------------------------------
236    void Serializer::readFileHeader(DataStreamPtr& stream)
237    {
238        unsigned short headerID;
239       
240        // Read header ID
241        readShorts(stream, &headerID, 1);
242       
243        if (headerID == HEADER_STREAM_ID)
244        {
245            // Read version
246            String ver = readString(stream);
247            if (ver != mVersion)
248            {
249                OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
250                    "Invalid file: version incompatible, file reports " + String(ver) +
251                    " Serializer is version " + mVersion,
252                    "Serializer::readFileHeader");
253            }
254        }
255        else
256        {
257            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Invalid file: no header", 
258                "Serializer::readFileHeader");
259        }
260
261    }
262    //---------------------------------------------------------------------
263    unsigned short Serializer::readChunk(DataStreamPtr& stream)
264    {
265        unsigned short id;
266        readShorts(stream, &id, 1);
267       
268        readInts(stream, &mCurrentstreamLen, 1);
269        return id;
270    }
271    //---------------------------------------------------------------------
272    void Serializer::readBools(DataStreamPtr& stream, bool* pDest, size_t count)
273    {
274        //XXX Nasty Hack to convert 1 byte bools to 4 byte bools
275#       if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
276        char * pTemp = (char *)malloc(1*count); // to hold 1-byte bools
277        stream->read(pTemp, 1 * count);
278        for(int i = 0; i < count; i++)
279            *(bool *)(pDest + i) = *(char *)(pTemp + i);
280           
281        free (pTemp);
282#       else
283        stream->read(pDest, sizeof(bool) * count);
284#       endif
285        //no flipping on 1-byte datatypes
286    }
287    //---------------------------------------------------------------------
288    void Serializer::readFloats(DataStreamPtr& stream, float* pDest, size_t count)
289    {
290        stream->read(pDest, sizeof(float) * count);
291        flipFromLittleEndian(pDest, sizeof(float), count);
292    }
293    //---------------------------------------------------------------------
294    void Serializer::readFloats(DataStreamPtr& stream, double* pDest, size_t count)
295    {
296                // Read from float, convert to double
297                float* tmp = new float[count];
298                float* ptmp = tmp;
299        stream->read(tmp, sizeof(float) * count);
300        flipFromLittleEndian(tmp, sizeof(float), count);
301                // Convert to doubles (no cast required)
302                while(count--)
303                {
304                        *pDest++ = *ptmp++;
305                }
306                delete [] tmp;
307    }
308    //---------------------------------------------------------------------
309    void Serializer::readShorts(DataStreamPtr& stream, unsigned short* pDest, size_t count)
310    {
311        stream->read(pDest, sizeof(unsigned short) * count);
312        flipFromLittleEndian(pDest, sizeof(unsigned short), count);
313    }
314    //---------------------------------------------------------------------
315    void Serializer::readInts(DataStreamPtr& stream, unsigned int* pDest, size_t count)
316    {
317        stream->read(pDest, sizeof(unsigned int) * count);
318        flipFromLittleEndian(pDest, sizeof(unsigned int), count);
319    }
320    //---------------------------------------------------------------------
321    String Serializer::readString(DataStreamPtr& stream, size_t numChars)
322    {
323        assert (numChars <= 255);
324        char str[255];
325        stream->read(str, numChars);
326        str[numChars] = '\0';
327        return str;
328    }
329    //---------------------------------------------------------------------
330    String Serializer::readString(DataStreamPtr& stream)
331    {
332        return stream->getLine(false);
333    }
334    //---------------------------------------------------------------------
335    void Serializer::writeObject(const Vector3& vec)
336    {
337        writeFloats(vec.ptr(), 3);
338    }
339    //---------------------------------------------------------------------
340    void Serializer::writeObject(const Quaternion& q)
341    {
342        float tmp[4] = { q.x, q.y, q.z, q.w };
343        writeFloats(tmp, 4);
344    }
345    //---------------------------------------------------------------------
346    void Serializer::readObject(DataStreamPtr& stream, Vector3& pDest)
347    {
348        readFloats(stream, pDest.ptr(), 3);
349    }
350    //---------------------------------------------------------------------
351    void Serializer::readObject(DataStreamPtr& stream, Quaternion& pDest)
352    {
353        float tmp[4];
354        readFloats(stream, tmp, 4);
355        pDest.x = tmp[0];
356        pDest.y = tmp[1];
357        pDest.z = tmp[2];
358        pDest.w = tmp[3];
359    }
360    //---------------------------------------------------------------------
361
362
363    void Serializer::flipToLittleEndian(void* pData, size_t size, size_t count)
364    {
365                if(mFlipEndian)
366                {
367                flipEndian(pData, size, count);
368                }
369    }
370   
371    void Serializer::flipFromLittleEndian(void* pData, size_t size, size_t count)
372    {
373                if(mFlipEndian)
374                {
375                flipEndian(pData, size, count);
376                }
377    }
378   
379    void Serializer::flipEndian(void * pData, size_t size, size_t count)
380    {
381        for(unsigned int index = 0; index < count; index++)
382        {
383            flipEndian((void *)((long)pData + (index * size)), size);
384        }
385    }
386   
387    void Serializer::flipEndian(void * pData, size_t size)
388    {
389        char swapByte;
390        for(unsigned int byteIndex = 0; byteIndex < size/2; byteIndex++)
391        {
392            swapByte = *(char *)((long)pData + byteIndex);
393            *(char *)((long)pData + byteIndex) = *(char *)((long)pData + size - byteIndex - 1);
394            *(char *)((long)pData + size - byteIndex - 1) = swapByte;
395        }
396    }
397   
398}
399
Note: See TracBrowser for help on using the repository browser.