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

Revision 657, 11.8 KB checked in by mattausch, 19 years ago (diff)

added ogre dependencies and patched ogre sources

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