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