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