Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreSerializer.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright © 2000-2002 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #include "OgreStableHeaders.h"
00026 
00027 #include "OgreSerializer.h"
00028 #include "OgreLogManager.h"
00029 #include "OgreDataChunk.h"
00030 #include "OgreException.h"
00031 #include "OgreVector3.h"
00032 #include "OgreQuaternion.h"
00033 
00034 
00035 namespace Ogre {
00036 
00038     const unsigned long CHUNK_OVERHEAD_SIZE = sizeof(unsigned short) + sizeof(unsigned long);
00039     const unsigned short HEADER_CHUNK_ID = 0x1000;
00040     //---------------------------------------------------------------------
00041     Serializer::Serializer()
00042     {
00043         // Version number
00044         mVersion = "[Serializer_v1.00]";
00045     }
00046     //---------------------------------------------------------------------
00047     Serializer::~Serializer()
00048     {
00049     }
00050     //---------------------------------------------------------------------
00051     void Serializer::writeFileHeader(void)
00052     {
00053         
00054         unsigned short val = HEADER_CHUNK_ID;
00055         writeShorts(&val, 1);
00056 
00057         writeString(mVersion);
00058 
00059     }
00060     //---------------------------------------------------------------------
00061     void Serializer::writeChunkHeader(unsigned short id, unsigned long size)
00062     {
00063         writeShorts(&id, 1);
00064         writeLongs(&size, 1);
00065     }
00066     //---------------------------------------------------------------------
00067     void Serializer::writeReals(const Real* pReal, size_t count)
00068     {
00069 #   if OGRE_ENDIAN == ENDIAN_BIG
00070             Real * pRealToWrite = (Real *)malloc(sizeof(Real) * count);
00071             memcpy(pRealToWrite, pReal, sizeof(Real) * count);
00072             
00073             flipToLittleEndian(pRealToWrite, sizeof(Real), count);
00074             writeData(pRealToWrite, sizeof(Real), count);
00075             
00076             free(pRealToWrite);
00077 #   else
00078             writeData(pReal, sizeof(Real), count);
00079 #   endif
00080     }
00081     //---------------------------------------------------------------------
00082     void Serializer::writeShorts(const unsigned short* pShort, size_t count)
00083     {
00084 #   if OGRE_ENDIAN == ENDIAN_BIG
00085             unsigned short * pShortToWrite = (unsigned short *)malloc(sizeof(unsigned short) * count);
00086             memcpy(pShortToWrite, pShort, sizeof(unsigned short) * count);
00087             
00088             flipToLittleEndian(pShortToWrite, sizeof(unsigned short), count);
00089             writeData(pShortToWrite, sizeof(unsigned short), count);
00090             
00091             free(pShortToWrite);
00092 #   else
00093             writeData(pShort, sizeof(unsigned short), count);
00094 #   endif
00095     }
00096     //---------------------------------------------------------------------
00097     void Serializer::writeInts(const unsigned int* pInt, size_t count)
00098     {
00099 #   if OGRE_ENDIAN == ENDIAN_BIG
00100             unsigned int * pIntToWrite = (unsigned int *)malloc(sizeof(unsigned int) * count);
00101             memcpy(pIntToWrite, pInt, sizeof(unsigned int) * count);
00102             
00103             flipToLittleEndian(pIntToWrite, sizeof(unsigned int), count);
00104             writeData(pIntToWrite, sizeof(unsigned int), count);
00105             
00106             free(pIntToWrite);
00107 #   else
00108             writeData(pInt, sizeof(unsigned int), count);
00109 #   endif
00110     }
00111     //---------------------------------------------------------------------
00112     void Serializer::writeLongs(const unsigned long* pLong, size_t count)
00113     {
00114 #   if OGRE_ENDIAN == ENDIAN_BIG
00115             unsigned long * pLongToWrite = (unsigned long *)malloc(sizeof(unsigned long) * count);
00116             memcpy(pLongToWrite, pLong, sizeof(unsigned long) * count);
00117             
00118             flipToLittleEndian(pLongToWrite, sizeof(unsigned long), count);
00119             writeData(pLongToWrite, sizeof(unsigned long), count);
00120             
00121             free(pLongToWrite);
00122 #   else
00123             writeData(pLong, sizeof(unsigned long), count);
00124 #   endif
00125     }
00126     //---------------------------------------------------------------------
00127     void Serializer::writeBools(const bool* pBool, size_t count)
00128     {
00129     //no endian flipping for 1-byte bools
00130     //XXX Nasty Hack to convert to 1-byte bools
00131 #   if OGRE_PLATFORM == PLATFORM_APPLE
00132         char * pCharToWrite = (char *)malloc(sizeof(char) * count);
00133         for(int i = 0; i < count; i++)
00134         {
00135             *(char *)(pCharToWrite + i) = *(bool *)(pBool + i);
00136         }
00137         
00138         writeData(pCharToWrite, sizeof(char), count);
00139         
00140         free(pCharToWrite);
00141 #   else
00142         writeData(pBool, sizeof(bool), count);
00143 #   endif
00144 
00145     }
00146     
00147     //---------------------------------------------------------------------
00148     void Serializer::writeData(const void* buf, size_t size, size_t count)
00149     {
00150         fwrite((void* const)buf, size, count, mpfFile);
00151     }
00152     //---------------------------------------------------------------------
00153     void Serializer::writeString(const String& string)
00154     {
00155         fputs(string.c_str(), mpfFile);
00156         // Write terminating newline char
00157         fputc('\n', mpfFile);
00158     }
00159     //---------------------------------------------------------------------
00160     void Serializer::readFileHeader(DataChunk& chunk)
00161     {
00162         unsigned short headerID;
00163         
00164         // Read header ID
00165         readShorts(chunk, &headerID, 1);
00166         
00167         if (headerID == HEADER_CHUNK_ID)
00168         {
00169             // Read version
00170             String ver = readString(chunk);
00171             if (ver != mVersion)
00172             {
00173                 Except(Exception::ERR_INTERNAL_ERROR, 
00174                     "Invalid file: version incompatible, file reports " + String(ver) +
00175                     " Serializer is version " + mVersion,
00176                     "Serializer::readFileHeader");
00177             }
00178         }
00179         else
00180         {
00181             Except(Exception::ERR_INTERNAL_ERROR, "Invalid file: no header", 
00182                 "Serializer::readFileHeader");
00183         }
00184 
00185     }
00186     //---------------------------------------------------------------------
00187     unsigned short Serializer::readChunk(DataChunk& chunk)
00188     {
00189         unsigned short id;
00190         readShorts(chunk, &id, 1);
00191         
00192         readLongs(chunk, &mCurrentChunkLen, 1);
00193         return id;
00194     }
00195     //---------------------------------------------------------------------
00196     void Serializer::readBools(DataChunk& chunk, bool* pDest, size_t count)
00197     {
00198         //XXX Nasty Hack to convert 1 byte bools to 4 byte bools
00199 #   if OGRE_PLATFORM == PLATFORM_APPLE
00200         char * pTemp = (char *)malloc(1*count); // to hold 1-byte bools
00201         chunk.read(pTemp, 1 * count);
00202         for(int i = 0; i < count; i++)
00203             *(bool *)(pDest + i) = *(char *)(pTemp + i);
00204             
00205         free (pTemp);
00206 #   else
00207         chunk.read(pDest, sizeof(bool) * count);
00208 #   endif
00209         //no flipping on 1-byte datatypes
00210     }
00211     //---------------------------------------------------------------------
00212     void Serializer::readReals(DataChunk& chunk, Real* pDest, size_t count)
00213     {
00214         chunk.read(pDest, sizeof(Real) * count);
00215         flipFromLittleEndian(pDest, sizeof(Real), count);
00216     }
00217     //---------------------------------------------------------------------
00218     void Serializer::readShorts(DataChunk& chunk, unsigned short* pDest, size_t count)
00219     {
00220         chunk.read(pDest, sizeof(unsigned short) * count);
00221         flipFromLittleEndian(pDest, sizeof(unsigned short), count);
00222     }
00223     //---------------------------------------------------------------------
00224     void Serializer::readInts(DataChunk& chunk, unsigned int* pDest, size_t count)
00225     {
00226         chunk.read(pDest, sizeof(unsigned int) * count);
00227         flipFromLittleEndian(pDest, sizeof(unsigned int), count);
00228     }
00229     //---------------------------------------------------------------------
00230     void Serializer::readLongs(DataChunk& chunk, unsigned long* pDest, size_t count) 
00231     {
00232         chunk.read(pDest, sizeof(unsigned long) * count);
00233         flipFromLittleEndian(pDest, sizeof(unsigned long), count);
00234     }
00235     //---------------------------------------------------------------------
00236     String Serializer::readString(DataChunk& chunk, size_t numChars)
00237     {
00238         assert (numChars <= 255);
00239         char str[255];
00240         chunk.read(str, numChars);
00241         str[numChars] = '\0';
00242         return str;
00243     }
00244     //---------------------------------------------------------------------
00245     String Serializer::readString(DataChunk& chunk)
00246     {
00247         char str[255];
00248         size_t readcount;
00249         readcount = chunk.readUpTo(str, 255);
00250         str[readcount] = '\0';
00251         return str;
00252 
00253     }
00254     //---------------------------------------------------------------------
00255     void Serializer::writeObject(const Vector3& vec)
00256     {
00257         writeReals(&vec.x, 1);
00258         writeReals(&vec.y, 1);
00259         writeReals(&vec.z, 1);
00260 
00261     }
00262     //---------------------------------------------------------------------
00263     void Serializer::writeObject(const Quaternion& q)
00264     {
00265         writeReals(&q.x, 1);
00266         writeReals(&q.y, 1);
00267         writeReals(&q.z, 1);
00268         writeReals(&q.w, 1);
00269     }
00270     //---------------------------------------------------------------------
00271     void Serializer::readObject(DataChunk& chunk, Vector3* pDest)
00272     {
00273         readReals(chunk, &pDest->x, 1);
00274         readReals(chunk, &pDest->y, 1);
00275         readReals(chunk, &pDest->z, 1);
00276     }
00277     //---------------------------------------------------------------------
00278     void Serializer::readObject(DataChunk& chunk, Quaternion* pDest)
00279     {
00280         readReals(chunk, &pDest->x, 1);
00281         readReals(chunk, &pDest->y, 1);
00282         readReals(chunk, &pDest->z, 1);
00283         readReals(chunk, &pDest->w, 1);
00284     }
00285     //---------------------------------------------------------------------
00286 
00287 
00288     void Serializer::flipToLittleEndian(void* pData, size_t size, size_t count)
00289     {
00290 #   if OGRE_ENDIAN == ENDIAN_BIG
00291         flipEndian(pData, size, count);
00292 #   endif
00293     }
00294     
00295     void Serializer::flipFromLittleEndian(void* pData, size_t size, size_t count)
00296     {
00297 #   if OGRE_ENDIAN == ENDIAN_BIG
00298         flipEndian(pData, size, count);
00299 #   endif
00300     }
00301     
00302     void Serializer::flipEndian(void * pData, size_t size, size_t count)
00303     {
00304         for(unsigned int index = 0; index < count; index++)
00305         {
00306             flipEndian((void *)((int)pData + (index * size)), size);
00307         }
00308     }
00309     
00310     void Serializer::flipEndian(void * pData, size_t size)
00311     {
00312         char swapByte;
00313         for(unsigned int byteIndex = 0; byteIndex < size/2; byteIndex++)
00314         {
00315             swapByte = *(char *)((int)pData + byteIndex);
00316             *(char *)((int)pData + byteIndex) = *(char *)((int)pData + size - byteIndex - 1);
00317             *(char *)((int)pData + size - byteIndex - 1) = swapByte;
00318         }
00319     }
00320     
00321 }
00322 

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:46 2004