source: OGRE/trunk/ogrenew/OgreMain/src/OgreSerializer.cpp @ 692

Revision 692, 13.2 KB checked in by mattausch, 19 years ago (diff)

adding ogre 1.2 and dependencies

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-2005 The OGRE Team
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-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26
27#include "OgreSerializer.h"
28#include "OgreLogManager.h"
29#include "OgreDataStream.h"
30#include "OgreException.h"
31#include "OgreVector3.h"
32#include "OgreQuaternion.h"
33
34
35namespace Ogre {
36
37    /// stream overhead = ID + size
38    const size_t STREAM_OVERHEAD_SIZE = sizeof(uint16) + sizeof(uint32);
39    const uint16 HEADER_STREAM_ID = 0x1000;
40    const uint16 OTHER_ENDIAN_HEADER_STREAM_ID = 0x0010;
41    //---------------------------------------------------------------------
42    Serializer::Serializer()
43    {
44        // Version number
45        mVersion = "[Serializer_v1.00]";
46                mFlipEndian = false;
47    }
48    //---------------------------------------------------------------------
49    Serializer::~Serializer()
50    {
51    }
52    //---------------------------------------------------------------------
53        void Serializer::determineEndianness(DataStreamPtr& stream)
54        {
55                if (stream->tell() != 0)
56                {
57                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
58                                "Can only determine the endianness of the input stream if it "
59                                "is at the start", "Serializer::determineEndianness");
60                }
61                               
62                uint16 dest;
63                // read header id manually (no conversion)
64        stream->read(&dest, sizeof(uint16));
65                // skip back
66                stream->skip(0 - sizeof(uint16));
67                if (dest == HEADER_STREAM_ID)
68                {
69                        mFlipEndian = false;
70                }
71                else if (dest == OTHER_ENDIAN_HEADER_STREAM_ID)
72                {
73                        mFlipEndian = true;
74                }
75                else
76                {
77                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
78                                "Can't find a header chunk to determine endianness",
79                                "Serializer::determineEndianness");
80                }
81        }
82    //---------------------------------------------------------------------
83        void Serializer::determineEndianness(Endian requestedEndian)
84        {
85                switch(requestedEndian)
86                {
87                case ENDIAN_NATIVE:
88                        mFlipEndian = false;
89                        break;
90                case ENDIAN_BIG:
91#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
92                        mFlipEndian = false;
93#else
94                        mFlipEndian = true;
95#endif
96                        break;
97                case ENDIAN_LITTLE:
98#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
99                        mFlipEndian = true;
100#else
101                        mFlipEndian = false;
102#endif
103                        break;
104                }
105        }
106    //---------------------------------------------------------------------
107    void Serializer::writeFileHeader(void)
108    {
109       
110        uint16 val = HEADER_STREAM_ID;
111        writeShorts(&val, 1);
112
113        writeString(mVersion);
114
115    }
116    //---------------------------------------------------------------------
117    void Serializer::writeChunkHeader(uint16 id, uint32 size)
118    {
119        writeShorts(&id, 1);
120        writeInts(&size, 1);
121    }
122    //---------------------------------------------------------------------
123    void Serializer::writeFloats(const float* const pFloat, size_t count)
124    {
125                if (mFlipEndian)
126                {
127            float * pFloatToWrite = (float *)malloc(sizeof(float) * count);
128            memcpy(pFloatToWrite, pFloat, sizeof(float) * count);
129           
130            flipToLittleEndian(pFloatToWrite, sizeof(float), count);
131            writeData(pFloatToWrite, sizeof(float), count);
132           
133            free(pFloatToWrite);
134                }
135                else
136                {
137            writeData(pFloat, sizeof(float), count);
138                }
139    }
140    //---------------------------------------------------------------------
141    void Serializer::writeFloats(const double* const pDouble, size_t count)
142    {
143                // Convert to float, then write
144                float* tmp = new float[count];
145                for (unsigned int i = 0; i < count; ++i)
146                {
147                        tmp[i] = static_cast<float>(pDouble[i]);
148                }
149                if(mFlipEndian)
150                {
151            flipToLittleEndian(tmp, sizeof(float), count);
152            writeData(tmp, sizeof(float), count);
153                }
154                else
155                {
156            writeData(tmp, sizeof(float), count);
157                }
158                delete [] tmp;
159    }
160    //---------------------------------------------------------------------
161    void Serializer::writeShorts(const uint16* const pShort, size_t count = 1)
162    {
163                if(mFlipEndian)
164                {
165            unsigned short * pShortToWrite = (unsigned short *)malloc(sizeof(unsigned short) * count);
166            memcpy(pShortToWrite, pShort, sizeof(unsigned short) * count);
167           
168            flipToLittleEndian(pShortToWrite, sizeof(unsigned short), count);
169            writeData(pShortToWrite, sizeof(unsigned short), count);
170           
171            free(pShortToWrite);
172                }
173                else
174                {
175            writeData(pShort, sizeof(unsigned short), count);
176                }
177    }
178    //---------------------------------------------------------------------
179    void Serializer::writeInts(const uint32* const pInt, size_t count = 1)
180    {
181                if(mFlipEndian)
182                {
183            unsigned int * pIntToWrite = (unsigned int *)malloc(sizeof(unsigned int) * count);
184            memcpy(pIntToWrite, pInt, sizeof(unsigned int) * count);
185           
186            flipToLittleEndian(pIntToWrite, sizeof(unsigned int), count);
187            writeData(pIntToWrite, sizeof(unsigned int), count);
188           
189            free(pIntToWrite);
190                }
191                else
192                {
193            writeData(pInt, sizeof(unsigned int), count);
194                }
195    }
196    //---------------------------------------------------------------------
197    //---------------------------------------------------------------------
198    void Serializer::writeBools(const bool* const pBool, size_t count = 1)
199    {
200    //no endian flipping for 1-byte bools
201    //XXX Nasty Hack to convert to 1-byte bools
202#       if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
203        char * pCharToWrite = (char *)malloc(sizeof(char) * count);
204        for(int i = 0; i < count; i++)
205        {
206            *(char *)(pCharToWrite + i) = *(bool *)(pBool + i);
207        }
208       
209        writeData(pCharToWrite, sizeof(char), count);
210       
211        free(pCharToWrite);
212#       else
213        writeData(pBool, sizeof(bool), count);
214#       endif
215
216    }
217   
218    //---------------------------------------------------------------------
219    void Serializer::writeData(const void* const buf, size_t size, size_t count)
220    {
221        fwrite((void* const)buf, size, count, mpfFile);
222    }
223    //---------------------------------------------------------------------
224    void Serializer::writeString(const String& string)
225    {
226        fputs(string.c_str(), mpfFile);
227        // Write terminating newline char
228        fputc('\n', mpfFile);
229    }
230    //---------------------------------------------------------------------
231    void Serializer::readFileHeader(DataStreamPtr& stream)
232    {
233        unsigned short headerID;
234       
235        // Read header ID
236        readShorts(stream, &headerID, 1);
237       
238        if (headerID == HEADER_STREAM_ID)
239        {
240            // Read version
241            String ver = readString(stream);
242            if (ver != mVersion)
243            {
244                OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
245                    "Invalid file: version incompatible, file reports " + String(ver) +
246                    " Serializer is version " + mVersion,
247                    "Serializer::readFileHeader");
248            }
249        }
250        else
251        {
252            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Invalid file: no header",
253                "Serializer::readFileHeader");
254        }
255
256    }
257    //---------------------------------------------------------------------
258    unsigned short Serializer::readChunk(DataStreamPtr& stream)
259    {
260        unsigned short id;
261        readShorts(stream, &id, 1);
262       
263        readInts(stream, &mCurrentstreamLen, 1);
264        return id;
265    }
266    //---------------------------------------------------------------------
267    void Serializer::readBools(DataStreamPtr& stream, bool* pDest, size_t count)
268    {
269        //XXX Nasty Hack to convert 1 byte bools to 4 byte bools
270#       if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
271        char * pTemp = (char *)malloc(1*count); // to hold 1-byte bools
272        stream->read(pTemp, 1 * count);
273        for(int i = 0; i < count; i++)
274            *(bool *)(pDest + i) = *(char *)(pTemp + i);
275           
276        free (pTemp);
277#       else
278        stream->read(pDest, sizeof(bool) * count);
279#       endif
280        //no flipping on 1-byte datatypes
281    }
282    //---------------------------------------------------------------------
283    void Serializer::readFloats(DataStreamPtr& stream, float* pDest, size_t count)
284    {
285        stream->read(pDest, sizeof(float) * count);
286        flipFromLittleEndian(pDest, sizeof(float), count);
287    }
288    //---------------------------------------------------------------------
289    void Serializer::readFloats(DataStreamPtr& stream, double* pDest, size_t count)
290    {
291                // Read from float, convert to double
292                float* tmp = new float[count];
293                float* ptmp = tmp;
294        stream->read(tmp, sizeof(float) * count);
295        flipFromLittleEndian(tmp, sizeof(float), count);
296                // Convert to doubles (no cast required)
297                while(count--)
298                {
299                        *pDest++ = *ptmp++;
300                }
301                delete [] tmp;
302    }
303    //---------------------------------------------------------------------
304    void Serializer::readShorts(DataStreamPtr& stream, unsigned short* pDest, size_t count)
305    {
306        stream->read(pDest, sizeof(unsigned short) * count);
307        flipFromLittleEndian(pDest, sizeof(unsigned short), count);
308    }
309    //---------------------------------------------------------------------
310    void Serializer::readInts(DataStreamPtr& stream, unsigned int* pDest, size_t count)
311    {
312        stream->read(pDest, sizeof(unsigned int) * count);
313        flipFromLittleEndian(pDest, sizeof(unsigned int), count);
314    }
315    //---------------------------------------------------------------------
316    String Serializer::readString(DataStreamPtr& stream, size_t numChars)
317    {
318        assert (numChars <= 255);
319        char str[255];
320        stream->read(str, numChars);
321        str[numChars] = '\0';
322        return str;
323    }
324    //---------------------------------------------------------------------
325    String Serializer::readString(DataStreamPtr& stream)
326    {
327        return stream->getLine(false);
328    }
329    //---------------------------------------------------------------------
330    void Serializer::writeObject(const Vector3& vec)
331    {
332        writeFloats(&vec.x, 1);
333        writeFloats(&vec.y, 1);
334        writeFloats(&vec.z, 1);
335
336    }
337    //---------------------------------------------------------------------
338    void Serializer::writeObject(const Quaternion& q)
339    {
340        writeFloats(&q.x, 1);
341        writeFloats(&q.y, 1);
342        writeFloats(&q.z, 1);
343        writeFloats(&q.w, 1);
344    }
345    //---------------------------------------------------------------------
346    void Serializer::readObject(DataStreamPtr& stream, Vector3& pDest)
347    {
348        readFloats(stream, &pDest.x, 1);
349        readFloats(stream, &pDest.y, 1);
350        readFloats(stream, &pDest.z, 1);
351    }
352    //---------------------------------------------------------------------
353    void Serializer::readObject(DataStreamPtr& stream, Quaternion& pDest)
354    {
355        readFloats(stream, &pDest.x, 1);
356        readFloats(stream, &pDest.y, 1);
357        readFloats(stream, &pDest.z, 1);
358        readFloats(stream, &pDest.w, 1);
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.